Three.js 中的 Clock
是一个用于跟踪时间的实用工具类,在3D动画、游戏开发和交互式场景中扮演着重要角色。下面我将全面介绍 Clock
的功能、用法和最佳实践。
一、Clock 基本概念
Clock
是 Three.js 提供的一个轻量级时间跟踪工具,主要用于:
-
计算帧间时间差(delta time),实现帧率无关的平滑动画 12
-
测量应用程序运行的总时间,用于时间相关逻辑 1
-
替代原生 JavaScript 的
Date
对象,提供更专业的时间管理功能 37
与原生 Date
相比,Clock
的优势在于:
-
专门为动画和渲染优化
-
提供简单易用的时间差计算
-
自动处理暂停/恢复逻辑
-
与
requestAnimationFrame
完美配合 3
二、Clock 的核心API
1. 构造函数
const clock = new THREE.Clock(autoStart);
-
autoStart
: 可选参数,默认为true
,表示是否在创建时自动启动时钟 14
2. 主要方法
-
start(): 启动时钟,重置计时 18
-
stop(): 停止时钟 27
-
getElapsedTime(): 返回自时钟启动后的总运行时间(秒)14
-
getDelta(): 返回自上次调用该方法以来的时间差(秒)17
3. 主要属性
-
running: 只读属性,指示时钟是否在运行 28
-
elapsedTime: 总运行时间(秒)47
-
autoStart: 是否自动启动 78
三、基础使用示例
1. 创建简单动画
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta(); // 获取帧间时间差
cube.rotation.x += delta; // 使用时间差控制旋转速度
cube.rotation.y += delta * 0.5;
renderer.render(scene, camera);
}
animate();
这段代码实现了立方体的平滑旋转,且旋转速度不受帧率影响 12
2. 控制多个物体动画
const cubes = [];
// 创建多个立方体...
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
cubes.forEach((cube, index) => {
cube.rotation.x += delta * (index + 1); // 每个立方体不同速度
cube.rotation.y += delta * (index + 1);
});
renderer.render(scene, camera);
}
通过 delta
乘以不同系数,实现多个物体以不同速度运动 2
四、进阶应用技巧
1. 动画速度控制
通过调整 delta
的系数可以灵活控制动画速度:
const speed = 2.0; // 2倍速
cube.rotation.x += delta * speed;
2. 暂停与恢复
// 当页面不可见时暂停时钟
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
clock.stop();
} else {
clock.start();
}
});
这种技术可以优化页面性能,当用户切换标签页时暂停动画 2
3. 定时事件触发
const elapsedTime = clock.getElapsedTime();
if (elapsedTime > 5) {
// 5秒后执行某些操作
}
4. 性能监控
function render() {
requestAnimationFrame(render);
const delta = clock.getDelta();
console.log('帧间隔:', delta * 1000 + 'ms');
console.log('帧率:', 1 / delta);
renderer.render(scene, camera);
}
通过 getDelta()
可以监控实际渲染性能 37
五、常见问题与解决方案
-
动画不流畅
-
原因:计算量过大或浏览器性能限制
-
解决:优化计算逻辑,确保使用
requestAnimationFrame
6
-
-
时间不准确
-
原因:JavaScript 时间精度问题
-
解决:Three.js 的
Clock
内部已优化,优先使用performance.now()
8
-
-
初次调用
getDelta()
返回异常值-
原因:第一次调用时没有基准时间
-
解决:可以忽略第一次返回值,或在循环外先调用一次 7
-
六、与 requestAnimationFrame 的关系
Clock
通常与 requestAnimationFrame
配合使用:
-
requestAnimationFrame
控制渲染节奏 -
Clock
提供精确的时间计算 -
组合使用可以实现帧率无关的平滑动画 37
相比之下,使用 setInterval
会有以下问题:
-
不考虑浏览器状态
-
不与显示器刷新同步
-
可能导致高CPU使用率 3
七、在不同框架中的使用
在 Vue 中使用:
animate() {
requestAnimationFrame(this.animate); // 注意不要加()
// 使用Clock逻辑...
}
注意传入函数名而非立即执行 3
总结
Three.js 的 Clock
是一个强大而简单的时间管理工具,特别适合:
-
3D动画开发
-
游戏循环实现
-
物理模拟
-
需要精确时间控制的交互场景
通过合理使用 getDelta()
和 getElapsedTime()
,开发者可以创建出流畅、帧率无关的动画效果,同时优化应用性能。