or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

boundaries-constraints.mdcamera-fitting.mdcamera-movement.mdcore-controls.mdevent-system.mdindex.mdinput-configuration.mdstate-management.md
tile.json

tessl/npm-camera-controls

A camera control for three.js, similar to THREE.OrbitControls yet supports smooth transitions and more features

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/camera-controls@3.1.x

To install, run

npx @tessl/cli install tessl/npm-camera-controls@3.1.0

index.mddocs/

Camera Controls

Camera Controls is a modern TypeScript library providing advanced camera control functionality for Three.js applications. It extends the capabilities of THREE.OrbitControls with smooth transitions, animation features, comprehensive interaction handling, and extensive customization options.

Package Information

  • Package Name: camera-controls
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install camera-controls
  • Peer Dependencies: three (>=0.126.1)

Core Imports

import CameraControls from 'camera-controls';
import * as THREE from 'three';

// Required: Install THREE.js before creating controls
CameraControls.install({ THREE });

For CommonJS:

const CameraControls = require('camera-controls');
const THREE = require('three');

CameraControls.install({ THREE });

For tree-shaking with minimal THREE.js subset:

import {
  Vector2, Vector3, Vector4, Quaternion, Matrix4,
  Spherical, Box3, Sphere, Raycaster
} from 'three';
import CameraControls from 'camera-controls';

const subsetOfTHREE = {
  Vector2, Vector3, Vector4, Quaternion, Matrix4,
  Spherical, Box3, Sphere, Raycaster
};

CameraControls.install({ THREE: subsetOfTHREE });

Basic Usage

import * as THREE from 'three';
import CameraControls from 'camera-controls';

// Install THREE.js dependency
CameraControls.install({ THREE });

// Create scene, camera, renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Create camera controls
const cameraControls = new CameraControls(camera, renderer.domElement);

// Animation loop
const clock = new THREE.Clock();
function animate() {
  const delta = clock.getDelta();
  const hasControlsUpdated = cameraControls.update(delta);
  
  // Optional: only render when controls update
  if (hasControlsUpdated) {
    renderer.render(scene, camera);
  }
  
  requestAnimationFrame(animate);
}
animate();

Architecture

Camera Controls is built around several key components:

  • Core Control System: Main CameraControls class extending EventDispatcher for camera manipulation
  • Input Handling: Configurable mouse, touch, and keyboard input processing with customizable action mappings
  • Animation Engine: Smooth transitions and programmable camera movements with Promise-based API
  • Constraint System: Boundary enforcement, collision detection, and movement limits
  • Event System: Comprehensive event dispatching for interaction states and camera updates
  • Utility Functions: Mathematical operations, coordinate transforms, and Three.js integration helpers

Capabilities

Core Controls

Fundamental camera control functionality including construction, initialization, and basic lifecycle management.

class CameraControls extends EventDispatcher {
  constructor(
    camera: THREE.PerspectiveCamera | THREE.OrthographicCamera,
    domElement?: HTMLElement
  );
  
  static install(libs: { THREE: THREESubset }): void;
  static createBoundingSphere(object3d: THREE.Object3D, out?: THREE.Sphere): THREE.Sphere;
  
  connect(domElement: HTMLElement): void;
  dispose(): void;
  update(delta: number): boolean;
}

Core Controls

Camera Movement

Comprehensive camera positioning and movement functionality including rotation, translation, and orientation controls.

// Rotation methods
rotate(azimuthAngle: number, polarAngle: number, enableTransition?: boolean): Promise<void>;
rotateTo(azimuthAngle: number, polarAngle: number, enableTransition?: boolean): Promise<void>;

// Distance and zoom methods  
dolly(distance: number, enableTransition?: boolean): Promise<void>;
dollyTo(distance: number, enableTransition?: boolean): Promise<void>;
zoom(zoomStep: number, enableTransition?: boolean): Promise<void>;
zoomTo(zoom: number, enableTransition?: boolean): Promise<void>;

// Position methods
moveTo(x: number, y: number, z: number, enableTransition?: boolean): Promise<void>;
setPosition(x: number, y: number, z: number, enableTransition?: boolean): Promise<void>;
setTarget(x: number, y: number, z: number, enableTransition?: boolean): Promise<void>;

Camera Movement

Input Configuration

Customizable input handling for mouse, touch, and keyboard interactions with flexible action mapping.

interface MouseButtons {
  left: mouseButtonAction;
  middle: mouseButtonAction;
  right: mouseButtonAction;
  wheel: mouseWheelAction;
}

interface Touches {
  one: singleTouchAction;
  two: multiTouchAction;
  three: multiTouchAction;
}

// Properties
mouseButtons: MouseButtons;
touches: Touches;
interactiveArea: DOMRect | { x: number, y: number, width: number, height: number };

