Skip to main content
Version: 6.0

Camera

Mappedin SDK version 6 is currently in a beta state while Mappedin perfects new features and APIs. Open the v6 release notes to view the latest changes.
Using Mappedin JS with your own map requires a Pro license. Try a demo map for free or refer to the Pricing page for more information.

Controlling the view of the map allows apps to create visually rich experiences using Mappedin JS. This guide shows how to focus the map view on targets, move the camera and listen to camera events.

Mappedin JS v6 Camera

Note that the MapView class implements the Camera interface and exposes it as MapView.Camera. Use MapView.Camera to utilize Camera's methods.

Video Walkthrough

Focus the Camera on Targets

Mappedin JS has built in functionality to focus the camera on one ore more targets using a single or array of TCameraFocusOnTarget. When multiple targets are used, the SDK will ensure that all targets are visible.

The following sample code acts on the click event to focus on the Space the user clicked on. Note that the Space must be set to interactive to allow it to be clickable.

// Act on the click event to focus on the Space that was clicked.
mapView.on('click', async (event) => {
// Focus on the space that was clicked.
mapView.Camera.focusOn(event.spaces[0]);
});

The CodeSandbox below allows you to test the Camera.focusOn capability. Click on a room to focus the camera on it.

Controlling the Camera

To Control the camera, set it with new pitch, bearing or zoom using Camera.set(). It accepts a TCameraTarget object that contains bearing, center coordinate, pitch and zoom level. These paraemters are all optional, allowing the camera to by moved by adjusting one or more of these values.

Experiment with these camera controls using the CodeSandbox below.

TCameraTarget

  • bearing - Bearing for the camera target in degrees.
  • center - Center Coordinate for the camera target.
  • pitch - Pitch for the camera target in degrees.
  • zoomLevel - Zoom level for the camera target in mercator zoom levels.
mapView.Camera.set({
bearing: 30,
pitch: 80,
zoomLevel: 100,
center: e.coordinate,
});

Animation

The camera can also be animated into position using the same transforms described in the Controlling the Camera section above. This is done using the Camera.animateTo() method. Similar to Camera.set(), the animateTo method accepts a TCameraTarget object, but it is optional. This allows the camera to changed by adjusting its bearing, pitch or zoomLevel without specifying a new target to move to. In addition, animateTo also accepts TCameraAnimationOptions that allow setting of the duration of the animation in milliseconds and setting the easing curve.

The next code snippet acts on the click event to animate the camera to the click position. It uses easing ease-in-out over 4000 milliseconds.

// Act on the click event to animate to a new camera position.
mapView.on('click', async (event) => {
mapView.Camera.animateTo(
{
bearing: 30,
pitch: 80,
zoomLevel: 100,
center: event.coordinate,
},
{ duration: 4000, easing: 'ease-in-out' },
);
});

The types of easing anmiations are defined in TEasingFunction.

The next CodeSandbox makes use of animates to fly the camera to all points of interest on the map.

TEasingFunction

  • Linear: This function implies a constant rate of change. It means the animation proceeds at the same speed from start to end. There's no acceleration or deceleration, giving a very mechanical feel.
  • Ease-in: This function causes the animation to start slowly and then speed up as it progresses. Initially, there's gradual acceleration, and as the function moves forward, the rate of change increases.
  • Ease-out: Contrary to ease-in, ease-out makes the animation start quickly and then slow down towards the end. It begins with a faster rate of change and gradually decelerates.
  • Ease-in-out: This function combines both ease-in and ease-out. The animation starts slowly, speeds up in the middle, and then slows down again towards the end. It offers a balance of acceleration and deceleration.

Resetting The Camera

While there is no method in Mappedin JS to reset the camera to its default position, this can be easily built into an app. To do so, store the camera position after the map is shown and then use those values to reposition the camera at a later time.

The code sample below stores the initial camera position. When a user clicks on a location it first focuses on that space. The next click will return the camera to its original position.

let focused: boolean = false;

//Display the default map in the mappedin-map div.
const mapView = await show3dMap(document.getElementById('mappedin-map') as HTMLDivElement, mapData);

const defaultCameraPosition: TCameraTarget = {
bearing: mapView.Camera.bearing,
pitch: mapView.Camera.pitch,
zoomLevel: mapView.Camera.zoomLevel,
center: mapView.Camera.center,
};

// Set each space to be interactive and its hover color to orange.
mapData.getByType('space').forEach((space) => {
mapView.updateState(space, {
interactive: true,
hoverColor: '#f26336',
});
});

// Act on the click event to focus on the Space that was clicked or reset the camera.
mapView.on('click', async (event) => {
if (focused) {
// Reset the camera to its default position.
mapView.Camera.set(defaultCameraPosition);
focused = false;
} else {
// Focus on the space that was clicked.
mapView.Camera.focusOn(event.spaces[0]);
focused = true;
}
});

Listening to Camera Events

There are several camera events that can be acted on by setting a listener with mapView.on('camera-change'). The camera-change event contains a CameraTransform object. CameraTransform provides the bearing, center coordinate, pitch and zoom level.

// Log camera change events to the console.
mapView.on('camera-change', async (cam) => {
console.log(
'Bearing: ' +
cam.bearing +
', Pitch: ' +
cam.pitch +
', Zoom Level: ' +
cam.zoomLevel +
', Center: Lat:' +
cam.center.latitude,
+', Lon:' + cam.center.longitude,
);
});

The following CodeSandbox implements the code snippet above to print out camera change events to the console.