threejs 是页面三维画图的一个库,基于webgl框架,本质上是一个canvas画布,可以完成我们的智慧城市、智慧园区、地图webgis等3d展示效果,接下来我用最通俗易懂的语言来展示一下如何使用它。
引入
- 原生 script 标签引入
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.156.1/three.min.js" type="module"></script>
- npm 下载使用
npm install three --save import * as THREE from 'three'
;
`
three 三要素
所谓三维场景,就是模拟人眼看的现实的事物,就可以理解用相机拍照,如果是动态的3d,就相当于用摄影机拍视频
- 场景 相当于根节点,里面包括着canvas画布的所有元素
new THTEE.Scene()
- 相机 拍照的相机
new THREE.PerspectiveCamera(50, 1, 0.1, 2000)
, 这四个参数分别表示
参数 | 含义 | 默认值 |
---|---|---|
fov | 相机视锥体竖直方向视野角度 | 50 |
aspect | 相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height | 1 |
near | 相机视锥体近裁截面相对相机距离 | 0.1 |
far | 相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向 | 2000 |
- 渲染器
THREE.WebGLRenderer()
将页面场景和相机元素渲染成最终效果,就相当于相机的快门。
物体
有了三要素,就形成了一个基本构图,接下来我们得定义一个物体。结合日常生活中,物体是由结构和材质组成的
定义一个正方体结构
const geometry = new THREE.BoxGeometry(100,100,100)
BoxGeometry 就是创建一个立方体, 传参为立方体的长宽高
定义一个材质
const meterial = new THREE.MeshBasicMaterial({color: 0xff00ff})
定义一个基础材质,颜色设置成红色
网格模型
three的基础是网格模型,场景中一个个的物体最终是以网格模型来呈现的,所以我们需要创建一个网格模型把立方体结构和材质结合起来,
const mesh = new THREE.Mesh(geometry, meterial)
添加物体到场景里面
scene.add(mesh)
到了这一步,创建物体就大功告成了。
创建并设置相机
const camera = new THREE.PerspectiveCamera(50, 1, 0.1, 2000)
创建透视相机camera.position.set(200,200,200)
设置相机位置(长宽高)camera.lookAt(0,0,0)
设置相机拍照目标位置(x, y, z坐标)
最终渲染
- 创建一个渲染器
const renderer = new THREE.WebGLRenderer()
- 渲染执行(按下快门)
renderer.render(scene, camera)
- 设置renderer结果的宽高
renderer.setSize(500, 500)
- 将渲染出来的结果插入到dom元素里面
document.body.appendChild(renderer.domElement);
完整代码
const scene = new THREE.Scene(); // 场景
const camera = new THREE.PerspectiveCamera(50, 1, 0.1, 2000);// 透视相机
const renderer = new THREE.WebGLRenderer(); // 渲染器
renderer.setSize(500, 500); // 设置渲染器的大小为窗口的内宽度,也就是内容区的宽度
// 将物体放入场景中
const geometry = new THREE.BoxGeometry(100, 100, 100);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
camera.position.set(200, 200, 200)
camera.lookAt(0,0,0)
// 执行渲染程序
renderer.render(scene, camera)
document.body.appendChild(renderer.domElement);