老板最近让改threejs代码的需求
前端小实习记录一下初学three.js
从Hello cube!开始
欢迎各位大佬批评指正
官方文档:three.js
1、首先安装threejs
npm install --save three
2、需要一个canvas标签
<template>
<div class="three-canvas">
<h1>hello cube!</h1>
<canvas id="c"></canvas>
</div>
</template>
3、引入threejs
轨道控制器可以实现鼠标效果,实现旋转、放大缩小等功能
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //引入轨道控制器
4、定义data
- 首先有一个渲染器(
Renderer)。这可以说是three.js的主要对象。你传入一个场景(Scene)和一个摄像机(Camera)到渲染器(Renderer)中,然后它会将摄像机视椎体中的三维场景渲染成一个二维图片显示在画布上。
data() {
return {
camera: null,
scene: null,
renderer: null,
cube:null,
cubes:null,
geometry:null,
// 轨道控制器
orbitControls:null,
}
},
5、
methods: {
init() {
const canvas = document.querySelector('#c')
this.renderer = new THREE.WebGLRenderer({ //创建一个WebGL渲染器
antialias: true, //是否开启反锯齿
canvas //渲染器WebGLRenderer 负责将提供的所有数据渲染绘制到 canvas 上
})
// 需要一个透视摄像机 PerspectiveCamera
const fov = 75; //视野范围 field of view 垂直方向为75度
const aspect = 2; //相机默认值 画布的宽高比 默认情况下: 画布是300x150像素
const near = 0.1; //近平面
const far = 5; //远平面 近平面和远平面限制了摄像机面朝方向的可绘区域。 任何距离小于或超过这个范围的物体都将被裁剪掉(不绘制)
// 四个参数定义了一个“视锥(frustum)”。是指一个像被削去顶部的金字塔形状。可以想象成其他三维形状如球体、立方体、棱柱体、截锥体
this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
this.camera.position.z = 2 //摄像机默认指向Z轴负方向,上方向朝向Y轴正方向。将立方体放置在坐标原点,需要后移一下摄像机才能显示出物体
this.scene = new THREE.Scene(); //创建一个场景
//创建一个包含盒子信息的立方几何体 BoxGeometry
const boxWidth = 1;
const boxHeight = 1;
const boxDepth = 1;
this.geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
// 创建一个基本的材质 并设置它的颜色
// MeshBasicMaterial材质不会受到灯光的影响。我们将他改成会受灯光影响的MeshPhongMaterial材质。
const material = new THREE.MeshPhongMaterial({color: 0x44aa88});
// 创建一个网格(Mesh)对象,包含:1、几何体(Geometry)(物体的形状);2、材质(Material)(如何绘制物体,光滑还是平整,什么颜色,什么贴图等);3、对象在场景中相对于他父对象的位置、朝向、和缩放。
this.cube = new THREE.Mesh(this.geometry, material);
// 将网格添加到场景中
this.scene.add(this.cube);
// 将场景和摄像机传递给渲染器来渲染出整个场景
this.renderer.render(this.scene, this.camera)
// 增加光照效果
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(-1, 2, 4); //将灯光位置设为(-1,2,4) 位于摄像机前面稍微左上方一点的地方
this.scene.add(light);
// 轨道控制器 实现鼠标旋转缩放
this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement)
},
// 让立方体旋转起来 需要用到一个渲染循环函数 requestAnimationFrame
// requestAnimationFrame会将页面开始加载到函数运行所经历的时间当作入参传给回调函数,单位是毫秒数。
// render(time) {
// time *= 0.001; //将时间单位变为秒
// this.cube.rotation.x = time;
// this.cube.rotation.y = time;
// this.renderer.render(this.scene, this.camera);
// requestAnimationFrame(this.render);
// },
// 创建一个根据指定颜色生成新材质的函数。根据指定的几何体生成对应网格,然后将网格添加进场景并设置其X轴的位置
makeInstance(geometry, color, x) {
const material = new THREE.MeshPhongMaterial({color});
this.cube = new THREE.Mesh(geometry, material);
this.scene.add(this.cube);
this.cube.position.x = x;
return this.cube
},
// 多个立方体自动旋转
render(time) {
time *= 0.001; //将时间单位变为秒
this.init();
this.animate() //逐帧渲染
// const canvas = this.renderer.domElement;
// this.camera.aspect = canvas.clientWidth / canvas.clientHeight; //将相机的宽高比设置为canvas的宽高比,保持正常比例
// this.camera.updateProjectionMatrix();
if (this.resizeRendererToDisplaySize(this.renderer)) {
const canvas = this.renderer.domElement;
this.camera.aspect = canvas.clientWidth / canvas.clientHeight;
this.camera.updateProjectionMatrix();
}
// 实现多个正方体
// this.cubes = [
// this.makeInstance(this.geometry, 0x44aa88, 0),
// this.makeInstance(this.geometry, 0x8844aa, -2),
// this.makeInstance(this.geometry, 0xaa8844, 2),
// ];
// this.cubes.forEach((cube, ndx) => {
// const speed = 1 + ndx * .1;
// const rot = time * speed;
// cube.rotation.x = rot;
// cube.rotation.y = rot;
// });
this.renderer.render(this.scene, this.camera);
// requestAnimationFrame(this.render);
},
// 写一个函数来检查渲染器的canvas尺寸是不是和canvas的显示尺寸不一样 如果不一样就设置它。
resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
},
// 逐帧渲染 threejs
animate() {
this.renderer.render(this.scene, this.camera)
requestAnimationFrame(this.animate)
}
},
6、
mounted() {
// this.init();
this.render()
},
有点蛇头蛇尾了哈哈哈哈,具体内容都写在注释里啦hhh