Skip to content

Three.js - Controls

A static scene is interesting, but an interactive one is engaging. Camera controls allow the user to move the camera around your scene using their mouse, trackpad, or touch screen. This is essential for exploring 3D environments and inspecting models.

Like loaders, camera controls are not part of the core Three.js library. You must import them from the three/examples/jsm/controls/ directory. While several types of controls exist, one is used far more than any other for general-purpose applications.

OrbitControls allows the camera to orbit around a target point. It’s intuitive and provides a great user experience for model viewers, e-commerce product displays, and simple scene exploration.

  • Orbit: Click and drag to rotate around the target.
  • Zoom: Scroll with the mouse wheel to zoom in and out.
  • Pan: Right-click and drag (or Ctrl/Cmd + click and drag) to move the camera and its target together.

Integrating OrbitControls is straightforward. You import it, instantiate it with your camera and the renderer’s DOM element, and then update it in your animation loop.

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// Assuming you have your scene, camera, and renderer set up
const canvas = renderer.domElement;
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 1. Instantiate the controls
const controls = new OrbitControls(camera, canvas);
// 2. (Optional but recommended) Enable damping for smooth motion
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// 3. Update in the animation loop
function animate() {
requestAnimationFrame(animate);
// This is required if damping is enabled
controls.update();
renderer.render(scene, camera);
}
animate();

Important: If you set controls.enableDamping = true, you must call controls.update() in every frame of your animation loop. This applies the smoothing effect over time.

OrbitControls has many properties you can configure to tailor the user experience:

  • .target: A Vector3 representing the point the camera orbits around. By default, it’s (0, 0, 0). You can change this to focus on a specific object: controls.target.set(object.position.x, object.position.y, object.position.z);
  • .minDistance / .maxDistance: Constrains how close or far the user can zoom.
  • .minPolarAngle / .maxPolarAngle: Constrains the vertical orbiting angle. For example, controls.maxPolarAngle = Math.PI / 2; would prevent the user from looking at the scene from below.
  • .enablePan / .enableZoom: Booleans to disable panning or zooming if you don’t want them.
  • .autoRotate / .autoRotateSpeed: Set controls.autoRotate = true; for a gentle, continuous rotation, great for product showcases.

While OrbitControls is the most common, other controls are useful for specific scenarios:

ControlDescription & Use Case
TrackballControlsSimilar to OrbitControls but without a fixed ‘up’ direction, allowing for free-form tumbling. Can feel less intuitive for beginners but offers more rotational freedom.
FlyControlsSimulates flying. The camera moves forward continuously, and the user steers with the mouse. Good for flight simulators or large-scale world exploration.
PointerLockControlsImplements first-person shooter (FPS) style controls. It locks the mouse cursor and allows the user to look around by moving the mouse and move with keyboard keys (W, A, S, D). Ideal for immersive, first-person experiences.
  • Start with OrbitControls: Unless you have a specific need for another type, OrbitControls provides the best general-purpose experience.
  • Always enable damping: The smooth start and stop motion from enableDamping feels much more polished and professional.
  • Consider constraints: Don’t let your users get lost. Set reasonable min/max distances and angles to keep the camera focused on the important parts of your scene.
  • Test on different devices: Ensure your control scheme works well on both mouse and touch-based devices.