Three.JS是基于WebGL的Javascript开源框架,一模一样的效果我也有用webGL做过,链接是这个https://segmentfault.com/a/11...
html部分还是很简单
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demoThree</title></head><body> <canvas id="demo-three"></canvas></body><script type="text/javascript" src="./three.js"></script><script type="text/javascript" src="./demo_three.js"></script></html>
下面是js部分,每行代码都有比较详细的注释解释
// 定义宽高const width = 400;const height = 400;const canvas = document.getElementById('demo-three');// WebGLRenderer如果不传参数不会把dom元素和最终渲染出来的屏幕上的html上的dom元素相关联,那种情况就需要把domElement,append到body上,才能有相关画布出现let renderer = new THREE.WebGLRenderer({ canvas});// 绘制场景,在scene中维护在场景中渲染的物体let scene = new THREE.Scene();// 使用正交相机(没有透视效果,适合我们这次的平面三角形),正交相机需要定义上下左右前后的坐标情况,从而规定正交相机所能截取到的相关的平面空间中,物体的情况(视角空间的截取)let camera = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, -1000, 1000)// 黑色背景,透明度1.0renderer.setClearColor(new THREE.Color(0x000000), 1.0);// renderer大小renderer.setSize(400, 400);// 在three.js官网可查看,有很多预定义的geometry,但是没有三角形,我们可以通过shapeGeometry来绘制let triangleShape = new THREE.Shape();// 将绘制起始点移动到(const0, 100)这个位置triangleShape.moveTo(0, 100);// 开始划线triangleShape.lineTo(-100, -100);triangleShape.lineTo(100, -100);triangleShape.lineTo(0, 100);// 定义几何体const geometry = new THREE.ShapeGeometry(triangleShape);// 定义材质,三角形只是基本图形,不需要光照const material = new THREE.MeshBasicMaterial({ color: 0xff0000, // 默认是一面的(只渲染法向量所对应那一面),定义为DoubleSide,将正反面都渲染出来 side: THREE.DoubleSide});// 第一个参数geometry,是我们之前定义的几何体的坐标情况,就很像之前的webGl中顶点着色器传入的顶点序列,不涉及颜色信息,只是定义几何体形状// 第二个参数material, 很像webGl中片段着色器中的,给顶点序列上色let mesh = new THREE.Mesh(geometry, material);// 设置mesh在scene中的位置mesh.position.x = 0;mesh.position.y = 0;mesh.position.z = 1;scene.add(mesh);// 相机沿着z轴负方向望进去,所以把相机设置在了原点// 设置位置直接通过position,要比原生webGl去修改往顶点着色器传的数据要方便很多camera.position.x = 0;camera.position.y = 0;camera.position.z = 0;// camera从(0, 0, 0)的位置望向(0,0,1)camera.lookAt(new THREE.Vector3(0, 0, 1));let currentAngle = 0;let lastTimestamp = Date.now();function animate() { // 记下时间,拿到现在的时间戳,因为每次requestAnimationFrame间隔时间是不知道的 const now = Date.now(); // 减去老的时间戳 const duration = now - lastTimestamp; lastTimestamp = now; // 想要requestAnimationFrame间隔时间内转180度 currentAngle = currentAngle + duration / 1000 * Math.PI;}function render() { animate(); // mesh绕y轴旋转currentAngle角度 mesh.rotation.set(0, currentAngle, 0); // 渲染 renderer.render(scene, camera); requestAnimationFrame(render);}render();
效果: