目标

  • 实现立方体的动画

思考

根据前两次的帖子,我们知道了,这个动画的实现是用到了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 = 1
  const boxHeight = 1
  const boxDepth = 1
  const 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) * 3
  camera.position.z = Math.cos(time / 1000) * 3
  camera.lookAt(scene.position)

  requestAnimationFrame(animate)
  // 渲染场景
  renderer.render(scene, camera)
}
onMounted(() => {
  // 初始化场景、相机、渲染器、物体
  initScene()
  initCamera()
  initRenderer()
  initCube()

  // 启动动画循环
  animate()
})
</script>

<template>
  <canvas id="canvasThree" ref="canvasThree" />
</template>

总结

通过在动画中,也就是在每次requestAnimationFrame调用时,即时间的变化。修改立方体或者相机的位置,实现了旋转功能,说明这两条路线是可行的。其他的还有各种各样的需求,如:相机远离就是缩小、相机靠近就是放大、以及平移等等。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