Input Configuration

Boundaries and Constraints

Movement boundaries, collision detection, and camera constraints for controlled navigation.

setBoundary(box3?: THREE.Box3): void;
setViewport(viewportOrX: THREE.Vector4 | number | null, y: number, width: number, height: number): void;

// Properties
boundaryFriction: number;
boundaryEnclosesCamera: boolean;
colliderMeshes: THREE.Object3D[];

Boundaries and Constraints

Camera Fitting

Automatic camera positioning to fit objects, bounding boxes, and spheres with configurable padding.

fitToBox(
  box3OrObject: THREE.Box3 | THREE.Object3D,
  enableTransition: boolean,
  options?: Partial<FitToOptions>
): Promise<void[]>;

fitToSphere(
  sphereOrMesh: THREE.Sphere | THREE.Object3D,
  enableTransition: boolean
): Promise<void[]>;

interface FitToOptions {
  cover: boolean;
  paddingLeft: number;
  paddingRight: number;
  paddingBottom: number;
  paddingTop: number;
}

Camera Fitting

State Management

Camera state persistence, serialization, and restoration functionality.

saveState(): void;
reset(enableTransition?: boolean): Promise<void[]>;
toJSON(): string;
fromJSON(json: string, enableTransition?: boolean): void;

// State accessors
getTarget(out: THREE.Vector3, receiveEndValue?: boolean): THREE.Vector3;
getPosition(out: THREE.Vector3, receiveEndValue?: boolean): THREE.Vector3;
getSpherical(out: THREE.Spherical, receiveEndValue?: boolean): THREE.Spherical;

State Management

Event System

Comprehensive event handling for camera interactions, transitions, and state changes.

interface CameraControlsEventMap {
  update: { type: 'update' };
  wake: { type: 'wake' };
  rest: { type: 'rest' };
  sleep: { type: 'sleep' };
  transitionstart: { type: 'transitionstart' };
  controlstart: { type: 'controlstart' };
  control: { type: 'control' };
  controlend: { type: 'controlend' };
}

// Inherited from EventDispatcher
addEventListener(type: string, listener: Listener): void;
removeEventListener(type: string, listener: Listener): void;
dispatchEvent(event: DispatcherEvent): void;

Event System

Types and Constants

Action Constants

const ACTION = {
  NONE: 0b0,
  ROTATE: 0b1,
  TRUCK: 0b10,
  SCREEN_PAN: 0b100,
  OFFSET: 0b1000,
  DOLLY: 0b10000,
  ZOOM: 0b100000,
  TOUCH_ROTATE: 0b1000000,
  TOUCH_TRUCK: 0b10000000,
  TOUCH_SCREEN_PAN: 0b100000000,
  TOUCH_OFFSET: 0b1000000000,
  TOUCH_DOLLY: 0b10000000000,
  TOUCH_ZOOM: 0b100000000000,
  TOUCH_DOLLY_TRUCK: 0b1000000000000,
  TOUCH_DOLLY_SCREEN_PAN: 0b10000000000000,
  TOUCH_DOLLY_OFFSET: 0b100000000000000,
  TOUCH_DOLLY_ROTATE: 0b1000000000000000,
  TOUCH_ZOOM_TRUCK: 0b10000000000000000,
  TOUCH_ZOOM_OFFSET: 0b100000000000000000,
  TOUCH_ZOOM_SCREEN_PAN: 0b1000000000000000000,
  TOUCH_ZOOM_ROTATE: 0b10000000000000000000,
} as const;

const MOUSE_BUTTON = {
  LEFT: 1,
  RIGHT: 2,
  MIDDLE: 4,
} as const;

const DOLLY_DIRECTION = {
  NONE: 0,
  IN: 1,
  OUT: -1,
} as const;

Core Types

interface THREESubset {
  Vector2: typeof THREE.Vector2;
  Vector3: typeof THREE.Vector3;
  Vector4: typeof THREE.Vector4;
  Quaternion: typeof THREE.Quaternion;
  Matrix4: typeof THREE.Matrix4;
  Spherical: typeof THREE.Spherical;
  Box3: typeof THREE.Box3;
  Sphere: typeof THREE.Sphere;
  Raycaster: typeof THREE.Raycaster;
  [key: string]: any;
}

interface PointerInput {
  pointerId: number;
  clientX: number;
  clientY: number;
  deltaX: number;  
  deltaY: number;
  mouseButton: MOUSE_BUTTON | null;
}

type Ref = { value: number };

type ACTION = number;
type MOUSE_BUTTON = typeof MOUSE_BUTTON[keyof typeof MOUSE_BUTTON];
type DOLLY_DIRECTION = typeof DOLLY_DIRECTION[keyof typeof DOLLY_DIRECTION];