From 3714d5ee4ab4305dcc3690bc1c3fa39c6bf5c6bd Mon Sep 17 00:00:00 2001
From: ZhangXianQiang <1135831638@qq.com>
Date: 星期五, 19 四月 2024 15:17:51 +0800
Subject: [PATCH] feat:添加资源销毁,防止内存泄漏

---
 src/views/screen/components/screen-map-three/experience/camera.js           |   38 ++++++--
 src/views/screen/components/screen-map-three/experience/index.js            |   56 ++++++++++++-
 src/views/screen/components/screen-map-three/experience/cssRenderer.js      |    4 +
 src/views/screen/components/screen-map-three/experience/world/enviroment.js |   39 +++++++++
 src/views/screen/components/screen-map-three/experience/world/world.js      |    4 +
 src/views/screen/components/screen-wrapper/index.vue                        |    2 
 src/views/screen/components/screen-map-three/index.vue                      |   13 ++-
 src/views/screen/components/screen-map-three/experience/renderer.js         |    4 +
 src/views/screen/components/screen-map-three/experience/world/map.js        |   41 ++++++++++
 src/views/screen/components/screen-map-three/experience/utils/time.js       |   10 ++
 10 files changed, 187 insertions(+), 24 deletions(-)

diff --git a/src/views/screen/components/screen-map-three/experience/camera.js b/src/views/screen/components/screen-map-three/experience/camera.js
index 8a541f2..64c604f 100644
--- a/src/views/screen/components/screen-map-three/experience/camera.js
+++ b/src/views/screen/components/screen-map-three/experience/camera.js
@@ -1,4 +1,4 @@
-import {MathUtils} from 'three';
+import { MathUtils } from 'three';
 import { PerspectiveCamera, CameraHelper } from 'three';
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
 
@@ -6,17 +6,16 @@
 export default class Camera {
     constructor(experience) {
         this.experience = experience;
-        this.scene = this.experience.scene;
-        this.canvas = this.experience.canvas;
-        this.sizes = this.experience.sizes;
+        this.scene = experience.scene;
+        this.canvas = experience.canvas;
+        this.sizes = experience.sizes;
         this.setInstance();
         this.setOrbitControls();
-
     }
 
     // 璁剧疆閫忚鐩告満
     setInstance() {
-        this.instance = new PerspectiveCamera(45,this.sizes.width / this.sizes.height, 0.001, 90000000);
+        this.instance = new PerspectiveCamera(45, this.sizes.width / this.sizes.height, 0.001, 90000000);
         this.instance.position.set(0, 45, 45);
         this.scene.add(this.instance);
         // const help = new CameraHelper(this.instance);
@@ -35,11 +34,7 @@
 
     resize() {
         // 閲嶆柊璁$畻姣斾緥
-        this.cameraAspect = (this.sizes.width / this.sizes.height) * this.frustrum;
-        this.instance.left = -this.cameraAspect / 2;
-        this.instance.right = this.cameraAspect / 2;
-        this.instance.top = this.frustrum / 2;
-        this.instance.bottom = -this.frustrum  / 2;
+        this.cameraAspect = this.sizes.width / this.sizes.height;
         this.instance.updateProjectionMatrix();
     }
 
@@ -47,4 +42,25 @@
     update() {
         this.controls.update();
     }
+
+    destroy() {
+        this.disposeObject();
+        this.removeObject();
+        this.resetObject();
+    }
+
+    disposeObject() {
+        this.controls.dispose();
+    }
+
+    removeObject() {
+        this.scene.remove(this.instance);
+    }
+    resetObject() {
+        this.controls = null;
+        this.instance = null;
+        this.scene = null;
+        this.canvas = null;
+        this.sizes = null;
+    }
 }
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/cssRenderer.js b/src/views/screen/components/screen-map-three/experience/cssRenderer.js
index dcae37c..c433745 100644
--- a/src/views/screen/components/screen-map-three/experience/cssRenderer.js
+++ b/src/views/screen/components/screen-map-three/experience/cssRenderer.js
@@ -28,4 +28,8 @@
   update() {
     this.instance.render(this.scene, this.camera.instance);
   }
+
+  destroy() {
+    this.instance.domElement.remove();
+  }
 }
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/index.js b/src/views/screen/components/screen-map-three/experience/index.js
index 17affbd..df12788 100644
--- a/src/views/screen/components/screen-map-three/experience/index.js
+++ b/src/views/screen/components/screen-map-three/experience/index.js
@@ -1,4 +1,4 @@
-import { Scene, GridHelper,AxesHelper } from 'three';
+import { Scene, GridHelper, AxesHelper } from 'three';
 import Stats from "three/examples/jsm/libs/stats.module";
 
 import World from "./world/world";
