Vue3+Three.js:第06期 实现立方体旋转动画
文章目录
- 目标
- 思考
- 物体的自动旋转
- 相机动起来
- 总结
目标
- 实现立方体的动画
思考
根据前两次的帖子,我们知道了,这个动画的实现是用到了requestAnimationFrame这个函数,而不是使用setInterval,requestAnimationFrame好嘛。
另外,这个动画与时间是有关系的,我们期望采用的是three.js里面的这个clock类
现在我们要实现立方体的动画,不是调用哪个混合器,而是要自己指挥这个立方体动起来。
应该是有两个角度:一个是立方体动起来,另一个是这个相机动起来
物体的自动旋转
有关物体的三维变化,在webgl中专门说过,这里先使用它的旋转这个功能,到三维变换,再具体说
- 关键是物体的旋转,主要放在哪里?
- 就是我们的动画函数中,在动画函数中,去更新我们的物体的位置,这里是旋转。
- 我们的动画函数,是由请求动画帧requestAnimationFrame这个函数不断调用的。这几次基本都一直在说。
- 下面是物体旋转的方法
// 3.创建物体(几何体 + 材质 = 物体)
const boxWidth = 1
const boxHeight = 1
const boxDepth = 1
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)
const material = new THREE.MeshBasicMaterial({ color: 0x44AA88 })
const cube = new THREE.Mesh(geometry, material)cube.rotation.x = 1
cube.rotation.y = 1
cube.rotation.z = 1
- 方式一:通过累加方式改变物体角度
- 方式二:通过requestAnimationFrame传入的时间改变物体角度
- 方式三:通过clock的时间改变物体角度
- 写在这个动画函数中就可以实现立方体动起来,这个角度需要不断的变化
- 随着requestAnimationFrame的不断调用,以及这个角度不断的增大,立方体的角度值就发生了变化
效果如下
备注,这里的立方体,是一直旋转运动的,用了requestAnimationFrame,但事实上没有用到时间这个变量。
这个根据需求,举例:在动画的第十秒绕y轴旋转到90度,这个时候,就必须用时间这个东西了。
上面只是为了演示,具体的需要根据需求来编写代码。
相机动起来
加上下面代码就可以了,只是相机离物体越来越远,并非旋转
效果如下:
修改为绕y轴旋转
效果如下:
完整代码,自己放在vue项目中直接调试
<script setup lang="ts">
import * as THREE from 'three'
import { onMounted, ref } from 'vue'const canvasThree = ref()// 创建scene、camera、renderer
let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, cube: THREE.Mesh
// 1.创建场景
function initScene() {scene = new THREE.Scene()
}
// 2.创建相机
function initCamera() {camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000,)camera.position.set(0, 0, 3)scene.add(camera)
}
// 3.创建物体(几何体 + 材质 = 物体)
function initCube() {const boxWidth = 1const boxHeight = 1const boxDepth = 1const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)const material = new THREE.MeshBasicMaterial({ color: 0x44AA88 })cube = new THREE.Mesh(geometry, material)scene.add(cube)
}
// 4.渲染场景
function initRenderer() {// 创建渲染器renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvasThree.value })// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight)
}// 5.动画循环渲染场景
function animate(time: number) {// 修改相机位置,绕y轴旋转camera.position.x = Math.sin(time / 1000) * 3camera.position.z = Math.cos(time / 1000) * 3camera.lookAt(scene.position)requestAnimationFrame(animate)// 渲染场景renderer.render(scene, camera)
}
onMounted(() => {// 初始化场景、相机、渲染器、物体initScene()initCamera()initRenderer()initCube()// 启动动画循环animate()
})
</script><template><canvas id="canvasThree" ref="canvasThree" />
</template>
总结
通过在动画中,也就是在每次requestAnimationFrame调用时,即时间的变化。修改立方体或者相机的位置,实现了旋转功能,说明这两条路线是可行的。其他的还有各种各样的需求,如:相机远离就是缩小、相机靠近就是放大、以及平移等等。