three.js 绘制3d地图
通过地图数据配合three可以做出非常酷炫的地图,在大数据展示中十分常见。
这篇郭先生就来说说使用three.js几何体制作3D地图。在线案例点击原文地址。
地图的数据是各个地图块的点数组,通过THREE.ExtrudeGeometry方法挤压出地图的版块,然后通过THREE.Line方法画出地图的分割线。地图的数据参见DATAV.GeoAtlas,鼠标悬浮到地图版块高亮,效果如图
1. 得到数据,遍历数据,处理数据
rawMap() { this.worldGeometry = mapJson; //mapJson就是地图的json数据 this.worldGeometry.features.forEach((worldItem, worldItemIndex) => { worldItem.geometry.coordinates.forEach(worldChildItem => { worldChildItem.forEach(countryItem => { //每个版块的点数组 this.drawExtrude(this.drawShape(countryItem)) //传递数据画出地图的shape,返回结果再传到drawExtrude方法得到ExtrudeGeometry网格 this.drawLine(countryItem); //传递数据画出地图边线 }); }); }); group.scale.y = 1.2; //group里面包含所有版块网格 scene.add(group); lineGroup.scale.y = 1.2; //lineGruop里面包含所有线的网格 scene.add(lineGroup); this.render(); }
2. 传递数据画出地图的shape,返回结果再传到drawExtrude方法得到ExtrudeGeometry网格。
drawShape(posArr) { var shape = new THREE.Shape(); shape.moveTo(posArr[0][0] - this.offsetX, posArr[0][1] - this.offsetY); posArr.forEach(item => { shape.lineTo(item[0] - this.offsetX, item[1] - this.offsetY); }); return shape; } drawExtrude(shapeObj) { var geometry = new THREE.ExtrudeGeometry(shapeObj, this.options); var material1 = new THREE.MeshPhongMaterial({ color: this.bgColor, specular: this.bgColor }); var material2 = new THREE.MeshBasicMaterial({ color: 0x008bfb }); let shapeGeometryObj = new THREE.Mesh(geometry, [material1, material2]); shapeGeometryObj.name = 'board'; group.add(shapeGeometryObj); }
3. 传递数据画出地图边线
drawLine(posArr) { let geometry1 = new THREE.Geometry(); let geometry2 = new THREE.Geometry(); posArr.forEach(item => { geometry1.vertices.push( new THREE.Vector3( item[0] - this.offsetX, item[1] - this.offsetY, 1.01 ) ); geometry2.vertices.push( new THREE.Vector3( item[0] - this.offsetX, item[1] - this.offsetY, -0.01 ) ); }); let lineMaterial = new THREE.LineBasicMaterial({ color: 0x008bfb }); let line1 = new THREE.Line(geometry1, lineMaterial); let line2 = new THREE.Line(geometry2, lineMaterial); lineGroup.add(line1); lineGroup.add(line2); }
4. 鼠标悬浮后高亮版块
handleMousemove(event) { event.preventDefault(); let mouse = new THREE.Vector2(0, 0); mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; this.raycaster.setFromCamera(mouse, camera); let intersects = this.raycaster.intersectObjects(group.children); this.previousObj.material[0].color = new THREE.Color(this.bgColor); if(intersects[0] && intersects[0].object) { intersects[0].object.material[0].color = new THREE.Color(0xffaa00); this.previousObj = intersects[0].object; //previousObj保存悬浮的对象,鼠标移开后恢复颜色。 } }
主要代码部分就是这样,我们也可以在颜色改变时加入一些渐变动画,three.js可以写出各种各样的地图,这是入门级的版本,希望给萌新一些启发。
转载请注明地址:郭先生的博客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?