@@ -28,10 +28,10 @@
     // const gridHelper = new GridHelper(size, divisions);
     // this.scene.add(gridHelper);
 
-    this.stats = new Stats();
-    document.querySelector('.map-container').appendChild(this.stats.dom);
+    // this.stats = new Stats();
+    // document.querySelector('.map-container').appendChild(this.stats.dom);
 
-    
+
 
     // 甯�
     this.time.on('tick', () => {
@@ -44,6 +44,52 @@
     this.world.update();
     this.renderer.update();
     this.cssRenderer.update();
-    this.stats.update();
+    // this.stats.update();
+  }
+
+  /**
+   * 閿�姣佸満鏅�
+   */
+  destroy() {
+    this.disposeObject();
+    this.resetObject();
+  }
+
+  disposeObject() {
+    this.time.destroy();
+    this.world.destroy();
+    this.camera.destroy();
+    this.renderer.destroy();
+    this.cssRenderer.destroy();
+    this.scene.traverse((child) => {
+      if (child.material) {
+        // 鍙兘瀛樺湪鏉愯川涓烘暟缁勭殑鎯呭喌
+        if (child.material instanceof Array) {
+          child.material.forEach((item) => item.dispose());
+        } else {
+          child.material.dispose();
+          if (child.material.map) {
+            child.material.map.dispose();
+          }
+        }
+      }
+      if (child.geometry) {
+        child.geometry.dispose();
+        child.geometry.attributes = null; // 杩欎簺灞炴�у寘鎷琾osition, normal, uv绛夌瓑
+      }
+      child = null;
+    });
+  }
+
+  resetObject() {
+    this.world = null;
+    this.camera = null;
+    this.renderer = null;
+    this.cssRenderer = null;
+    this.scene = null;
+    this.canvas = null;
+    this.container = null;
+    this.time = null;
+    this.sizes = null;
   }
 }
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/renderer.js b/src/views/screen/components/screen-map-three/experience/renderer.js
index e75b135..a5febfa 100644
--- a/src/views/screen/components/screen-map-three/experience/renderer.js
+++ b/src/views/screen/components/screen-map-three/experience/renderer.js
@@ -30,4 +30,8 @@
     update() {
         this.instance.render(this.scene, this.camera.instance);
     }
+    destroy() {
+        this.instance.dispose();
+        this.instance.domElement.remove();
+    }
 }
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/utils/time.js b/src/views/screen/components/screen-map-three/experience/utils/time.js
index 680b19d..e60078b 100644
--- a/src/views/screen/components/screen-map-three/experience/utils/time.js
+++ b/src/views/screen/components/screen-map-three/experience/utils/time.js
@@ -6,6 +6,7 @@
         this.current = this.start;
         this.elapsed = 0;
         this.delta = 16;
+        // 鍚堥�傜殑鏃舵満鎵цloop寰幆
         window.requestAnimationFrame(() => {
             this.tick();
         });
@@ -17,9 +18,14 @@
         this.current = currentTime;
         this.elapsed = this.current - this.start;
         this.trigger('tick');
-        
-        window.requestAnimationFrame(() => {
+
+        this.loopId = window.requestAnimationFrame(() => {
             this.tick();
         });
     }
+
+    destroy() {
+        window.cancelAnimationFrame(this.loopId);
+        this.off('tick');
+    }
 }
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/world/enviroment.js b/src/views/screen/components/screen-map-three/experience/world/enviroment.js
index f648da6..833dc82 100644
--- a/src/views/screen/components/screen-map-three/experience/world/enviroment.js
+++ b/src/views/screen/components/screen-map-three/experience/world/enviroment.js
@@ -117,13 +117,50 @@
     }
   }
 
