ZhangXianQiang
2024-04-19 3714d5ee4ab4305dcc3690bc1c3fa39c6bf5c6bd
feat:添加资源销毁,防止内存泄漏
10个文件已修改
211 ■■■■ 已修改文件
src/views/screen/components/screen-map-three/experience/camera.js 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/cssRenderer.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/index.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/renderer.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/utils/time.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/world/enviroment.js 39 ●●●●● 补丁 | 查看 | 原始文档 | 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 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-wrapper/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
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;
    }
}
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
@@ -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; // 这些属性包括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();
        });
@@ -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');
    }
}
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轴的位置");
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
@@ -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%;
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);
  }