This package contains the SceneNavigationController API, along with its constituents which may be used to create your
own controller.
Overview
The SceneNavigationController lets you pan, rotate, and zoom in 3D.
The Gizmos that visualize the current gesture can be customized via the optional gizmos option.
If the gizmos option is omitted, defaul gestures are used (rotation: circles GLB, pan: arrows GLB, zoom: octahedron GLB at 40 px).
Use of this controller allows the following interactions:
-
Panning orthogonally to the camera’s forward direction is done with a left-mouse drag by default, or a one-finger drag on touch. The mouse button can be configured.
-
Rotating around an anchor under the mouse is done with a right-mouse drag by default, or a two-finger drag on touch. The mouse button can be configured.
-
Rotating around the camera eye with left + right mouse drags or the normal rotation controls with ctrl pressed, or with normal rotation controls if
NavigationKeysMode.CAMERA_FORWARDis set. -
Zooming in to and away from an anchor under your mouse with the scroll wheel or pinch gestures.
-
Zooming in on a clicked point, when both
useZoomAnimationsandallowZoomOnClickare enabled. -
Move horizontally relative to the earth’s surface with the arrow or WASD keys (or corresponding keys if you don’t have a QWERTY keyboard) when using
NavigationKeysMode.TANGENT_FORWARD, or relative to the camera’s forward and right vector withNavigationKeysMode.CAMERA_FORWARD. -
Move vertically relative to the earth’s surface with the Q and E keys (or corresponding keys if you don’t have a QWERTY keyboard) when using
NavigationKeysMode.TANGENT_FORWARD, or relative to the camera’s up direction withNavigationKeysMode.CAMERA_FORWARD.
The left/right mouse button roles for pan vs. rotation can be swapped via the swapPanRotateButtons option.
A Bounds object must be passed to create an instance of SceneNavigationController.
These bounds define the main navigation area, so it is recommended to provide bounds that are large enough to encompass your
entire 3D object, with some margin to "move around in."
By default, navigation is constrained by these bounds. This behavior can be disabled by setting constrainToBounds to false, allowing free camera movement outside the bounds.
For detailed API information, see the SceneNavigationController file in the source code.
Camera bounds state notifications
The controller exposes whether the camera is currently within the configured bounds and allows listening to changes of this state.
Use cameraInBounds to query the current state, or onCameraInBoundsChange to be notified
when the camera transitions between in-bounds and out-of-bounds:
const handle = navigateController.onCameraInBoundsChange((inBounds) => {
console.log("Is camera in bounds:", inBounds);
});
Limitations
The map’s camera must be an instance of type PerspectiveCamera.
Usage
This code shows a typical use of the tool:
// Retrieve a 3D layer from somewhere.
// const layer = ...
map.layerTree.addChild(layer);
// Specify custom gizmos for each navigation type.
const gizmos = {
[NavigationType.ROTATION]: new NavigationGizmo("url/to/rotation-gizmo.glb"),
[NavigationType.PAN]: new NavigationGizmo("url/to/pan-gizmo.glb"),
[NavigationType.ZOOM]: new NavigationGizmo("url/to/zoom-gizmo.glb", { sizeInPixels: 40 })
};
// Create a controller with varying options.
const navigateController = new SceneNavigationController(layer.model.bounds, {
gizmos, // note: if omitted, the default gizmo setup is applied
navigationMode: NavigationKeysMode.CAMERA_FORWARD, // navigate along camera paths
defaultSpeed: 8, // ~28km/h
allowZoomOnClick: true, // clicking on a spot zooms in on to that location by a set fraction
useZoomAnimations: false, // don't use smooth animations when zooming or out
fasterMultiplier: 2, // go two times as fast when shift is pressed
slowerMultiplier: 0.5, // go only half as fast when space is pressed
swapPanRotateButtons: true, // rotate: left mouse button, pan: right mouse button
});
map.defaultController = new DefaultController({ navigateController });