Now that we've got our 3D scene set up and some objects within it, the next exciting step is to bring them to life! Animation is what transforms static renders into dynamic and engaging experiences. In Three.js, animating an object primarily involves changing its properties over time. The most common properties we'll animate are its position, rotation, and scale.
The core of animation in Three.js, and indeed in most game engines or 3D frameworks, relies on a game loop or render loop. This loop continuously updates the scene and redraws it on the screen. For each frame of the animation, we'll calculate new values for our object's properties and update them before rendering. Three.js provides the requestAnimationFrame API, which is the standard way to handle this loop in web browsers. It's efficient because it pauses animation when the tab is inactive, saving resources.
function animate() {
requestAnimationFrame(animate);
// Update object properties here
renderer.render(scene, camera);
}
animate();Let's break down how to animate each of these fundamental properties: position, rotation, and scale.
Animating Position
To move an object, we modify its position property, which is a Vector3 object. This object has x, y, and z components. By incrementally changing these values within our animation loop, we can make the object move along any axis or a combination of axes.
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function animate() {
requestAnimationFrame(animate);
// Move the cube along the X-axis
cube.position.x += 0.01;
renderer.render(scene, camera);
}In this example, the cube's x position increases by 0.01 in each frame, causing it to move to the right. You can achieve more complex movements by animating y and z as well, or by introducing mathematical functions to control the speed and direction of movement.
Animating Rotation
Rotation is handled by the rotation property, which is a Euler object. It also has x, y, and z components, representing rotations around the respective axes in radians. You can increment these values to make your object spin.
function animate() {
requestAnimationFrame(animate);
// Rotate the cube around the Y-axis
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}Here, cube.rotation.y += 0.01 makes the cube spin around its vertical axis. Remember that rotations are cumulative. If you want to reset an object's rotation, you can set cube.rotation.set(0, 0, 0).
Animating Scale
The scale property, a Vector3, controls the size of an object. Each component (x, y, z) determines how much the object is stretched or shrunk along that axis. Animating scale can create pulsing or growing effects.
function animate() {
requestAnimationFrame(animate);
// Scale the cube up and down
cube.scale.x += 0.005;
cube.scale.y += 0.005;
cube.scale.z += 0.005;
// Optional: Reset scale to create a pulsing effect
if (cube.scale.x > 1.2) {
cube.scale.set(1, 1, 1);
}
renderer.render(scene, camera);
}This code snippet makes the cube grow uniformly. The optional if condition demonstrates how to reset the scale, which, when combined with increasing scale, can create a pulsating effect. You can also scale objects non-uniformly by changing individual x, y, or z components.
Combining Animations
The real magic happens when you combine these animations. You can make an object move, rotate, and scale simultaneously to create complex and dynamic behaviors. The animation loop is where all these property updates occur before the scene is rendered.
function animate() {
requestAnimationFrame(animate);
cube.position.x += 0.01;
cube.rotation.y += 0.01;
cube.scale.z = Math.sin(Date.now() * 0.001) * 0.5 + 1; // Pulsating scale
renderer.render(scene, camera);
}In this final example, the cube moves to the right, spins, and its scale along the Z-axis pulses using a sine wave for a smooth, organic effect. The Date.now() * 0.001 part controls the speed of the pulsation. Experimenting with different mathematical functions and combinations of property changes will unlock a vast array of animation possibilities for your 3D web experiences.