- Animating is like doing stop motion(定格动画)
- we need to update objects and do a render on each frame,we are going to do that in a function and call this function with window.requestAnimationFrame()
- the purpose of
requestAnimationFrame
is to call the function provided on the next frame
import * as THREE from "three"
// Scene
const scene = new THREE.Scene()
// Cube
const geometry = new THREE.BoxGeometry(1,1,1) // 1表示一个单位
const material = new THREE.MeshBasicMaterial({
color: '#ff0000'
})
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
// Sizes
const sizes = {
width: 800,
height: 600
}
// Camera
// 垂直视野,纵横比
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
// 修改camera位置,默认所有东西都在场景中心,也就是修改位置前camera位于立方体的内部中心
camera.position.set(0, 0, 10)
scene.add(camera)
// Render
const renderer = new THREE.WebGLRenderer({})
renderer.setSize(sizes.width, sizes.height)
document.body.appendChild(renderer.domElement)
// Animations
const tick = () => {
// Update objects
mesh.rotation.y += 0.01
// mesh.position.x += 0.01
// Render
renderer.render(scene, camera)
window.requestAnimationFrame(tick) // 仅传递方法,不调用,会在下一帧调用
}
tick()
-
适应帧率:Adapation to the framerate,仅使用
requestAnimationFrame
实现动画的话,因为显示器刷新率的不同,在不同的显示器会呈现出不同的动画速度
- 解决方法1:substract the previous time to get the deltaTime,思路:统一使用相同的速度
0.001
,获取帧与帧执行的时间差deltaTime
(单位:毫秒),使用公式位移s = 速度v * 时间t
(高刷新率的显示器,帧与帧的时间差值相对更小)
// Time
let time = Date.now()
// Animations
const tick = () => {
// Time
const currentTime = Date.now()
const deltaTime = currentTime - time // 帧间隔时长,单位毫秒,高刷新率的时长更短
time = currentTime
// console.log('deltaTime',deltaTime)
// Update objects
// mesh.position.x += 0.001 * deltaTime
mesh.rotation.y += 0.001 * deltaTime
// Render
renderer.render(scene, camera)
window.requestAnimationFrame(tick) // 仅传递方法,不调用,会在下一帧调用
}
tick()
- 解决方法2:three.js has a built-in solution named Clock
// Clock
const clock = new THREE.Clock() // 启动Clock
// Animations
const tick = () => {
// Clock
let elapsedTime = clock.getElapsedTime() // 获取自Clock启动后的秒数
// console.log('elapsedTime',elapsedTime)
// Update objects
// mesh.rotation.y = elapsedTime
// mesh.rotation.y = elapsedTime * Math.PI * 2 // 每秒转一圈
// mesh.position.y = Math.sin(elapsedTime)
// mesh.position.x = Math.cos(elapsedTime)
// camera.position.y = Math.sin(elapsedTime)
// camera.position.x = Math.cos(elapsedTime)
// camera.lookAt(mesh.position)
// Render
renderer.render(scene, camera)
window.requestAnimationFrame(tick) // 仅传递方法,不调用,会在下一帧调用
}
tick()
网友评论