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 loop

Step 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 animation

Step 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);