-
-
Notifications
You must be signed in to change notification settings - Fork 173
feat(core): extract context management logic to useTresContextManager composable #1233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for tresjs-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for tresjs-lab ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for cientos-tresjs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| ) { | ||
| const instance = getCurrentInstance() | ||
|
|
||
| const createInternalComponent = (context: TresContext, empty = false) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Moving all this from the TresCanvas component to this composable is not desirable. The composables role is to initialize and orchestrate all the things around three.js while showing the dependencies between the respective elements (like renderer needs camera, event manager needs the renderer,...). The things that are moved here are very specific to the TresCanvas. Moving them harms the architecture and the readability imo. @Jungzl Maybe you can explain a bit what kind of fix or feature the change brings for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your feedback.
The motivation behind this PR is to enable rendering three.js content inside a host-provided WebGL layer (e.g., a map’s WebGL layer) while reusing Tres’s scene/camera lifecycle, scheduling, and state management—without duplicating the internal logic from the Context component.
But Tres doesn’t expose a low-level primitive equivalent to createRoot (from R3F) or createThrelteContext (from Threlte). If we attempt to integrate directly by mounting into an external canvas/context, we end up replicating much of Context.vue’s orchestration. To avoid that, this PR extracts and exports the logic as a composable (useTresContextManager), paired with useTresContextProvider.
The code looks like below:
<!-- CustomTresLayer.vue -->
<script setup lang="ts">
//...
const slots = defineSlots<{
default: () => any
}>()
extend(THREE)
const createRenderer: RendererOptions['renderer'] = ctx => {
const renderer = new WebGLRenderer({
...ctx,
canvas: hostCanvas,
context: hostGLContext,
})
renderer.autoClear = false
return renderer as TresRenderer
}
const scene = shallowRef(new Scene())
const context = shallowRef(
useTresContextProvider({
scene: scene.value,
canvas: hostCanvas,
rendererOptions: { ...props, renderer: createRenderer }
})
)
const { dispose } = useTresContextManager(scene, context, props, emit, slots)
// Bridge render requests to host
watchEffect(() => {
context.value?.renderer?.replaceRenderFunction(notifySuccess => {
host.render() // Trigger host redraw
notifySuccess()
})
})
// Sync camera to host view in render callback
const render = () => {
const { camera, scene } = context.value
const activeCamera = camera.activeCamera.value
// Apply host camera parameters
const { near, far, fov, position, lookAt } = host.getCameraParams()
activeCamera.near = near
activeCamera.far = far
activeCamera.fov = fov
activeCamera.position.set(...position)
activeCamera.lookAt(...lookAt)
activeCamera.updateProjectionMatrix()
// Render with host state
renderer.render(scene.value, activeCamera)
renderer.resetState()
}
</script>
<template>
<CustomLayer :render="render" />
</template># Conflicts: # packages/core/src/components/Context.vue
follows up: #1232
close: #1210
like
createRootfrom@react-three/fiberorcreateThrelteContextfrom@threlte/corefinally, I can easily integrate
tresjsin map app.