diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue b/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue index 338f50e..5f7dec6 100644 --- a/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue @@ -41,6 +41,9 @@ const captureView = ()=>{ onMounted(()=>{ }) onUnmounted(()=>{ + console.log('onUnmounted') + threeModel.disposeModel() + threeModel = null }) defineExpose({open,captureView}) diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts b/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts index 0232b2e..3b224ba 100644 --- a/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts @@ -24,7 +24,7 @@ export class ThreeManager { camera: THREE.PerspectiveCamera;//相机对象 renderer: THREE.WebGLRenderer;//渲染器对象 controls: OrbitControls;//轨道控制器对象 - + animationId: number | null = null; pointLight: THREE.AmbientLight;//环境光对象 studioLights: any;//工作室光对象数组 @@ -316,15 +316,14 @@ export class ThreeManager { } operation(){ - let this_ = this const animate = () => { - requestAnimationFrame(animate); - this.controls.update(); - this.updateStudioLighting(); - this.updateImagePipeline(); - this.renderer.render(this.scene, this.camera); - } - animate(); + this.animationId = requestAnimationFrame(animate); + this.controls?.update(); + this.updateStudioLighting(); + this.updateImagePipeline(); + this.renderer?.render(this.scene, this.camera); + }; + animate(); } // 释放模型资源 @@ -343,7 +342,91 @@ export class ThreeManager { } }); } - + disposeModel() { + console.log('开始销毁 ThreeManager...'); + // 1. 停止动画 + if (this.animationId) { + cancelAnimationFrame(this.animationId); + this.animationId = null; + } + + // 2. 销毁控制器 + if (this.controls) { + this.controls.dispose(); + this.controls = null; + } + + // 3. 销毁模型 + if (this.currentModel) { + this.dispose(this.currentModel); + this.scene?.remove(this.currentModel); + this.currentModel = null; + } + + // 4. 销毁灯光 + if (this.studioLights?.length) { + this.studioLights.forEach(item => { + if (item.light) { + this.scene?.remove(item.light); + item.light.dispose?.(); + } + }); + this.studioLights = []; + } + + // 5. 清理环境光 + if (this.pointLight) { + this.scene?.remove(this.pointLight); + this.pointLight = null; + } + + // 6. 清理场景 + if (this.scene) { + this.scene.traverse((obj) => { + if (obj.isMesh) { + const mesh = obj as THREE.Mesh; + mesh.geometry?.dispose(); + if (mesh.material) { + if (Array.isArray(mesh.material)) { + mesh.material.forEach(m => m.dispose()); + } else { + mesh.material.dispose(); + } + } + } + }); + + while (this.scene.children.length) { + this.scene.remove(this.scene.children[0]); + } + this.scene = null; + } + + // 7. 销毁渲染器 + if (this.renderer) { + this.renderer.dispose(); + if (this.renderer.domElement?.parentNode) { + this.renderer.domElement.parentNode.removeChild(this.renderer.domElement); + } + this.renderer = null; + } + + // 8. 清空 DOM 容器 + if (this.threeDom) { + this.threeDom.innerHTML = ''; + this.threeDom = null; + } + + // 9. 清空其他引用 + this.camera = null; + this.v1 = null; + this.camDir = null; + this.camForward = null; + this.camToTarget = null; + this.modelInfo = null; + + console.log('ThreeManager 已销毁'); + } exportAsImage(){ return this.renderer.domElement.toDataURL('image/png');