CameraOrbitControl

← prev index next →

Turns the camera into an interactive turntable — orbit, pan, zoom, and auto-fit around a pivot — so you frame a scene without hand-placing the camera.

Remarks

This is the camera-control companion to the AbstractCamera family: rather than a camera itself, it takes over aiming one. Presence of a camera-orbit-control alongside the camera opts the scene into interactive orbit / pan / zoom plus an optional auto-fit that frames the scene for you — the easy way to get a good shot, since a bare camera has to be positioned and rotated by hand.

Key attributes. The pose is azimuth (turn around the pivot), elevation (height above it), and radius (distance from it) — all animatable, so an animation can sweep the camera on a turntable. fit-targets / fit-margin turn on the auto-fit that keeps the subject framed, and orient-toward-pivot keeps the camera aimed at the pivot as it moves. Reflection and animation are handled by the shared SkenraAnimatable machinery, and orbit-pose writes drive the camera through the underlying Orbit node; the fit-backed properties re-arm the auto-fit at runtime.

Lifecycle: The browser upgrade path constructs the element with NO arguments, so it must be valid uninitialized — it has no camera until attachCamera binds one (the declarative scene bootstrap or an imperative caller). The canonical Orbit node is created lazily on connect (so an animation always has a real animatable to target) and survives camera detach/re-attach, preserving its identity and pose subscription.

Animation: an animation on this control is redirected onto the canonical Orbit (see _resolveAnimationEffectTarget), the true animatable owning azimuth / elevation / radius. Fit-backed properties (fitTargets, fitMargin, freezeOnFit, pivot, panX, panY, zoomFactor) are live and scriptable but NOT animatable.

Interactive input composes with animation. Orbit drag, zoom, and inertia contribute a persistent additive offset through the same effect stack the animation uses (see CameraOrbitUserOffset), so you can grab and orbit the camera while a turntable animation is playing and the gesture simply shifts the framing — the animation keeps running underneath without a frame-to-frame fight. Because the gesture is a separate effect layer, a drag does NOT rewrite the authored azimuth / elevation / radius attributes; the authored pose stays the base the animation and the offset compose onto. resetView and setViewDirection clear the accumulated offset.

This class owns the orbit setup/lifecycle, pivot management, zoom/radius state, reset state, pan-direction vector extraction, sensitivity configs, and min/max clamping. It owns NO DOM event listeners and has no knowledge of pointer/wheel/touch events.

Constructor

constructor(config?: { camera?: AbstractCamera; orbitSensitivity?: number; panSensitivity?: number; zoomSensitivity?: number; minZoom?: number; maxZoom?: number; orientationAxis?: '-x' | '+x' | '-y' | '+y' | '-z' | '+z'; pivotNode?: SceneNode; orbitNode?: Orbit })

Properties

Config Properties

PropertyTypeDefaultDescriptionDeclared by
cameraconfig-only AbstractCamera A camera to attach to at construction (imperative sugar for CameraOrbitControl.attachCamera). CameraOrbitControlInit
orbitSensitivity number 0.005 Orbit drag sensitivity (radians per pixel). Consumed by the viewport input handler. CameraOrbitControl
panSensitivity number 0.01 Pan drag sensitivity. CameraOrbitControl
zoomSensitivity number 0.005 Zoom drag sensitivity (scale factor per pixel). CameraOrbitControl
minZoom number 1 Minimum zoom level (orthographic height or perspective orbit distance). CameraOrbitControl
maxZoom number 500 Maximum zoom level (orthographic height or perspective orbit distance). CameraOrbitControl
orientationAxis '-x' | '+x' | '-y' | '+y' | '-z' | '+z' "-z" Which camera axis points at the pivot when orienting. CameraOrbitControl
pivotNode SceneNode The SceneNode the camera currently orbits around: an explicit pivot CameraOrbitControl
orbitNoderead-only Orbit Get the Orbit attached to the camera. CameraOrbitControl

Other Properties

