ZhangXianQiang
2024-04-19 3714d5ee4ab4305dcc3690bc1c3fa39c6bf5c6bd
feat:添加资源销毁,防止内存泄漏
10个文件已修改
195 ■■■■■ 已修改文件
src/views/screen/components/screen-map-three/experience/camera.js 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/cssRenderer.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/index.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/renderer.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/utils/time.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/world/enviroment.js 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/world/map.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/world/world.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/index.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-wrapper/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/camera.js
@@ -6,12 +6,11 @@
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();
    }
    // 设置透视相机
@@ -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;
    }
}
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();
  }
}
src/views/screen/components/screen-map-three/experience/index.js
@@ -28,8 +28,8 @@
    // 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);
    
@@ -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; // 这些属性包括position, 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;
  }
}
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();
    }
}
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();
        });
@@ -18,8 +19,13 @@
        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');
    }
}
src/views/screen/components/screen-map-three/experience/world/enviroment.js
@@ -117,6 +117,43 @@
    }
  }
  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();
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; // 这些属性包括position, 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;
    }
}
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();
  }
}
src/views/screen/components/screen-map-three/index.vue
@@ -18,7 +18,6 @@
  watch: {
    loadEnd: {
      handler(newVal) {
        console.log(newVal);
        if(newVal) {
          world = new Experience(this.$refs.worldContainer);
        }
@@ -26,7 +25,12 @@
    }
  },
  mounted() {
  }
  },
  beforeDestroy() {
    world.destroy();
    world = null;
  },
}
</script>
@@ -38,6 +42,7 @@
  left: 0;
  top: 0;
  z-index: 0;
  .world {
    width: 100%;
    height: 100%;
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);
  }