Camera Control and animation
The viewer provides a level of abstraction over the cameras in the scene to make it easy to manage multiple cameras, enable/disable/configure camera controls(like
OrbitControls), and integrate with post-processing and XR pipelines. This is managed in a class called
On initialisation, the viewer creates a default
PerspectiveCamera with a
OrbitControls which is used for scene rendering.
The active camera controller can be accessed by:
const controller = viewer.scene.activeCamera;
// get the threejs camera
const perspectiveCamera = controller.cameraObj;
// get orbit controls
const orbitControls = controller.controls;
activeCamera is the camera that is used for scene rendering. This can be set to a custom camera like:
const cameraObj = new THREE.PerspectiveCamera();
viewer.scene.activeCamera = viewer.createCamera(cameraObj);
createCamera above, creates and returns a
CameraController instance. It is automatically ensured that only one controller is created for a camera instance, even if this function is called multiple times.
To get the
CameraController from the camera use
controller = cameraObj.userData.iCamera
target can be set directly in the controller;
viewer.scene.activeCamera.position = new THREE.Vector3(2, 3, -5);
viewer.scene.activeCamera.target = new THREE.Vector3(0, 2, 0);
viewer.scene.activeCamera.position.set(2, 3, -5);
viewer.scene.activeCamera.positionUpdated(); // this must be called to notify the controller on value update
viewer.scene.activeCamera.target.set(0, 2, 0);
viewer.scene.activeCamera.targetUpdated(); // this must be called to notify the controller on value update
Camera global scale must be set to
z. This is automatically ensured while models and cameras are imported, but it must be taken care of when updating models and hierarchy by code.
Various camera options can be get/set from the controller:
const options = viewer.scene.activeCamera.getCameraOptions();
options.fov = 25;
The following options can be set:
fov: Vertical Field of View in degrees. Perspective Camera only.
zoom: Camera zoom value
aspect: Camera aspect ratio. Default is set to
'auto', which calculates the aspect ratio based on canvas size, and updates on size change.
controlsEnabled: Enable or disable Orbit Controls etc.
frustumSize: for Orthographic camera.
Options for controls like
OrbitControls can be set directly after accessing it.
const controls = viewer.scene.activeCamera.controls;
controls.autoRotate = true;
controls.autoRotateSpeed = true;
controls.enableDamping = true;
controls.rotateSpeed = 2.0;
controls.enableZoom = false;
For all properties, see three.js docs on OrbitControls
OrbitControls in webgi also support smooth dolly zooming with mouse wheel when used with
enabledDamping=true. To control the speed and max speed of this zooming see
OrbitControls in webgi is extended for some extra performance improvements, and camera movements are syned with the render loop. So, prefer to use the instance of
OrbitControls in the default camera instead of passing in a custom one.
OrbitControls is supported, internally, but others can be added by extending
Here's a codepen with live demo for accessing and modifying the camera properties:
Camera Animation and Views
CameraViewPlugin can be used to manage and animate between multiple camera states(views).
First add the plugin (This is done in
Then get the reference to the plugin
const camViewPlugin = viewer.getPlugin(CameraViewPlugin)
Camera views can be created in the editor and downloaded as a preset and applied at runtime or they can be added programmatically like below:
let view = camViewPlugin.getCurrentCameraView(viewer.scene.activeCamera) // Get the current camera state
camViewPlugin.camViews.push(view) // save it for later.
// add more views
Now we can animate the camera to a view:
await camViewPlugin.animateToView(camViews.camViews, 2000) // 2000 ms is the duration
Once the camera views are added, they can be looped or played through once.
camViewPlugin.animDuration = 3000 // ms, default duration of one animation
await camViewPlugin.animateAllViews() // This will loop once
camViewPlugin.viewLooping = true // This will loop indefinitely
Interpolation of camera position is spherical by default to ensure smooth movement, but it can be changed to linear for direct interpolation.
Animation easing is set to
easeInOutSine by default, but can be set to any easing from
Check the API docs for more parameters in
Here is a codepen with live demo for the