+  destroy() {
+    this.disposeObject();
+    this.removeObject();
+    this.resetObject();
+  }
+
+  disposeObject() {
+    this.hola1.geometry.dispose();
+    this.hola1.material.dispose();
+    this.hola2.geometry.dispose();
+    this.hola2.material.dispose();
+    this.background.geometry.dispose();
+    this.background.material.dispose();
+    this.circle.geometry.dispose();
+    this.circle.material.dispose();
+    this.directionalLight1.dispose();
+    this.directionalLight2.dispose();
+    this.ambientLight.dispose();
+  }
+
+  removeObject() {
+    this.scene.remove(this.hola1);
+    this.scene.remove(this.hola2);
+    this.scene.remove(this.background);
+    this.scene.remove(this.circle);
+  }
+
+  resetObject() {
+    this.hola1 = null;
+    this.hola2 = null;
+    this.background = null;
+    this.circle = null;
+    this.directionalLight1 = null;
+    this.directionalLight2 = null;
+    this.ambientLight = null;
+  }
+
   debuger() {
     const gui = new GUI();
 
     const folder1 = gui.addFolder('骞宠鍏�1');
     const folder2 = gui.addFolder('骞宠鍏�2');
     const folder3 = gui.addFolder('鐜鍏�');
- 
+
     folder1.add(this.directionalLight1.position, 'x').min(-200).max(200).step(1).name("x杞寸殑浣嶇疆");
     folder1.add(this.directionalLight1.position, 'y').min(-200).max(200).step(1).name("y杞寸殑浣嶇疆");
     folder1.add(this.directionalLight1.position, 'z').min(-200).max(200).step(1).name("z杞寸殑浣嶇疆");
diff --git a/src/views/screen/components/screen-map-three/experience/world/map.js b/src/views/screen/components/screen-map-three/experience/world/map.js
index fd648d6..1dd127f 100644
--- a/src/views/screen/components/screen-map-three/experience/world/map.js
+++ b/src/views/screen/components/screen-map-three/experience/world/map.js
@@ -271,4 +271,45 @@
             ease: 'power1.out'
         })
     }
+
+    destroy() {
+        this.removeMouseEvent();
+        this.disposeObject();
+        this.removeObject();
+        this.resetObject();
+    }
+
+    disposeObject() {
+        this.map.traverse((child) => {
+            if (child.material) {
+                // 鍙兘瀛樺湪鏉愯川涓烘暟缁勭殑鎯呭喌
+                if (child.material instanceof Array) {
+                    child.material.forEach((item) => item.dispose());
+                } else {
+                    child.material.dispose();
+                    if (child.material.map) {
+                        child.material.map.dispose();
+                    }
+                }
+            }
+            if (child.geometry) {
+                child.geometry.dispose();
+                child.geometry.attributes = null; // 杩欎簺灞炴�у寘鎷琾osition, normal, uv绛夌瓑
+            }
+            child = null;
+        });
+        this.topFaceMaterial.dispose();
+        this.sideMaterial.dispose();
+    }
+
+    removeObject() {
+        this.scene.remove(this.map);
+    }
+
+    resetObject() {
+        this.map = null;
+        this.provinceMeshList = null;
+        this.labelList = null;
+        this.textureLoader = null;
+    }
 }
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/world/world.js b/src/views/screen/components/screen-map-three/experience/world/world.js
index 5ab10f0..a872335 100644
--- a/src/views/screen/components/screen-map-three/experience/world/world.js
+++ b/src/views/screen/components/screen-map-three/experience/world/world.js
@@ -14,4 +14,8 @@
   update() {
     this.enviroment.update();
   }
+  destroy() {
+    this.enviroment.destroy();
+    this.map.destroy();
+  }
 }
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/index.vue b/src/views/screen/components/screen-map-three/index.vue
index af189c1..806fa3e 100644
--- a/src/views/screen/components/screen-map-three/index.vue
+++ b/src/views/screen/components/screen-map-three/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="map-container" >
+  <div class="map-container">
     <canvas class="world" ref="worldContainer"></canvas>
   </div>
 </template>
@@ -18,15 +18,19 @@
   watch: {
     loadEnd: {
       handler(newVal) {
-        console.log(newVal);
-        if(newVal) {
+        if (newVal) {
           world = new Experience(this.$refs.worldContainer);
         }
       }
     }
   },
   mounted() {
-  }
+
+  },
+  beforeDestroy() {
+    world.destroy();
+    world = null;
+  },
 }
 </script>
 
@@ -38,6 +42,7 @@
   left: 0;
   top: 0;
   z-index: 0;
+
   .world {
     width: 100%;
     height: 100%;
diff --git a/src/views/screen/components/screen-wrapper/index.vue b/src/views/screen/components/screen-wrapper/index.vue
index a6e27e1..b80e0e0 100644
--- a/src/views/screen/components/screen-wrapper/index.vue
+++ b/src/views/screen/components/screen-wrapper/index.vue
@@ -69,7 +69,7 @@
     const container = document.querySelector('.screen-wrapper');
     container.addEventListener('transitionend', this.checkAnimationEnd);
   },
-  destroyed() {
+  beforDestroy() {
     const container = document.querySelector('.screen-wrapper');
     container.removeEventListener('transitionend', this.checkAnimationEnd);
   }

--
Gitblit v1.8.0