Three.js 动画与交互开发实战指南

一、动画系统核心原理

1.1 动画循环机制

Three.js的动画系统基于浏览器渲染循环构建,通过requestAnimationFrame实现高性能动画。该API与浏览器刷新率同步(通常60fps),确保动画流畅性。

  1. function animate() {
  2. requestAnimationFrame(animate);
  3. // 更新逻辑
  4. renderer.render(scene, camera);
  5. }
  6. animate();

关键优化点

  • 避免在循环中创建新对象
  • 使用增量计算替代绝对赋值
  • 合理控制帧率(可通过performance.now()实现)

1.2 基础变换动画

物体变换包含位置(position)、旋转(rotation)、缩放(scale)三大属性,支持逐帧修改实现动态效果:

  1. function updateScene() {
  2. // 复合旋转(欧拉角)
  3. mesh.rotation.x += 0.005;
  4. mesh.rotation.y += 0.01;
  5. // 正弦波位置动画
  6. const time = Date.now() * 0.001;
  7. mesh.position.y = Math.sin(time) * 2;
  8. // 呼吸效果缩放
  9. mesh.scale.set(
  10. 1 + Math.sin(time * 0.5) * 0.3,
  11. 1 + Math.sin(time * 0.5 + 1) * 0.3,
  12. 1 + Math.sin(time * 0.5 + 2) * 0.3
  13. );
  14. }

进阶技巧

  • 使用四元数(Quaternion)避免万向节死锁
  • 矩阵变换(Matrix4)实现复杂组合变换
  • 顶点着色器实现GPU加速动画

二、专业动画解决方案

2.1 补间动画系统

补间动画通过定义起始/结束状态自动生成中间帧,主流实现方案包括:

TWEEN.js 基础用法

  1. import * as TWEEN from 'three/addons/libs/tween.module.js';
  2. const tween = new TWEEN.Tween(mesh.position)
  3. .to({ x: 5, y: 0, z: 3 }, 2000)
  4. .easing(TWEEN.Easing.Elastic.Out)
  5. .onUpdate(() => {
  6. // 实时更新回调
  7. })
  8. .start();
  9. // 在动画循环中更新
  10. function animate() {
  11. requestAnimationFrame(animate);
  12. TWEEN.update();
  13. renderer.render(scene, camera);
  14. }

GSAP 高级特性

GSAP提供更丰富的动画控制:

  1. gsap.to(mesh.scale, {
  2. x: 1.5,
  3. y: 1.5,
  4. duration: 2,
  5. repeat: -1,
  6. yoyo: true,
  7. ease: "power2.inOut"
  8. });

方案对比
| 特性 | TWEEN.js | GSAP |
|——————-|————————|————————|
| 体积 | 轻量级(5KB) | 完整版(120KB) |
| 缓动函数 | 基础集合 | 30+专业缓动 |
| 序列动画 | 需手动实现 | 内置时间轴 |
| 插件生态 | 有限 | 丰富(物理动画等)|

2.2 骨骼动画系统

对于角色动画,Three.js支持GLTF格式的骨骼动画:

  1. const mixer = new THREE.AnimationMixer(model);
  2. const action = mixer.clipAction(gltf.animations[0]);
  3. action.play();
  4. function animate() {
  5. const delta = clock.getDelta();
  6. mixer.update(delta);
  7. renderer.render(scene, camera);
  8. }

性能优化

  • 使用动画分层(AnimationLayers)
  • 关键帧压缩
  • 蒙皮矩阵批量处理

三、交互系统开发

3.1 鼠标交互体系

射线投射检测

  1. const raycaster = new THREE.Raycaster();
  2. const mouse = new THREE.Vector2();
  3. window.addEventListener('mousemove', (event) => {
  4. mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  5. mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  6. });
  7. function checkIntersection() {
  8. raycaster.setFromCamera(mouse, camera);
  9. const intersects = raycaster.intersectObjects(scene.children);
  10. if (intersects.length > 0) {
  11. const obj = intersects[0].object;
  12. obj.material.emissive.setHex(0x666666);
  13. // 触发点击事件等
  14. }
  15. }

高级交互模式

  • 拖拽控制:结合TransformControls
  • 悬停提示:使用Sprite或CSS2DRenderer
  • 选择框:实现矩形区域选择

3.2 键盘与游戏手柄

键盘事件处理

  1. const keyMap = {};
  2. window.addEventListener('keydown', (e) => { keyMap[e.key] = true; });
  3. window.addEventListener('keyup', (e) => { keyMap[e.key] = false; });
  4. function updateControls() {
  5. if (keyMap['w']) mesh.translateZ(0.1);
  6. if (keyMap['s']) mesh.translateZ(-0.1);
  7. if (keyMap['a']) mesh.translateX(-0.1);
  8. if (keyMap['d']) mesh.translateX(0.1);
  9. }

游戏手柄支持

  1. const gamepads = {};
  2. window.addEventListener("gamepadconnected", (e) => {
  3. gamepads[e.gamepad.index] = e.gamepad;
  4. });
  5. function handleGamepad() {
  6. const gamepad = gamepads[0];
  7. if (gamepad) {
  8. mesh.position.x += gamepad.axes[0] * 0.1;
  9. mesh.position.z += gamepad.axes[1] * 0.1;
  10. }
  11. }

3.3 物理交互集成

结合某物理引擎实现真实碰撞:

  1. // 初始化物理世界
  2. const world = new CANNON.World({
  3. gravity: new CANNON.Vec3(0, -9.82, 0)
  4. });
  5. // 创建物理刚体
  6. const shape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));
  7. const body = new CANNON.Body({ mass: 1, shape });
  8. world.addBody(body);
  9. // 同步到Three.js
  10. function syncPhysics() {
  11. mesh.position.copy(body.position);
  12. mesh.quaternion.copy(body.quaternion);
  13. }

四、性能优化策略

  1. 动画批处理:合并相似物体的更新逻辑
  2. 层级裁剪:使用frustumCulling自动剔除不可见物体
  3. 工作线程:将复杂计算移至Web Worker
  4. LOD系统:根据距离动态调整模型细节
  5. 实例化渲染:对重复物体使用InstancedMesh

五、典型应用场景

  1. 产品3D展示:结合动画说明和交互热点
  2. 数据可视化:动态图表与用户过滤交互
  3. 虚拟展厅:第一人称控制与物品交互
  4. 游戏原型:角色控制与物理反馈系统

通过系统掌握这些技术,开发者可以构建出从简单演示到复杂交互应用的全方位3D解决方案。建议结合实际项目需求,逐步深入各个模块的实现细节。