Skip to content

Commit 9a20b52

Browse files
authoredAug 15, 2024··
fix: 796 unmount the canvas component instant mount children again even if canvas is not mounted (#799)
* fix: avoid mounting again custom renderer components on TresCanvas unmounted * chore: fix lint
1 parent 3fadeed commit 9a20b52

File tree

6 files changed

+76
-11
lines changed

6 files changed

+76
-11
lines changed
 

‎playground/src/pages/basic/index.vue

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { TresCanvas, useRenderLoop } from '@tresjs/core'
55
import { OrbitControls } from '@tresjs/cientos'
66
77
const state = reactive({
8-
clearColor: '#201919',
8+
clearColor: '#ffffff',
99
shadows: true,
1010
alpha: false,
1111
@@ -24,7 +24,7 @@ onLoop(({ elapsed }) => {
2424
sphereRef.value.position.y += Math.sin(elapsed) * 0.01
2525
2626
// Update events without needing the mouse to move
27-
canvasRef.value?.context?.eventManager.forceUpdate()
27+
canvasRef.value?.context?.eventManager?.forceUpdate()
2828
})
2929
3030
function onPointerEnter(ev) {
@@ -50,6 +50,7 @@ const toonTealMaterial = new MeshToonMaterial({
5050
type="checkbox"
5151
/>
5252
<TresCanvas
53+
v-if="sphereExists"
5354
ref="canvasRef"
5455
v-bind="state"
5556
@render="onRender"
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!-- eslint-disable no-console -->
2+
<script setup lang="ts">
3+
import { onMounted, onUnmounted } from 'vue'
4+
5+
console.log('BOX--INIT:', Date.now())
6+
7+
onMounted(() => {
8+
console.log('BOX--MOUNTED', Date.now())
9+
})
10+
11+
onUnmounted(() => {
12+
console.log('BOX--UNMOUNTED', Date.now())
13+
})
14+
</script>
15+
16+
<template>
17+
<TresMesh>
18+
<TresBoxGeometry />
19+
<TresMeshNormalMaterial />
20+
</TresMesh>
21+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<script setup lang="ts">
2+
import TheBox from './TheBox.vue'
3+
</script>
4+
5+
<template>
6+
<TresPerspectiveCamera :position="[5, 5, 5]" :look-at="[0, 0, 0]" />
7+
<TheBox />
8+
</template>
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script setup lang="ts">
2+
import { TresCanvas } from '@tresjs/core'
3+
import TheExperience from './TheExperience.vue'
4+
5+
const gl = {
6+
clearColor: '#82DBC5',
7+
shadows: true,
8+
alpha: false,
9+
}
10+
11+
const showCanvas = ref(true)
12+
</script>
13+
14+
<template>
15+
<input
16+
v-model="showCanvas"
17+
type="checkbox"
18+
/>
19+
<TresCanvas v-if="showCanvas" v-bind="gl">
20+
<TheExperience />
21+
</TresCanvas>
22+
</template>

‎playground/src/router/routes/issues.ts

+6
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@ export const issuesRoutes = [
1919
name: '#749: attach-detach',
2020
component: () => import('../../pages/issues/749/index.vue'),
2121
},
22+
{
23+
path: '/issues/796',
24+
name: '#796: unmounted',
25+
component: () => import('../../pages/issues/796/index.vue'),
26+
},
27+
2228
]

‎src/components/TresCanvas.vue

+16-9
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ const scene = shallowRef<TresScene | Scene>(new Scene())
110110
const instance = getCurrentInstance()?.appContext.app
111111
extend(THREE)
112112
113-
const createInternalComponent = (context: TresContext) =>
113+
const createInternalComponent = (context: TresContext, empty = false) =>
114114
defineComponent({
115115
setup() {
116116
const ctx = getCurrentInstance()?.appContext
@@ -121,12 +121,12 @@ const createInternalComponent = (context: TresContext) =>
121121
if (typeof window !== 'undefined') {
122122
registerTresDevtools(ctx?.app, context)
123123
}
124-
return () => h(Fragment, null, slots?.default ? slots.default() : [])
124+
return () => h(Fragment, null, !empty ? slots.default() : [])
125125
},
126126
})
127127
128-
const mountCustomRenderer = (context: TresContext) => {
129-
const InternalComponent = createInternalComponent(context)
128+
const mountCustomRenderer = (context: TresContext, empty = false) => {
129+
const InternalComponent = createInternalComponent(context, empty)
130130
const { render } = createRenderer(nodeOps(context))
131131
render(h(InternalComponent), scene.value as unknown as TresObject)
132132
}
@@ -141,7 +141,6 @@ const dispose = (context: TresContext, force = false) => {
141141
(scene.value as TresScene).__tres = {
142142
root: context,
143143
}
144-
mountCustomRenderer(context)
145144
}
146145
147146
const disableRender = computed(() => props.disableRender)
@@ -150,6 +149,16 @@ const context = shallowRef<TresContext | null>(null)
150149
151150
defineExpose({ context, dispose: () => dispose(context.value as TresContext, true) })
152151
152+
const handleHMR = (context: TresContext) => {
153+
dispose(context)
154+
mountCustomRenderer(context)
155+
}
156+
157+
const unmountCanvas = () => {
158+
dispose(context.value as TresContext)
159+
mountCustomRenderer(context.value as TresContext, true)
160+
}
161+
153162
onMounted(() => {
154163
const existingCanvas = canvas as Ref<HTMLCanvasElement>
155164
@@ -209,12 +218,10 @@ onMounted(() => {
209218
}
210219
211220
// HMR support
212-
if (import.meta.hot && context.value) { import.meta.hot.on('vite:afterUpdate', () => dispose(context.value as TresContext)) }
221+
if (import.meta.hot && context.value) { import.meta.hot.on('vite:afterUpdate', () => handleHMR(context.value as TresContext)) }
213222
})
214223
215-
onUnmounted(() => {
216-
dispose(context.value as TresContext)
217-
})
224+
onUnmounted(unmountCanvas)
218225
</script>
219226

220227
<template>

0 commit comments

Comments
 (0)
Please sign in to comment.