PropertyTypeDefaultDescriptionDeclared by
azimuthanimatable number 0 Initial/horizontal orbit angle (radians); animatable. CameraOrbitControl
elevationanimatable number 0 Initial/vertical orbit angle (radians); animatable. CameraOrbitControl
radiusanimatable number 10 Orbit radius (distance from pivot); animatable. CameraOrbitControl
orientTowardPivot boolean false When true, the camera faces the pivot. CameraOrbitControl
fitTargets "none" | "auto" | readonly string[] "none" Nodes whose bounds drive an auto-fit: 'auto', 'none', or id list. CameraOrbitControl
fitMargin number 0 Padding fraction applied around fitted bounds. CameraOrbitControl
freezeOnFit boolean true Stop the fit observer after the first frame with real bounds. CameraOrbitControl
pivot string | null The point the camera orbits around, as an element id reference (#id), CameraOrbitControl
panX string | null Post-fit horizontal pan (CSS length string), or null. CameraOrbitControl
panY string | null Post-fit vertical pan (CSS length string), or null. CameraOrbitControl
zoomFactor number 1 Post-fit zoom multiplier (1 = no change). CameraOrbitControl
enabled boolean true Whether camera controls are enabled. CameraOrbitControl
enableInertia boolean true Whether inertia/momentum is enabled after pointer release. CameraOrbitControl
inertiaFactor number 0.05 Decay factor per frame for inertia. Higher values = more damping (stops faster). CameraOrbitControl
inertiaThreshold number 0.0001 Velocity magnitude below which inertia stops. CameraOrbitControl
hasActiveInertiaread-only boolean Whether there is currently active inertia motion. CameraOrbitControl
zoomLevelread-only number Get the current zoom level. CameraOrbitControl
orbitConstraintread-only OrbitConstraint | null Get the OrbitConstraint attached to the camera. CameraOrbitControl
sceneread-only any Gets the Scene this animatable belongs to, if any. SkenraAnimatable
animationsread-only SkenraAnimation[] Public getter for the animations affecting this target. SkenraAnimatable

Methods

MethodDescriptionDeclared by
attachCamera(camera: AbstractCamera, config?: CameraOrbitControlOptions): this Binds this control to a live camera and installs the orbit runtime CameraOrbitControl
setCamera(camera: AbstractCamera): void Sets a new camera for this controller. CameraOrbitControl
dispose(): void Terminal teardown. Detaches the camera runtime, then permanently drops CameraOrbitControl
update(): void Per-frame update entrypoint. CameraOrbitControl
orbit(deltaAzimuth: number, deltaElevation: number): void Orbit the camera by adjusting azimuth and elevation. CameraOrbitControl
pan(deltaX: number, deltaY: number): void Pan the camera by moving the pivot point in screen-aligned directions. CameraOrbitControl
zoom(factor: number): void Zoom the camera by a given factor. CameraOrbitControl
handleWheelZoom(deltaY: number): void Handle mouse wheel zoom. CameraOrbitControl
startOrbitInertia(velocityAzimuth: number, velocityElevation: number): void Start orbit inertia with the given angular velocity. CameraOrbitControl
startPanInertia(velocityX: number, velocityY: number): void Start pan inertia with the given pixel velocity. CameraOrbitControl
stopInertia(): void Immediately stop any active inertia. CameraOrbitControl
updateInertia(): void Update inertia state for the current frame. CameraOrbitControl
setViewDirection(direction: 'front' | 'back' | 'left' | 'right' | 'top' | 'bottom'): void Set the camera to a predefined view direction. CameraOrbitControl
resetView(): void Reset the camera to its initial state. CameraOrbitControl
fitToNode(node: SceneNode): void Fits the camera to the given node's bounding box. CameraOrbitControl
setFitTarget(target: SceneNode | ReadonlyArray<SceneNode> | 'auto' | 'none', options?: SetFitTargetOptions): void Schedules an auto-fit of the camera to one or more targets, deferred CameraOrbitControl
getConfig(): CameraOrbitControlConfig Returns the resolved configuration with defaults applied. CameraOrbitControl
animate(firstArg: TypedKeyframe<this>[] | TypedPropertyIndexedKeyframes<this> | Record<string, any> | globalThis.Keyframe[] | globalThis.PropertyIndexedKeyframes | null, secondArg?: number | KeyframeAnimationOptions | globalThis.KeyframeAnimationOptions): SkenraAnimation & Animation Creates a new SkenraAnimation for this target per Web Animations API. SkenraAnimatable
removeAnimation(animation: SkenraAnimation): boolean Removes a specific animation from this object. SkenraAnimatable
constrain(type: K, config: ConstraintConfigMap[K]): ConstraintReturnMap[K] Creates a constraint on this Animatable using a fluent API. SkenraAnimatable

Example

import { CameraOrbitControl } from '/js/skenra/camera/camera-orbit-control.js';

const controller = new CameraOrbitControl({ camera: camera,
    panSensitivity: 0.02
});
controller.radius = 15;   // camera-to-pivot distance

controller.orbit(Math.PI / 4, 0);   // Orbit 45° horizontally
controller.pan(10, 5);              // Pan 10px right, 5px up
controller.zoom(0.5);              // Zoom in by 50%
controller.resetView();           // Reset to initial state
controller.dispose();