利用ThreeJS制作3D地图
就像我们拆组件、写方法一样,我们可以将画轮廓、画地图的方法包装一下放到 JS 文件里导出,只要给 json 数据,就直接给他返回一个模型,然后再封装一下render()函数,这样日后画一个地图就会很方便。
推荐使用NSDT 3DConvert进行3D模型格式转换,支持glb、obj、stp、fbx、ifc等多种3D模型格式之间进行互相转换,在转换过程中,能够很好的保留模型原有的颜色、材质等信息。
ThreeJS简介
OpenGL 是一个跨平台 3D/2D 的绘图标准,WebGL 则是 openGL 在浏览器上的一个实现。web 前端开发人员可以直接用 WebGL 接口进行编程,但 WebGL 只是非常基础的绘图 API,需要编程人员有很多的数学知识、绘图知识才能完成 3D 编程任务,而且代码量巨大。Threejs 对 WebGL 进行了封装,让前端开发人员在不需要掌握很多数学知识和绘图知识的情况下,也能够轻松进行 web 3D 开发,降低了门槛,同时大大提升了效率。
ThreeJS 的几个要素
1. 场景
场景就像环境一样,用来放我们要添加的所有东西。
2. 相机
相机可以当作我们的眼睛,没有相机,我们就看不到任何东西。相机有很多种。
3. 灯光
就像我们没有灯光就看不见东西一样,我们需要灯光来照亮东西。光分很多种,有环境光,点光源,聚光灯,平行光等等,不同的光的照亮效果不一样。
4. 场景控制器
这里我们用它来控制场景里的所有东西,当我们拖动场景缩小放大的时候,实际上就是在控制相机移动。
5. 渲染器
渲染器,把注册的所有东西渲染到场景中。
绘制一个 3D 地图
我们可以用 json 数据,收尾连线的方式,画出轮廓线和中国地图,再挤压画出的平面图形,让其成为有厚度的 3D 模型。
我们也可以直接引入成型的地图模型,渲染就完事了。不过对于这种简单的模型,建议使用 json 数据画出来,因为加载模型的话,模型大小是一个问题,网页打开时加载模型需要一些时间,影响体验,而且,你得有一个愿意配合你的小伙伴。
我们采用上面所说的第一种方式。
简单讲解一下画模型的思路: 首先,模型由两点构成 几何体 和 网格,我们可以理解为,一个没穿衣服的光秃秃模型和它的衣服。所以显然易见,我们选择一个几何体(或者画出一个几何体),然后给他穿个衣服(给他捯饬捯饬,弄点颜色透、明度之类的属性,也可以贴图上去)。
1. 画出轮廓线
2. 画出地图形状,并且挤压出厚度
3. 渲染模型
为什么要做响应式处理?
我们先来了解一下 requestAnimationFrame
[1] requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率。
[2] 在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的 CPU、GPU 和内存使用量。
[3] requestAnimationFrame 是由浏览器专门为动画提供的 API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了 CPU 开销。
即使用了 requestAnimationFrame,我们还要注意的是:相机的会在每次render()
时计算更新投影矩阵
,但是如果渲染区域没有变化的话,我们就没有必要一直计算更新,所以我们在每次执行渲染函数时,计算出渲染区域大小是否发生变化,如果没有,就不去更新它,以此节省性能。
4. 鼠标移动 区域高亮
实现方法:从一个地方发射一条射线,调用方法返回交叉点的数组,对穿过的模型进行操作。