yomotsu / Camera Controls
Programming Languages
Projects that are alternatives of or similar to Camera Controls
camera-controls
A camera control for three.js, similar to THREE.OrbitControls yet supports smooth transitions and more features.
Examples
camera move | default user input (Configurable) |
---|---|
Orbit rotation | left mouse drag / touch: one-finger move |
Dolly | middle mouse drag, or mousewheel / touch: two-finger pinch-in or out |
Truck (Pan) | right mouse drag / touch: two-finger move or three-finger move |
- basic
- fit-and-padding
- fit-to-bounding-sphere
- boundary
- focal offset
viewport
within the canvas- z-up camera
- orthographic
- user input config
- combined gestures
- keyboard events
- changing-cursor
- collision
- first-person
- third-person (with meshwalk)
- camera shake effect
- rotate with duration and easing (with tween.js)
- path animation (with tween.js)
- dragging outside the iframe
Usage
import * as THREE from 'three';
import CameraControls from 'camera-controls';
CameraControls.install( { THREE: THREE } );
// snip ( init three scene... )
const clock = new THREE.Clock();
const camera = new THREE.PerspectiveCamera( 60, width / height, 0.01, 1000 );
const cameraControls = new CameraControls( camera, renderer.domElement );
( function anim () {
// snip
const delta = clock.getDelta();
const hasControlsUpdated = cameraControls.update( delta );
requestAnimationFrame( anim );
// you can skip this condition to render though
if ( hasControlsUpdated ) {
renderer.render( scene, camera );
}
} )();
Important!
You must install Three.js before using camera-controls. Not doing so will lead to runtime errors (undefined references to THREE).
Before creating a new CameraControls instance, call:
CameraControls.install( { THREE: THREE } );
You can then proceed to use CameraControls.
Constructor
CameraControls( camera, domElement )
-
camera
is aTHREE.PerspectiveCamera
orTHREE.OrthographicCamera
to be controlled. -
domElement
is aHTMLElement
for draggable area.
Terms
Orbit rotations
CameraControls uses Spherical Coordinates for orbit rotations.
If your camera is Y-up, Azimuthal angle will be the angle for y-axis rotation and Polar angle will be the angle for vertical position.
Dolly vs Zoom
- A Zoom involves changing the lens focal length. In three.js, zooming is actually changing the camera FOV, and the camera is stationary (doesn't move).
- A Dolly involves physically moving the camera to change the composition of the image in the frame.
See the demo
Properties
Name | Type | Default | Description |
---|---|---|---|
.enabled |
boolean |
true |
Whether or not the controls are enabled. |
.currentAction |
ACTION |
N/A | Getter for the current ACTION . |
.distance |
number |
N/A | current distance. |
.minDistance |
number |
0 |
Minimum distance for dolly. |
.maxDistance |
number |
Infinity |
Maximum distance for dolly. |
.polarAngle |
number |
N/A | current polarAngle in radians. |
.minPolarAngle |
number |
0 |
In radians. |
.maxPolarAngle |
number |
Math.PI |
In radians. |
.azimuthAngle |
number |
N/A | current azimuthAngle in radians. |
.minAzimuthAngle |
number |
-Infinity |
In radians. |
.maxAzimuthAngle |
number |
Infinity |
In radians. |
.boundaryFriction |
number |
0.0 |
Friction ratio of the boundary. |
.boundaryEnclosesCamera |
boolean |
false |
Whether camera position should be enclosed in the boundary or not. |
.dampingFactor |
number |
0.05 |
The damping inertia |
.draggingDampingFactor |
number |
0.25 |
The damping inertia while dragging |
.azimuthRotateSpeed |
number |
1.0 |
Speed of azimuth rotation. |
.polarRotateSpeed |
number |
1.0 |
Speed of polar rotation. |
.dollySpeed |
number |
1.0 |
Speed of mouse-wheel dollying. |
.truckSpeed |
number |
2.0 |
Speed of drag for truck and pedestal. |
.verticalDragToForward |
boolean |
false |
The same as .screenSpacePanning in three.js's OrbitControls. |
.dollyToCursor |
boolean |
false |
true to enable Dolly-in to the mouse cursor coords. |
.colliderMeshes |
array |
[] |
An array of Meshes to collide with camera ¹. |
.infinityDolly |
boolean |
false |
true to enable Infinity Dolly ². |
- Be aware colliderMeshes may decrease performance. Collision test uses 4 raycasters from camera, since near plane has 4 corners.
- When the Dolly distance less than the minDistance, the sphere of radius will set minDistance.
Events
CameraControls instance emits the following events.
To subscribe, use cameraControl.addEventListener( 'eventname', function )
.
To unsubscribe, use cameraControl.removeEventListener( 'eventname', function )
.
Event name | Timing |
---|---|
'controlstart' |
When the user starts to control the camera via mouse / touches. |
'control' |
When the user controls the camera (dragging). |
'controlend' |
When the user ends to control the camera. |
'update' |
When the camera position is updated. |
'wake' |
When the camera start moving. |
'sleep' |
When the camera end moving. |
User input config
Working example: user input config
button to assign | behavior |
---|---|
mouseButtons.left |
CameraControls.ACTION.ROTATE * | CameraControls.ACTION.TRUCK | CameraControls.ACTION.OFFSET | CameraControls.ACTION.DOLLY | CameraControls.ACTION.ZOOM | CameraControls.ACTION.NONE
|
mouseButtons.right |
CameraControls.ACTION.ROTATE | CameraControls.ACTION.TRUCK * | CameraControls.ACTION.OFFSET | CameraControls.ACTION.DOLLY | CameraControls.ACTION.ZOOM | CameraControls.ACTION.NONE
|
mouseButtons.wheel |
CameraControls.ACTION.ROTATE | CameraControls.ACTION.TRUCK | CameraControls.ACTION.OFFSET | CameraControls.ACTION.DOLLY | CameraControls.ACTION.ZOOM | CameraControls.ACTION.NONE
|
- * is the default.
- The default of
mouseButtons.wheel
is:-
DOLLY
for Perspective camera. -
ZOOM
for Orthographic camera, and can't setDOLLY
.
-
fingers to assign | behavior |
---|---|
touches.one |
CameraControls.ACTION.TOUCH_ROTATE * | CameraControls.ACTION.TOUCH_TRUCK | CameraControls.ACTION.TOUCH_OFFSET | CameraControls.ACTION.DOLLY
|
touches.two |
ACTION.TOUCH_DOLLY_TRUCK | ACTION.TOUCH_DOLLY_OFFSET | ACTION.TOUCH_ZOOM_TRUCK | ACTION.TOUCH_ZOOM_OFFSET | ACTION.TOUCH_DOLLY | ACTION.TOUCH_ZOOM | CameraControls.ACTION.TOUCH_ROTATE | CameraControls.ACTION.TOUCH_TRUCK | CameraControls.ACTION.TOUCH_OFFSET | CameraControls.ACTION.NONE
|
touches.three |
ACTION.TOUCH_DOLLY_TRUCK | ACTION.TOUCH_DOLLY_OFFSET | ACTION.TOUCH_ZOOM_TRUCK | ACTION.TOUCH_ZOOM_OFFSET | CameraControls.ACTION.TOUCH_ROTATE | CameraControls.ACTION.TOUCH_TRUCK | CameraControls.ACTION.TOUCH_OFFSET | CameraControls.ACTION.NONE
|
- * is the default.
- The default of
touches.two
andtouches.three
is:-
TOUCH_DOLLY_TRUCK
for Perspective camera. -
TOUCH_ZOOM_TRUCK
for Orthographic camera, and can't setTOUCH_DOLLY_TRUCK
andTOUCH_DOLLY
.
-
Methods
rotate( azimuthAngle, polarAngle, enableTransition )
Rotate azimuthal angle(horizontal) and polar angle(vertical).
Name | Type | Description |
---|---|---|
azimuthAngle |
number |
Azimuth rotate angle. In radian. |
polarAngle |
number |
Polar rotate angle. In radian. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
rotateTo( azimuthAngle, polarAngle, enableTransition )
Rotate azimuthal angle(horizontal) and polar angle(vertical) to a given point.
Name | Type | Description |
---|---|---|
azimuthAngle |
number |
Azimuth rotate angle to. In radian. |
polarAngle |
number |
Polar rotate angle to. In radian. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
dolly( distance, enableTransition )
Dolly in/out camera position.
Name | Type | Description |
---|---|---|
distance |
number |
Distance of dollyIn |
enableTransition |
boolean |
Whether to move smoothly or immediately |
dollyTo( distance, enableTransition )
Dolly in/out camera position to given distance.
Name | Type | Description |
---|---|---|
distance |
number |
Distance of dollyIn |
enableTransition |
boolean |
Whether to move smoothly or immediately |
zoom( zoomStep, enableTransition )
Zoom in/out of camera.
Name | Type | Description |
---|---|---|
zoomStep |
number |
zoom scale |
enableTransition |
boolean |
Whether to move smoothly or immediately |
You can also make zoomIn function using camera.zoom
property.
e.g.
const zoomIn = () => cameraControls.zoom( camera.zoom / 2, true );
const zoomOut = () => cameraControls.zoom( - camera.zoom / 2, true );
zoomTo( zoom, enableTransition )
Zoom in/out camera to given scale.
Name | Type | Description |
---|---|---|
zoom |
number |
zoom scale |
enableTransition |
boolean |
Whether to move smoothly or immediately |
truck( x, y, enableTransition )
Truck and pedestal camera using current azimuthal angle.
Name | Type | Description |
---|---|---|
x |
number |
Horizontal translate amount |
y |
number |
Vertical translate amount |
enableTransition |
boolean |
Whether to move smoothly or immediately |
setFocalOffset( x, y, z, enableTransition )
Set focal offset using the screen parallel coordinates.
z
doesn't affect in Orthographic as with Dolly.
Name | Type | Description |
---|---|---|
x |
number |
Horizontal offset amount |
y |
number |
Vertical offset amount |
z |
number |
Depth offset amount. The result is the same as Dolly but unaffected by minDistance and maxDistance
|
enableTransition |
boolean |
Whether to move smoothly or immediately |
forward( distance, enableTransition )
Move forward / backward.
Name | Type | Description |
---|---|---|
distance |
number |
Amount to move forward / backward. Negative value to move backward |
enableTransition |
boolean |
Whether to move smoothly or immediately |
moveTo( x, y, z, enableTransition )
Move target
position to given point.
Name | Type | Description |
---|---|---|
x |
number |
x coord to move center position |
y |
number |
y coord to move center position |
z |
number |
z coord to move center position |
enableTransition |
boolean |
Whether to move smoothly or immediately |
fitToBox( box3OrMesh, enableTransition, { paddingTop, paddingLeft, paddingBottom, paddingRight } )
Fit the viewport to the box or the bounding box of the object, using the nearest axis. paddings are in unit.
Name | Type | Description |
---|---|---|
box3OrMesh |
THREE.Box3 | THREE.Mesh
|
Axis aligned bounding box to fit the view. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
options |
object |
Options |
options.paddingTop |
number |
Padding top. Default is 0
|
options.paddingRight |
number |
Padding right. Default is 0
|
options.paddingBottom |
number |
Padding bottom. Default is 0
|
options.paddingLeft |
number |
Padding left. Default is 0
|
fitToSphere( sphereOrMesh, enableTransition )
Fit the viewport to the sphere or the bounding sphere of the object.
Name | Type | Description |
---|---|---|
sphereOrMesh |
THREE.Sphere | THREE.Mesh
|
bounding sphere to fit the view. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
setLookAt( positionX, positionY, positionZ, targetX, targetY, targetZ, enableTransition )
It moves the camera into position
, and make it look at target
.
Name | Type | Description |
---|---|---|
positionX |
number |
Position x of look at from. |
positionY |
number |
Position y of look at from. |
positionZ |
number |
Position z of look at from. |
targetX |
number |
Position x of look at. |
targetY |
number |
Position y of look at. |
targetZ |
number |
Position z of look at. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
lerpLookAt( positionAX, positionAY, positionAZ, targetAX, targetAY, targetAZ, positionBX, positionBY, positionBZ, targetBX, targetBY, targetBZ, t, enableTransition )
Similar to setLookAt
, but it interpolates between two states.
Name | Type | Description |
---|---|---|
positionAX |
number |
The starting position x of look at from. |
positionAY |
number |
The starting position y of look at from. |
positionAZ |
number |
The starting position z of look at from. |
targetAX |
number |
The starting position x of look at. |
targetAY |
number |
The starting position y of look at. |
targetAZ |
number |
The starting position z of look at. |
positionBX |
number |
Look at from position x to interpolate towards. |
positionBY |
number |
Look at from position y to interpolate towards. |
positionBZ |
number |
Look at from position z to interpolate towards. |
targetBX |
number |
look at position x to interpolate towards. |
targetBY |
number |
look at position y to interpolate towards. |
targetBZ |
number |
look at position z to interpolate towards. |
t |
number |
Interpolation factor in the closed interval [0, 1]. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
setPosition( positionX, positionY, positionZ, enableTransition )
setLookAt
without target, keep gazing at the current target.
Name | Type | Description |
---|---|---|
positionX |
number |
Position x of look at from. |
positionY |
number |
Position y of look at from. |
positionZ |
number |
Position z of look at from. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
setTarget( targetX, targetY, targetZ, enableTransition )
setLookAt
without position, Stay still at the position.
Name | Type | Description |
---|---|---|
targetX |
number |
Position x of look at. |
targetY |
number |
Position y of look at. |
targetZ |
number |
Position z of look at. |
enableTransition |
boolean |
Whether to move smoothly or immediately |
setBoundary( box3? )
Set the boundary box that encloses the target of the camera. box3
is in THREE.Box3
Return its current position.
Name | Type | Description |
---|---|---|
box3 |
THREE.Box3? |
Boundary area. No argument to remove the boundary. |
setViewport( vector4? )
Set (or unset) the current viewport.
Set this when you want to use renderer viewport and .dollyToCursor
feature at the same time.
See: THREE.WebGLRenderer.setViewport()
Name | Type | Description |
---|---|---|
vector4 |
THREE.Vector4? |
Vector4 that represents the viewport, or undefined for unsetting this. |
setViewport( x, y, width, height )
Same as setViewport( vector4 )
, but you can give it four numbers that represents a viewport instead:
Name | Type | Description |
---|---|---|
x |
number |
Leftmost of the viewport. |
y |
number |
Bottommost of the viewport. |
width |
number |
Width of the viewport. |
height |
number |
Height of the viewport. |
getPosition( out )
Return its current position.
Name | Type | Description |
---|---|---|
out |
THREE.Vector3 |
The receiving vector |
getTarget( out )
Return its current gazing target, which is the center position of the orbit.
Name | Type | Description |
---|---|---|
out |
THREE.Vector3 |
The receiving vector |
getFocalOffset( out )
Return its current focal offset, which is how much the camera appears to be translated in screen parallel coordinates.
Name | Type | Description |
---|---|---|
out |
THREE.Vector3 |
The receiving vector |
saveState()
Set current camera position as the default position
normalizeRotations()
Normalize camera azimuth angle rotation between 0 and 360 degrees.
reset( enableTransition )
Reset all rotation and position to default.
Name | Type | Description |
---|---|---|
enableTransition |
boolean |
Whether to move smoothly or immediately |
update( delta ): boolean
Update camera position and directions. This should be called in your tick loop and returns true
if re-rendering is needed.
Name | Type | Description |
---|---|---|
delta |
number |
Delta time between previous update call |
updateCameraUp()
When you change camera-up vector, run .updateCameraUp()
to sync.
addEventListener( type: string, listener: function )
Adds the specified event listener.
removeEventListener( type: string, listener: function )
Removes the specified event listener.
removeAllEventListeners( type: string )
Removes all listeners for the specified type.
toJSON()
Get all state in JSON string
fromJSON( json, enableTransition )
Reproduce the control state with JSON. enableTransition
is where anim or not in a boolean.
dispose()
Dispose the cameraControls instance itself, remove all eventListeners.
Breaking changes
@1.16.0 dolly()
will take opposite value. e.g. dolly-in to dolly( 1 )
(used be dolly-in to dolly( -1 )
)
Contributors
This project exists thanks to all the people who contribute.