threejs 3d地图实现省份下钻实例

threejs yekong

在之前我们使用echarts绘制的可以下钻的3d地图,vue echarts-gl 3d地图从中国下钻到市级实例,但是echarts-gl绘制出来的3d地图自定义程度不够,我们想要更加灵活的自定义3d地图,所以选择使用threejs来实现3d地图,今天我们来使用threejs来实现地图下钻实例。

3d地图的下钻本质上就是更换地图数据销毁重绘地图。

演示实例

threejs 3d地图实现省份下钻实例

效果截图

threejs 3d地图实现下钻实例

地图下钻动画

销毁地图

为了避免内存消耗,我们每次绘制新地图的时候需要先销毁旧地图。

destroyMap() {
      var that = this;
      if (that.scene) {
        that.renderer.setAnimationLoop(null);

        function disposeObject(obj) {
          if (obj.geometry) {
            obj.geometry.dispose();
          }
          if (obj.material) {
            if (Array.isArray(obj.material)) {
              obj.material.forEach((material) => {
                disposeMaterial(material);
              });
            } else {
              disposeMaterial(obj.material);
            }
          }
          if (obj.texture) {
            obj.texture.dispose();
          }
        }

        function disposeMaterial(material) {
          if (material.map) {
            material.map.dispose();
          }
          if (material.lightMap) {
            material.lightMap.dispose();
          }
          if (material.bumpMap) {
            material.bumpMap.dispose();
          }
          if (material.normalMap) {
            material.normalMap.dispose();
          }
          if (material.specularMap) {
            material.specularMap.dispose();
          }
          if (material.envMap) {
            material.envMap.dispose();
          }
          if (material.alphaMap) {
            material.alphaMap.dispose();
          }
          if (material.aoMap) {
            material.aoMap.dispose();
          }
          if (material.displacementMap) {
            material.displacementMap.dispose();
          }
          if (material.emissiveMap) {
            material.emissiveMap.dispose();
          }
          if (material.gradientMap) {
            material.gradientMap.dispose();
          }
          if (material.metalnessMap) {
            material.metalnessMap.dispose();
          }
          if (material.roughnessMap) {
            material.roughnessMap.dispose();
          }
          if (material.clearcoatMap) {
            material.clearcoatMap.dispose();
          }
          if (material.clearcoatRoughnessMap) {
            material.clearcoatRoughnessMap.dispose();
          }
          if (material.clearcoatNormalMap) {
            material.clearcoatNormalMap.dispose();
          }
          material.dispose(); // 释放材质
        }

        while (that.scene.children.length > 0) {
          const object = that.scene.children[0];
          that.scene.remove(object);
          disposeObject(object);
        }
        that.$refs.map3DMain.innerHTML = ''
        that.renderer.dispose(); // 释放 WebGLRenderer 占用的资源
      }
    }

点击选择地图

我们需要使用射线拾取来获取选中的地图,然后通过这个地图名称去获取地图数据,再进行销毁重绘即可,为了避免重绘地图导致重复注册点击事件,这里我们的点击事件设为1次。

that.chooseMap = function (event) {
var Sx = event.clientX; //鼠标单击位置横坐标
var Sy = event.clientY; //鼠标单击位置纵坐标
//屏幕坐标转WebGL标准设备坐标
var x = (Sx / window.innerWidth) * 2 - 1; //WebGL标准设备横坐标
var y = -(Sy / window.innerHeight) * 2 + 1; //WebGL标准设备纵坐标
//创建一个射线投射器`Raycaster`
var raycaster = new THREE.Raycaster();
//通过鼠标单击位置标准设备坐标和相机参数计算射线投射器`Raycaster`的射线属性.ray
raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
//返回.intersectObjects()参数中射线选中的网格模型对象
// 未选中对象返回空数组[],选中一个数组1个元素,选中两个数组两个元素
var intersects = raycaster.intersectObjects(meshGroup.children);
// intersects.length大于0说明,说明选中了模型
if (intersects.length > 0) {
  chooseMesh = intersects[0].object;
  if (chooseMesh.name) {
    console.log(chooseMesh.name)
    if (chooseMesh.name != that.listCode[that.listCode.length - 1].name) {
      that.areaName = chooseMesh.name
      that.getCode()
    }
  }
} else {
  chooseMesh = null;
}
addEventListener('click', that.chooseMap, {once: true});
}
addEventListener('click', that.chooseMap, {once: true});

实例代码下载

项目运行环境 vue3 vite js nodejs 14

相关文件下载地址
此资源需支付 ¥5 后下载
支付宝购买扫右侧红包码购买更优惠,如无法下载请联系微信:17331886870
喜欢
threejs 3d地图实现省份下钻实例