动画是让您的3D 场景变得生动的关键。它们可以通过用户交互、滚动或时间触发,并应用于3D 对象、灯光和相机。
掌握动画是一种创建沉浸式体验的关键技能。您掌握的技巧越多,就越能表达您的创造力。
注意: 3D 模型动画的内容已在模型章节中介绍。
Lerp
Lerp 是一种数学函数,可以在两个值之间进行插值。它非常有用于在两个点之间动画化一个值。
const value = THREE.MathUtils.lerp(start, end, t);
第一个参数是起始值,第二个参数是结束值,第三个参数是介于 0 和 1 之间的插值因子。
插值因子越接近0,动画就越慢。插值因子越接近1,动画达到结束或目标值的速度就越快。
让我们在 starter pack 的 AnimatedBox
组件上试验一下。
该组件有一个 boxPositions
数组,包含盒子在不同时间点的位置。让我们添加一个 useFrame
钩子以基于时间更新盒子的位置:
import { RoundedBox } from "@react-three/drei"; import { useRef } from "react"; export const AnimatedBox = ({ boxPositions, ...props }) => { const box = useRef(); useFrame(({ clock }) => { const seconds = parseInt(clock.getElapsedTime()); const targetPosition = boxPositions[seconds % boxPositions.length]; box.current.position.x = targetPosition.x; box.current.position.y = targetPosition.y; box.current.position.z = targetPosition.z; }); // ... };
此时我们的盒子并未动画化。它是从一个位置跳到另一个位置。让我们使用 lerp
函数为它添加动画:
import * as THREE from "three"; // ... export const AnimatedBox = ({ boxPositions, ...props }) => { const box = useRef(); useFrame(({ clock }) => { const seconds = parseInt(clock.getElapsedTime()); const targetPosition = boxPositions[seconds % boxPositions.length]; box.current.position.x = THREE.MathUtils.lerp( box.current.position.x, targetPosition.x, 0.05 ); box.current.position.y = THREE.MathUtils.lerp( box.current.position.y, targetPosition.y, 0.05 ); box.current.position.z = THREE.MathUtils.lerp( box.current.position.z, targetPosition.z, 0.05 ); }); // ... };
现在盒子有了动画效果。它可以平滑地从一个位置移动到另一个位置。
Vector3
类有一个 lerp
方法,可以替代使用 THREE.MathUtils.lerp
函数:
// box.current.position.x = THREE.MathUtils.lerp( // box.current.position.x, // targetPosition.x, // 0.05 // ); // box.current.position.y = THREE.MathUtils.lerp( // box.current.position.y, // targetPosition.y, // 0.05 // ); // box.current.position.z = THREE.MathUtils.lerp( // box.current.position.z, // targetPosition.z, // 0.05 // ); box.current.position.lerp(targetPosition, 0.05);
这样可以减少很多行代码,而且效果相同!
请不要犹豫,尽情玩弄这些时间,尝试对其他属性(如 rotation
或 scale
)进行 lerp 操作,以尝试不同的效果。
Float
Float 是 Drei 库 中的一个包装组件,用于简单地给对象一种漂浮的印象。
它包含以下属性:
speed
: 动画速度,默认为 1rotationIntensity
: XYZ 轴旋转强度,默认为 1floatIntensity
: 上/下漂浮强度,与 floatingRange 一起作为乘数使用,默认为 1floatingRange
: 对象在 y 轴方向漂浮的范围,默认为 [-0.1, 0.1]
让我们在 Experience.jsx
中让我们的 Duck 漂浮起来:
React Three Fiber: The Ultimate Guide to 3D Web Development
✨ You have reached the end of the preview ✨
Go to the next level with Three.js and React Three Fiber!
Get full access to this lesson and the complete course when you enroll:
- 🔓 Full lesson videos with no limits
- 💻 Access to the final source code
- 🎓 Course progress tracking & completion
- 💬 Invite to our private Discord community
One-time payment. Lifetime updates included.