基于Three.js制作一个3D中国地图
目录
- 1.使用geoJson绘制3d地图
- 1.1 创建场景相关
- 1.2 根据json绘制地图
- 2.增加光照
- 3.增加阴影模糊
- 4.增加鼠标事件
- 5.渲染
- 6.动画效果
github
下载项目,如果可以顺便来个star
哈哈本项目使用
vue-cli
创建,但不影响使用,主要绘制都已封装成类1.使用geoJson绘制3d地图
1.1 创建场景相关
// 创建webGL渲染器this.renderer = new THREE.WebGLRenderer( { antialias: true,alpha: true} ); this.renderer.shadowMap.enabled = true; // 开启阴影this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; this.renderer.toneMapping = THREE.ACESFilmicToneMapping; this.renderer.toneMappingExposure = 1.25; // 根据自己的需要调整颜色模式// this.renderer.outputEncoding = THREE.sRGBEncoding; this.renderer.outputEncoding = THREE.sHSVEncoding; this.renderer.setPixelRatio( window.devicePixelRatio ); // 清除背景色,透明背景this.renderer.setClearColor(0xffffff, 0); this.renderer.setSize(this.width, this.height); // 场景this.scene = new THREE.Scene(); this.scene.background = null// 相机 透视相机this.camera = new THREE.PerspectiveCamera(45, this.width / this.height, 0.1, 5000); this.camera.position.set(0, -40, 70); this.camera.lookAt(0, 0, 0);
1.2 根据json绘制地图
利用
THREE.Shape
绘制地图的平面边数据,再用THREE.ExtrudeGeometry
将一个面拉高成3d模型,3d饼图同理也可以这么制作let jsonData = https://www.it610.com/article/require('./json/china.json')this.initMap(jsonData); // initMap 方法主要部分initMap(chinaJson) {/* ...省略...*/chinaJson.features.forEach((elem, index) => {// 定一个省份3D对象const province = new THREE.Object3D(); // 每个的 坐标 数组const { coordinates } = elem.geometry; const color = COLOR_ARR[index % COLOR_ARR.length]// 循环坐标数组coordinates.forEach(multiPolygon => {multiPolygon.forEach((polygon) => {const shape = new THREE.Shape(); for (let i = 0; i < polygon.length; i++) {let [x, y] = projection(polygon[i]); if (i === 0) {shape.moveTo(x, -y); }shape.lineTo(x, -y); }const extrudeSettings = {depth: 4,bevelEnabled: true,bevelSegments: 1,bevelThickness: 0.2}; const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); // 平面部分材质const material = new THREE.MeshStandardMaterial( {metalness: 1,color: color,} ); // 拉高部分材质const material1 = new THREE.MeshStandardMaterial( {metalness: 1,roughness: 1,color: color,} ); const mesh = new THREE.Mesh(geometry, [material,material1]); // 设置高度将省区分开来if (index % 2 === 0) {mesh.scale.set(1, 1, 1.2); }// 给mesh开启阴影mesh.castShadow = truemesh.receiveShadow = truemesh._color = colorprovince.add(mesh); })})_this.map.add(province); })}
geoJson
的坐标需要进行墨卡托投影转换才能转换成平面坐标,这里需要用到d3
// 墨卡托投影转换const projection = d3.geoMercator().center([104.0, 37.5]).scale(80).translate([0, 0]);
2.增加光照 我们把各种光都打上,环境光,半球光,点光,平行光。以平行光为例,增加投影,调整投影分辨率,避免投影出现马赛克
const light = new THREE.DirectionalLight( 0xffffff, 0.5 ); light.position.set( 20, -50, 20 ); light.castShadow = true; light.shadow.mapSize.width = 1024; light.shadow.mapSize.height = 1024; this.scene.add(light);
castShadow = true
表示开启投影3.增加阴影模糊 默认的阴影没有模糊效果,看起来像白炽灯照射的样子,没有柔和感。使用官方示例中的
csm
来增加阴影模糊import { CSM } from 'three/examples/jsm/csm/CSM.js'; this.csm = new CSM( {maxFar: params.far,cascades: 4,mode: params.mode,parent: this.scene,shadowMapSize: 1024,lightDirection: new THREE.Vector3( params.lightX, params.lightY, params.lightZ ).normalize(),camera: this.camera} );
4.增加鼠标事件 在
3d
空间中,鼠标事件主要通过射线来获取鼠标所在位置,可以想象成鼠标放出一道射线,照射到的第一个物体就是鼠标所在位置。此时用的threejs
的Raycaster
,通过Raycaster
给对应的省份增加鼠标移入高亮效果和省份民悬浮展示效果this.raycaster = new THREE.Raycaster(); // 传入需要检测的对象 group,group下的所有对象都会被检测到,如果被射线照到,则intersects有值,表示鼠标当前在这些物体上const intersects = this.raycaster.intersectObject( this.group, true ); // 代码太多就不贴了,见 GitHub源码
5.渲染
threejs
的渲染一般调用原生的requestAnimationFrame
,主要做的事就是调用renderer
的render
方法,当然因为我们做了阴影模糊处理,所以还有别的需要做的:this.camera.updateMatrixWorld(); this.csm.update(); this.renderer.render(this.scene, this.camera);
6.动画效果 地图上如果有一些动画效果,可以使用
TWEEN.js
,github地址,比如地图标注的出现动画:文章图片
最后再奉上项目地址
【基于Three.js制作一个3D中国地图】到此这篇关于基于Three.js制作一个3D中国地图的文章就介绍到这了,更多相关Three.js 3D中国地图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 使用Three.js制作一个3D奖牌页面
- Java毕设项目|基于JavaScript+html5的家教小程序的设计与实现
- 使用Three.js实现神奇的3D文字悬浮效果
- 基于Kubernetes/K8S构建Jenkins持续集成平台(下)
- 图解大数据|图解大数据 | 基于Spark RDD的大数据处理分析
- 基于FeignException$InternalServerError的解决方案
- springboot-curd基于mybatis项目搭建
- Vue|基于vue+srpingboot的学生成绩管理系统
- 基于mybatis一对多查询内层排序的问题
- 深度学习(基于pytorch)|深度学习笔记(七)——pytorch数据处理工具箱(一)