使用vue2+three.js帮你快速打造一个精美的3D可视化地图
npm i three@0.136.0
这里我使用的是136版本,想要别的版本可以去npm下载
想要搭建一个three.js的项目,离不开三个基础要素:
我们优先对他们进行构建
首先构建场景,他有几个关键属性,后续的开发会讲到,你可以把他想象成做菜的锅,锅造好了就可以往里面加菜了
getScene(){
scene = new THREE.Scene()
}
摄像机就可以理解为广义的真实相机,只是他对着屏幕而已,他有三个轴x、y、z轴。
x和y轴就是普通的2d轴,我们的目光看向电脑 我们的目光构成的线 就是z轴
相机主要有两种相机:
我们这次使用透视相机
getCamera(){
// 第二参数就是 长度和宽度比 默认采用浏览器 返回以像素为单位的窗口的内部宽度和高度
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
)
camera.position.z=10
camera.lookAt(scene.position)
}
THREE.PerspectiveCamera(fov, aspect, near, far)
参数 | 作用 |
---|---|
fov | 相机视锥体竖直方向视野角度 |
aspect | 相机视锥体水平方向和竖直方向长度比 |
near | 相机视锥体近裁截面相对相机距离 |
far | 相机视锥体远裁截面相对相机距离 |
如果你觉得很蒙,那你先照着代码上的设置,然后慢慢去更改,你就能理解他的具体作用了
getRenderer(){
let that=this
renderer = new THREE.WebGLRenderer({
// antialias:true,
// alpha: true,
})
//开启阴影
//renderer.shadowMap.enabled = true;
// renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
let canvas=renderer.context.canvas
canvas.addEventListener(
'webglcontextlost',
function (event) {
event.preventDefault();
setTimeout(function () {
alert("您的运行内存不足,建议您刷新浏览器或者重启电脑")
// cancelAnimationFrame(that.AnimationFrameId)
// that.renderer.forceContextRestore();
}, 1);
},
false
);
console.log("渲染器构建完成",renderer)
}
渲染器可以看做炒菜的厨师,没有他,有锅有菜也没用,所以我们先需要找到这个厨师,然后 再让他开始炒菜。
addHelper() {
const helper = new THREE.CameraHelper(camera)
scene.add(helper)
},
他会显示轴线和中心点,帮助我们进行定位
使用控制器需要额外引用,不过就在three包里。
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
setController() {
controller = new OrbitControls(
camera,
renderer.domElement
)
}
他会让我们用鼠标移动视角。
构建一个正方体,加入场景,至于贴图和几何后面会讲
getBox(){
let geometry = new THREE.BoxGeometry(6,6 ,6);
let material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
let cube = new THREE.Mesh(geometry, material);
scene.add(cube);
},
animate(){
this.AnimationFrameId=requestAnimationFrame(this.animate.bind(this))
this.render()
},
render(){
renderer.render(scene, camera);
},
requestAnimationFrame 简单理解为一个加强版的 setinterval()
不断地调用渲染
renderer.render 调用渲染器开始渲染,也就是叫厨师开始炒菜
init(){
this.getScene()
this.getRenderer()
this.getCamera()
this.getBox()
this.addHelper()
this.setController()
this.animate()
},
mounted(){
this.init()
}