现需要使用 Three.js 实现 3D 地图
我们需要思考 如何实现??? (完全没有Threejs 基础)
Q :如果使用 Three.js ,它是渲染出图形的?
A: 参考 Threejs中文网 文档介绍 npm 中 Three的下载路径
Threejs中文网具体地址
npm 中 Three的下载路径
从这个里面我知道 如果需要成功加载一个3D图形,我需要 5步走
- 创建环境
- 创建相机
- 创建渲染器
- 创建物体
- 渲染场景
//引入
import * as THREE from 'three';
const width = window.innerWidth, height = window.innerHeight;
// 1.创建一个场景
const scene = new THREE.Scene();
// 2.创建一个相机 PerspectiveCamera(透视摄像机)。
const camera = new THREE.PerspectiveCamera( 70, width / height, 0.01, 10 );
camera.position.z = 1; //向z轴偏移
// 3.创建渲染器
const renderer = new THREE.WebGLRenderer( {
antialias: true } );
renderer.setSize( width, height ); //渲染多大 要尺寸
//4.创建一个物体 构造器 Mesh 由 几何体+材质构成
const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 ); //BoxGeometry 立方缓冲几何体
const material = new THREE.MeshNormalMaterial(); //材质 基础网格材质
const mesh = new THREE.Mesh( geometry, material ); // 构造器
scene.add( mesh );
//5.渲染场景
renderer.setAnimationLoop( animation );
document.body.appendChild( renderer.domElement ); //添加到页面中
// animation
function animation( time ) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render( scene, camera );
}
Q :我们已经解决了 Three 是如何展示3D图形的,那么实现3D地图,我需要那些必备的属性?
A: 我们本质上只需要改变它的物体就可以了,让他变成地图,展示出来
这里地图的 几何体我们该用什么? 地图的材质要用什么? 地图的数据该从哪里来?如何才能展现出来?
几何体有哪些?
材质有那些?
地图的几何体用 :
挤压缓冲几何体(ExtrudeGeometry) 参考示例
基础线条材质(LineBasicMaterial) 参考示例 用来单独描线的 也可以不用 ,根据需求来
地图的材质用:
基础网格材质(MeshBasicMaterial) 介绍
示例:
/*
ExtrudeGeometry(shapes : Array, options : Object)
shapes — 形状或者一个包含形状的数组。
options — 一个包含有下列参数的对象:
curveSegments — int,曲线上点的数量,默认值是12。
steps — int,用于沿着挤出样条的深度细分的点的数量,默认值为1。
depth — float,挤出的形状的深度,默认值为1。
bevelEnabled — bool,对挤出的形状应用是否斜角,默认值为true。
bevelThickness — float,设置原始形状上斜角的厚度。默认值为0.2。
bevelSize — float。斜角与原始形状轮廓之间的延伸距离,默认值为bevelThickness-0.1。
bevelOffset — float. Distance from the shape outline that the bevel starts. Default is 0.
bevelSegments — int。斜角的分段层数,默认值为3。
extrudePath — THREE.Curve对象。一条沿着被挤出形状的三维样条线。Bevels not supported for path extrusion.
UVGenerator — Object。提供了UV生成器函数的对象。
该对象将一个二维形状挤出为一个三维几何体。
当使用这个几何体创建Mesh的时候,如果你希望分别对它的表面和它挤出的侧面使用单独的材质,你可以使用一个材质数组。 第一个材质将用于其表面;第二个材质则将用于其挤压出的侧面。
属性
*/
const length = 12, width = 8;
const shape = new THREE.Shape(); //形状
shape.moveTo( 0,0 );
shape.lineTo( 0, width );
shape.lineTo( length, width );
shape.lineTo( length, 0 );
shape.lineTo( 0, 0 );
const extrudeSettings = {
steps: 2,
depth: 16,
bevelEnabled: true,
bevelThickness: 1,
bevelSize: 1,
bevelOffset: 0,
bevelSegments: 1
};
const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
const material = new THREE.MeshBasicMaterial( {
color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );
由此 我们知道了,地图的是通过这个 shape 描绘成形状展示的,数据可以通过 datav.aliyun 地图json小工具 获取到
数据拿到之后,就是展示的问题,直接展示是不行的,需要通过 d3 对数据处理,才能按照正确的地图样子展示
import * as d3 from "d3"; //莫开托坐标 矫正地图坐标
//center 的位置可以自己定
const handleProj = d3.geoMercator().center([109, 34.5]).scale(1000).translate([0, 0]) // d3投影转换函数
接下来就是封装地图信息 ,使它变成这个样子 (这里用到了)
const shape = new THREE.Shape(); //形状
shape.moveTo( 0,0 );
shape.lineTo( 0, width );
shape.lineTo( length, width );
shape.lineTo( length,