Skip to content

Camera

The camera manages the view matrix on the Context3D and supports orbit, pan, zoom, and lookAt operations. Property changes like position, target, and fov are batched via microtasks so multiple changes in the same synchronous block result in a single matrix update. Built-in mouse interactions (scroll to zoom, drag to orbit, Shift+drag to pan) can be enabled with a single flag or fine-tuned per interaction.

NOTE

For the full API, see the 3D API Reference.

Demo

Both demos pair the moving camera with lightMode: 'camera'. See Light Modes for why a world-fixed light looks frozen when the camera moves and the geometry does not.

Creation

ts
import {
    createCamera,
} from '@ripl/3d';

const camera = createCamera(context, {
    position: [0, 2, 5],
    target: [0, 0, 0],
    fov: 60,
    near: 0.1,
    far: 1000,
    projection: 'perspective',
});

Options

  • position (Vector3): camera position in world space (default [0, 0, 5])
  • target (Vector3): point the camera looks at (default [0, 0, 0])
  • up (Vector3): up direction (default [0, 1, 0])
  • fov: field of view in degrees (default 60)
  • near: near clipping plane (default 0.1)
  • far: far clipping plane (default 1000)
  • projection: 'perspective' or 'orthographic' (default 'perspective')

Methods

orbit(deltaTheta, deltaPhi)

Orbits the camera around the target point.

ts
camera.orbit(0.1, 0.05);

pan(deltaX, deltaY)

Pans the camera (shifts both position and target).

ts
camera.pan(1, 0);

zoom(delta)

Moves the camera along the eye-to-target vector. A positive delta moves toward the target (zooms in), a negative one retreats (zooms out). The move is clamped so the target never crosses the near plane.

ts
camera.zoom(2);

lookAt(target)

Points the camera at a new target.

ts
camera.lookAt([5, 5, 5]);

flush()

Immediately applies pending changes (bypasses microtask batching).

ts
camera.flush();

Reactive Updates

Setting properties like camera.position, camera.target, or camera.fov schedules a microtask to update the context. Multiple changes in the same synchronous block are batched into a single update.

ts
camera.position = [1, 2, 3];
camera.target = [0, 0, 0];
camera.fov = 90;
// All three changes are applied in a single microtask

Interactions

The camera supports built-in mouse interactions for zoom, pivot (orbit), and pan. Enable them via the interactions option:

ts
const camera = createCamera(context, {
    interactions: true, // enable all interactions with default sensitivity
});

For granular control, pass an object:

ts
const camera = createCamera(context, {
    interactions: {
        zoom: {
            enabled: true,
            sensitivity: 5,
        },
        pivot: true,
        pan: true,
    },
});

Interaction Options

Pass interactions: true to enable all interactions with default sensitivity, or pass an object to configure each individually. Each interaction (zoom, pivot, pan) accepts boolean or { enabled, sensitivity }.

Controls

  • Orbit / Pivot: left-click + drag, or one-finger drag
  • Pan: middle-click + drag, Shift + left-click + drag, or two-finger drag
  • Zoom: scroll up to zoom in and down to zoom out, or spread two fingers to zoom in

Zoom matches the 2D Navigator: the same gesture moves both the same way, at the same rate, and a scroll back up returns you exactly where you started.

dispose()

Removes all interaction event listeners.

ts
camera.dispose();