Skip to main content

OrbitControls

OrbitControls adds pointer-driven orbiting, wheel zoom, optional automatic rotation, and configurable camera bounds to an HTML canvas. The controls maintain a camera position around a target without depending on a specific renderer, scene graph, or GPU backend.

Usage

import {OrbitControls} from '@luma.gl/engine';
import {Matrix4} from '@math.gl/core';

const canvas = document.querySelector<HTMLCanvasElement>('#canvas')!;
const controls = new OrbitControls(canvas, {
target: [0, 1, 0],
distance: 8,
minDistance: 2,
maxDistance: 24,
pitch: 0.35,
autoRotate: true,
autoRotateSpeed: 0.2
});
const viewMatrix = new Matrix4();

function render(timeMilliseconds: number): void {
controls.update(timeMilliseconds);

viewMatrix.lookAt({
eye: controls.getEyePosition(),
center: controls.props.target,
up: [0, 1, 0]
});

// Use viewMatrix to draw the current animation frame.
requestAnimationFrame(render);
}

requestAnimationFrame(render);

Call controls.destroy() when the canvas or its owning application is removed.

Types

OrbitPosition

type OrbitPosition = [number, number, number];

A three-component world-space position. OrbitControls copies configured targets, so mutating the original target array does not move the orbit center.

OrbitControlsProps

type OrbitControlsProps = {
target?: Readonly<OrbitPosition>;
distance?: number;
yaw?: number;
pitch?: number;
minDistance?: number;
maxDistance?: number;
minPitch?: number;
maxPitch?: number;
rotateSpeed?: number;
pitchSpeed?: number;
zoomSpeed?: number;
autoRotate?: boolean;
autoRotateSpeed?: number;
onInteractionStart?: () => void;
};
PropertyDefaultDescription
target[0, 0, 0]World-space point around which the camera rotates.
distance10Initial distance from the orbit target, in world-space units.
yaw0Initial horizontal orbit angle in radians.
pitch0.25Initial vertical orbit angle in radians.
minDistance1Minimum distance from the target.
maxDistance100Maximum distance from the target.
minPitch-Math.PI / 2 + 0.01Lowest allowed pitch angle in radians.
maxPitchMath.PI / 2 - 0.01Highest allowed pitch angle in radians.
rotateSpeed0.006Horizontal rotation applied per CSS pixel of pointer movement, in radians.
pitchSpeedrotateSpeedOptional vertical rotation applied per CSS pixel. Negative values invert the vertical drag direction.
zoomSpeed0.001Exponential wheel-zoom sensitivity.
autoRotatefalseWhether update() automatically advances the horizontal angle.
autoRotateSpeed0.1Automatic horizontal rotation speed in radians per second.
onInteractionStartundefinedOptional callback invoked when a primary-button drag or wheel interaction begins.

Properties

canvas: HTMLCanvasElement

The canvas receiving pointer and wheel events.

props

The resolved orbit configuration. Defaults are filled in when controls are created. Read props.target when constructing a camera view matrix; call setProps() to update configuration and apply new camera values consistently.

yaw: number

Current horizontal orbit angle in radians. Applications can read or adjust this value directly between frames.

pitch: number

Current vertical orbit angle in radians. Pointer interaction and setProps() clamp this value between minPitch and maxPitch.

distance: number

Current world-space distance from the target. Wheel interaction and setProps() clamp this value between minDistance and maxDistance.

Methods

constructor(canvas: HTMLCanvasElement, props?: OrbitControlsProps)

Creates controls for canvas, attaches pointer and wheel listeners, clamps the initial pitch and distance, and sets the canvas cursor and touch-action style for orbit gestures.

canvas must be a real HTML canvas or an equivalent object implementing DOM pointer-event methods. An OffscreenCanvas does not provide the necessary interaction APIs.

update(timeMilliseconds: number): void

Advances automatic rotation using an absolute animation-frame timestamp in milliseconds. Call once per frame before reading getEyePosition().

  • The first call records the initial timestamp without changing the angle.
  • Automatic rotation is paused while the primary pointer is dragging.
  • Rotation resumes from the manually adjusted angle after the pointer is released.
  • Elapsed time is clamped to 100 milliseconds to avoid large camera jumps after an inactive tab or stalled frame.
  • Backward timestamps do not reverse the orbit.
function onAnimationFrame(timeMilliseconds: number): void {
controls.update(timeMilliseconds);
const cameraPosition = controls.getEyePosition();

drawFrame(cameraPosition);
}

getEyePosition(): OrbitPosition

Returns the current world-space camera position computed from target, yaw, pitch, and distance.

At yaw: 0 and pitch: 0, the camera is positioned on the positive Z side of its target. Positive pitch moves the camera upward.

setProps(props: OrbitControlsProps): void

Updates the orbit configuration without replacing the controls or reattaching event listeners.

Specified camera values are applied immediately. If pitch or distance limits change, existing values are clamped to the new limits. An updated target is copied rather than retained by reference.

controls.setProps({
target: sceneBounds.center,
distance: sceneBounds.radius * 2,
minDistance: sceneBounds.radius * 0.25,
maxDistance: sceneBounds.radius * 8
});

Changing yaw, pitch, or distance through setProps() also updates the configured camera pose used by reset().

setAutoRotate(autoRotate: boolean): void

Enables or disables automatic rotation without resetting the current angle.

controls.setAutoRotate(false);

reset(): void

Restores the configured yaw, pitch, and distance. The restored pitch and distance respect the current configured bounds.

destroy(): void

Removes all pointer and wheel listeners, releases active pointer capture, and restores the canvas cursor and touch-action styles that existed before construction.

Interaction behavior

  • Drag with the primary mouse button or an equivalent touch/pen pointer to orbit the target.
  • Scroll the wheel to zoom. Wheel deltas are bounded before applying exponential zoom so large trackpad or mouse events cannot produce an excessive distance jump.
  • Pointer capture keeps a drag associated with its original pointer even when the pointer moves outside the canvas.
  • pointercancel ends an active drag and releases pointer capture.
  • The controls compute camera coordinates only; rendering, camera projection, matrix updates, and redraw scheduling remain the application's responsibility.
  • @luma.gl/experimental continues to re-export OrbitControls for compatibility, but new applications should import the class and its types from @luma.gl/engine.