Bläddra i källkod

feat: introduce useTres composable and update related documentation (#1017)

* feat: introduce useTres composable and update related documentation

- Added the `useTres` composable to provide a simplified API for accessing the TresJS context, including methods for `invalidate` and `advance`.
- Updated various components and documentation to utilize the new `useTres` composable, enhancing code clarity and maintainability.
- Included a new documentation page for `useTres` detailing its usage and properties.

* fix: clean up TresCanvas template and update useFBO imports

- Removed unnecessary line breaks in the TresCanvas template for improved readability.
- Updated the import statement in useFBO.ts to remove unused useTresContext, streamlining the code and enhancing clarity.

* refactor: remove performance state from useTres composable

- Removed the `perf` property from the `useTres` composable, streamlining the context returned by `useTresContext`.
- Introduced a new `PerformanceState` interface in `setupDevtools.ts` to manage performance metrics, enhancing clarity and maintainability of performance-related data.
Alvaro Saburido 3 veckor sedan
förälder
incheckning
fd03f7241e

+ 1 - 0
docs/.vitepress/config/en.ts

@@ -41,6 +41,7 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
         text: 'Composables',
         link: '/api/composables',
         items: [
+          { text: 'useTres', link: '/composables/use-tres' },
           { text: 'useLoader', link: '/composables/use-loader' },
           { text: 'useGraph', link: '/composables/use-graph' },
         ],

+ 2 - 2
docs/advanced/performance.md

@@ -82,13 +82,13 @@ import { useTres } from '@tresjs/core'
 import { shallowRef, watch } from 'vue'
 
 const boxRef = shallowRef(null)
-const { renderer } = useTres()
+const { invalidate } = useTres()
 
 watch(boxRef, () => {
   if (boxRef.value?.position) {
     boxRef.value.position.x = 1
   }
-  renderer.invalidate()
+  invalidate()
 })
 </script>
 

+ 63 - 0
docs/composables/use-tres.md

@@ -0,0 +1,63 @@
+# useTres
+
+The `useTres` composable provides access to a simplified version of the TresJS context. It is a wrapper around the `useTresContext` composable that provides a more convenient API for common use cases.
+
+## Usage
+
+```ts
+import { useTres } from '@tresjs/core'
+
+const { scene, renderer, camera, invalidate } = useTres()
+```
+
+:::warning
+`useTres` can be only be used inside a child component of a `TresCanvas` since this component acts as the provider for the context data.
+:::
+
+::: code-group
+
+```vue [App.vue]
+<script setup>
+import { TresCanvas } from '@tresjs/core'
+import SubComponent from './SubComponent.vue'
+</script>
+
+<template>
+  <TresCanvas>
+    <SubComponent />
+  </TresCanvas>
+</template>
+```
+
+```vue [SubComponent.vue]
+<script lang="ts" setup>
+import { useTres } from '@tresjs/core'
+
+const { camera } = useTres()
+
+watchEffect(() => {
+  console.log(camera.value)
+})
+</script>
+```
+
+## Properties
+
+| Property | Description |
+| --- | --- |
+| **camera** | the currently active camera |
+| **scene** | the [scene](https://threejs.org/docs/?q=sce#api/en/scenes/Scene) |
+| **renderer** | Contains the [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer)  |
+| **sizes** | contains width, height and aspect ratio of your canvas |
+| **loop** | the renderer loop |
+| **controls** | the controls of your scene |
+| **raycaster** | the global raycaster used for pointer events |
+| **perf** | the performance monitor |
+| **extend** | Extends the component catalogue. See [extending](/advanced/extending). |
+
+## Methods
+
+| Method | Description |
+| --- | --- |
+| **invalidate** | Marks the scene as needing an update in the next frame. This is used in on-demand rendering mode to schedule a render. |
+| **advance** | Manually advances the render loop by one frame. This is particularly useful in manual rendering mode where you want explicit control over when frames are rendered. |

+ 3 - 4
playground/vue/src/pages/advanced/fbo/useFBO.ts

@@ -1,7 +1,7 @@
-import type { Camera, WebGLRenderTargetOptions } from 'three'
+import type { Camera } from 'three'
 import type { Ref } from 'vue'
 /* eslint-disable no-console */
-import { useLoop, useTresContext } from '@tresjs/core'
+import { useLoop, useTres } from '@tresjs/core'
 import { useThrottleFn } from '@vueuse/core'
 import { DepthTexture, FloatType, HalfFloatType, LinearFilter, WebGLRenderTarget } from 'three'
 import { isReactive, onBeforeUnmount, reactive, ref, toRefs, watchEffect } from 'vue'
@@ -48,8 +48,7 @@ export function useFBO(options: FboOptions) {
 
   const { height, width, settings, depth } = isReactive(options) ? toRefs(options) : toRefs(reactive(options))
 
-  /*   const { onLoop } = useRenderLoop() */
-  const { sizes } = useTresContext()
+  const { sizes } = useTres()
 
   watchEffect(() => {
     target.value?.dispose()

+ 3 - 3
playground/vue/src/pages/advanced/manual/experience.vue

@@ -3,10 +3,10 @@ import { OrbitControls } from '@tresjs/cientos'
 import { useTres } from '@tresjs/core'
 import BlenderCube from '../../../components/BlenderCube.vue'
 
-const { renderer } = useTres()
+const { advance } = useTres()
 
 onMounted(() => {
-  renderer.advance()
+  advance()
 })
 </script>
 
@@ -18,7 +18,7 @@ onMounted(() => {
   <BlenderCube />
 
   <TresGridHelper />
-  <OrbitControls @change="renderer.advance" />
+  <OrbitControls @change="advance" />
   <TresAmbientLight :intensity="1" />
   <TresDirectionalLight
     :position="[0, 8, 4]"

+ 3 - 3
playground/vue/src/pages/advanced/on-demand/experience.vue

@@ -4,17 +4,17 @@ import { useTres } from '@tresjs/core'
 import { ref, watch } from 'vue'
 import BlenderCube from '../../../components/BlenderCube.vue'
 
-const { renderer } = useTres()
+const { invalidate } = useTres()
 
 const blenderCubeRef = ref()
 
 watch(blenderCubeRef, (prev, next) => {
   if (!next) { return }
-  renderer.invalidate()
+  invalidate()
 })
 
 function onControlChange() {
-  renderer.invalidate()
+  invalidate()
 }
 </script>
 

+ 1 - 0
src/composables/index.ts

@@ -7,6 +7,7 @@ export * from './useLoop'
 export * from './useRaycaster'
 export * from './useRenderer/useRendererManager'
 export * from './useRenderLoop'
+export * from './useTres'
 
 export * from './useTresContextProvider'
 export * from './useTresEventManager'

+ 1 - 1
src/composables/useRenderer/useRendererManager.ts

@@ -310,12 +310,12 @@ export function useRendererManager(
 
   return {
     instance,
-
     isReady: readonly(isReady),
     advance,
     onRender,
     invalidate,
     canBeInvalidated,
+    amountOfFramesToRender,
   }
 }
 

+ 54 - 0
src/composables/useTres/index.ts

@@ -0,0 +1,54 @@
+import { type ComputedRef, toValue } from 'vue'
+import type { TresContext } from '../useTresContextProvider'
+import { useTresContext } from '../useTresContextProvider'
+import type { Camera, WebGLRenderer } from 'three'
+
+export interface TresPartialContext extends Omit<TresContext, 'renderer' | 'camera'> {
+  /**
+   * The renderer instance
+   *
+   * @type {WebGLRenderer}
+   * @memberof TresPartialContext
+   */
+  renderer: WebGLRenderer
+  /**
+   * The current active camera
+   *
+   * @type {ComputedRef<Camera | undefined>}
+   * @memberof TresPartialContext
+   */
+  camera: ComputedRef<Camera | undefined>
+  /**
+   * Marks the scene as needing an update in the next frame.
+   * This is used in on-demand rendering mode to schedule a render.
+   *
+   * @type {() => void}
+   * @memberof TresPartialContext
+   */
+  invalidate: () => void
+  /**
+   * Manually advances the render loop by one frame.
+   * This is particularly useful in manual rendering mode where you want explicit control over when frames are rendered.
+   *
+   * @type {() => void}
+   * @memberof TresPartialContext
+   */
+  advance: () => void
+}
+
+export function useTres(): TresPartialContext {
+  const { scene, renderer, camera, sizes, controls, loop, extend, raycaster } = useTresContext()
+
+  return {
+    scene,
+    renderer: toValue(renderer.instance),
+    camera: camera.activeCamera,
+    sizes,
+    controls,
+    loop,
+    extend,
+    raycaster,
+    invalidate: () => renderer.invalidate(),
+    advance: () => renderer.advance(),
+  }
+}

+ 0 - 2
src/composables/useTresContextProvider/index.ts

@@ -109,5 +109,3 @@ export function useTresContext(): TresContext {
 
   return context as TresContext
 }
-
-export const useTres = useTresContext

+ 13 - 0
src/devtools/setupDevtools.ts

@@ -4,6 +4,19 @@ import type { TresContext } from '../composables'
 import type { TresObject } from '../types'
 import { onUnmounted } from 'vue'
 
+export interface PerformanceState {
+  maxFrames: number
+  fps: {
+    value: number
+    accumulator: number[]
+  }
+  memory: {
+    currentMem: number
+    allocatedMem: number
+    accumulator: number[]
+  }
+}
+
 export function setupTresDevtools(ctx: TresContext) {
   if (!ctx) { return }