Animate Three.js Camera Along a Path
This article explains how to smoothly animate a camera’s position along a predefined 3D path in Three.js. You will learn how to define a curve using mathematical splines, update the camera’s position along this path inside the render loop, and orient the camera so it dynamically looks ahead as it moves.
To animate a camera along a path in Three.js, you need to define a geometric curve, track the movement progress, and update both the camera’s position and its target orientation on every frame.
Step 1: Define the Path
The most common way to create a smooth path in Three.js is by using
THREE.CatmullRomCurve3. This class takes an array of 3D
vectors (THREE.Vector3) and generates a smooth spline curve
through them.
// Define the control points for the path
const pathPoints = [
new THREE.Vector3(-20, 5, 20),
new THREE.Vector3(-10, 15, 10),
new THREE.Vector3(0, 5, -10),
new THREE.Vector3(10, 12, -20),
new THREE.Vector3(20, 5, 0)
];
// Create a closed or open smooth 3D curve
const cameraPath = new THREE.CatmullRomCurve3(pathPoints, true); // Set 'true' to close the loopStep 2: Track the Animation Progress
To move the camera along the curve, track a progress variable (often
called t) that ranges from 0 (the start of the
path) to 1 (the end of the path).
let progress = 0;
const speed = 0.001; // Adjust this value to speed up or slow down the animationStep 3: Update the Camera in the Animation Loop
Inside your requestAnimationFrame loop, increment the
progress variable. Use the .getPointAt() method of the
curve to retrieve the 3D coordinates at that specific progress point,
then copy those coordinates to the camera’s position.
To make the movement look natural, the camera should face the
direction it is traveling. Retrieve a point slightly ahead on the curve
(e.g., progress + 0.01) and use the
camera.lookAt() method to point the camera toward it.
function animate() {
requestAnimationFrame(animate);
// 1. Increment progress and loop it back to 0 when it exceeds 1
progress += speed;
if (progress > 1) {
progress = 0;
}
// 2. Get the current position on the curve
const cameraPosition = cameraPath.getPointAt(progress);
camera.position.copy(cameraPosition);
// 3. Make the camera look slightly ahead on the curve
const lookAtTarget = cameraPath.getPointAt((progress + 0.01) % 1);
camera.lookAt(lookAtTarget);
// 4. Render the scene
renderer.render(scene, camera);
}
// Start the animation loop
animate();Optional: Visualizing the Path
While developing, it is helpful to visualize the camera path in the
3D scene. You can draw a line along the curve using
THREE.Line:
const points = cameraPath.getPoints(50); // Get 50 points along the curve
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
const pathVisualization = new THREE.Line(geometry, material);
scene.add(pathVisualization);