头图

直接看成品
立方体.gif

可以看到点击开始旋转的时候立方体开始旋转,点击停止旋转的时候立方体停止旋转。


先放官网文档threejs官网

image.png

点击en切换为中文,然后点击创建第一个场景,页面就全部变成中文啦。


先使用原生js编写代码,首先就是下载threejs然后引入

    <script src="./three.js"></script>

然后就可以使用THREE这个对象了

要创建一个立方体,首先我们需要创建一个场景,一个摄像机,一个渲染器,这样我们才能透过摄像机看到渲染出的场景

var width = 500
var height = 500
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75,width/height,0.1,1000)
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width,height);
document.body.appendChild(renderer.domElement);

首先我定义了整体的宽高,如果直接用window.innerWidthinnerHeight的话,就占满了整个页面,所以我选择固定一个小一点的宽高,方便观察和后续添加元素。

threejs有几种不同的相机,这里用的是PerspectiveCamera(透视相机)。
第一个参数是视野角度(FOV),就是你能在显示器上看到的场景范围,单位是角度(与弧度不同)
经常玩游戏的人肯定知道这个参数的作用,比如射击游戏里,FOV越大,能看到的场景越多
这里推荐一个FOV有关的资料https://zhuanlan.zhihu.com/p/...

第二个参数是长宽比,即画面的比例,比如4:3、16:9这种。比例设置不对,那一个物体看起来就会被压扁或者拉伸。

接下来两个参数是近截面和远截面。当一个物体的某个部分离摄像机的近截面更近或者远截面更远的时候,这部分就不会被渲染到场景里。

下面就是渲染器了,这里使用的是WebGLRenderer渲染器,其他的我暂时没有用过,也不懂。

创建完渲染器实例以后,我们还需要设置渲染尺寸,如果整个页面都需要渲染,那就把setSize里的参数改为浏览器的宽高,如果性能不行,可以尝试调小这个值,比如都除以2。

最后一步就是把渲染器renderer的dom元素renderer.domElement添加到我们的HTML中,也就是在页面里增加了一个<canvas>

当然,现在页面上还是一片白,因为我们没有真正的渲染canvas里面的东西

加上这一步

function animate() {
    renderer.render( scene, camera );
}
animate();

就可以看到页面上渲染出来了一个黑色的区域
image.png


第二步,摆个盒子上去

先上代码

const geometry = new THREE.BoxGeometry(1,1,1);
const material = new THREE.MeshBasicMaterial({color:0x00ff00});
const cube = new THREE.Mesh(geometry,material);
scene.add(cube);
camera.position.z = 5;

要创建一个立方体,我们需要一个BoxGeometry对象,这个对象包含了一个立方体中所有的顶点和面。

下面,我们需要给这个立方体一个材质,让它有颜色。Threejs自带了几种材质,这里使用的是MeshBasicMaterial。所有的材质都存有应用于他们属性的对象。这里简单化,只设置一个color属性,值为0x00ff00 注意,和CSS中的十六进制不同。

第三步,我们需要一个Mesh(网格)。网格包含一个几何体以及作用在该几何体上的材质。直接讲该网格对象放入到场景中。

一般情况下,当我们调用scene.add()方法的时候,物体将被直接添加到(0,0,0)坐标,摄像机默认位置也在这里,所以为了避免物体和摄像机重叠,我们需要将摄像机往外移动一点,即设置cameraposition中的z轴值为5就行

保存以后,页面上就变成了这样

image.png


第三步,让立方体动起来

首先弄两个按钮上去

<div>
    <div class="btn" onclick="btnfunc()">点我开始旋转</div>
    <div class="btn" onclick="cancel()">点我停止旋转</div>
</div>

image.png

记得上面我们使用了一个方法,这个方法是用来渲染出立方体和场景的,只会执行一次

function animate() {
    renderer.render( scene, camera );
}

接下来我们写旋转的方法

function btnfunc(){
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render(scene,camera)
}

发现动是动了,但是是点一下,动一下,明显不符合要求

这里有两个方法,第一个方法是增加一个setInterval来重复执行这个方法
另一个方法是使用requestAnimationFrame()方法
requestAnimationFrame更好,因为这是浏览器自带的重复执行方法,执行的间隔就是你显示器的刷新率,如果是60的,就一秒钟更新六十次,如果是90的,就一秒钟更新90次,不会有割裂感,更重要的是,当页面挂在后台的时候,这个方法是暂停的,极大节约了系统的压力。
将旋转方法改动下:

function btnfunc(){
  requestAnimationFrame(btnfunc);
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render(scene,camera)
}

这样,点击一下,立方体就会自动旋转了。


停止旋转

前面我们让立方体动起来了,现在我们需要它停下,官网的文档这点非常不好,只有开始旋转没有停止旋转,虎头蛇尾。

根据百度可以知道,requestAnimationFrame()参数会返回一个id,而cancelAnimationFrame()接受一个id,停止其动作,所以我们需要这样做

var animationId = ''
function btnfunc(){
    animationId = requestAnimationFrame(btnfunc);
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    renderer.render(scene,camera)
    console.log(animationId)
}

function cancel(){
    cancelAnimationFrame(animationId);
}

这样就可以停止旋转啦。


munergs
30 声望6 粉丝

现在即是最好。


引用和评论

0 条评论