Skip to Content
ExamplesRoute Animation

Route Animation

To animate a route, we have the option to animate the complete route, or animate step by step.

Below is an example image showing the route animation, with customizable colors and a personalized icon:

Route animation example

Style animation

Both options use the same interface to configure the style used to draw the route on the map.

The AnimationDrawingConfig lets you configure:

  • aheadPathStyle — style for the route ahead of the icon (default: gray)
  • behindPathStyle — style for the route behind the icon (default: blue)
  • polylineWidth — line width in pixels (default: 10)
  • routeIconConfig — customize the default arrow icon colors
  • routeIcon — provide a completely custom HTMLElement as the route icon

Custom route icon

You can use the default arrow icon with custom colors:

const drawConfig: AnimationDrawingConfig = { aheadPathStyle: { type: "Solid", color: "#757575" }, behindPathStyle: { type: "Solid", color: "#0076B6" }, routeIconConfig: { backgroundColor: "#E53935", arrowColor: "#FFFFFF", }, }

Or provide a fully custom icon (e.g., a car or wheelchair image):

const carIcon = new Image(40, 40) carIcon.src = "path/to/car-icon.svg" const drawConfig: AnimationDrawingConfig = { routeIcon: carIcon, // Takes precedence over routeIconConfig aheadPathStyle: { type: "Solid", color: "#757575" }, behindPathStyle: { type: "Solid", color: "#0076B6" }, }

Animate complete route

On this animation you can start the animation, pause and resume the animation, and restart a already started animation.

Start animation

To start the animation, you need to use startAnimateRoute.

This function receive three arguments:

  • The first correspond to a GetRouteConfiguration to define the route to animate.
  • The second correspond to a AnimationDrawingConfig to define the style used to draw the route during the animation. A difference from the style used on addRoute, in this you can configure two RouteStyle, one for the path before the icon representing the user, and one for the path ahead of the icon.
  • The third argument correspond to a AnimationConfig. In this you can configure the animation of the route, for example define the time used to animate each step, the time used to rotate the icon, define a callback function to know what step is being animated, etc. For more details revise the documentation available on AnimationConfig.

This function return the information of the route being animated as a MVXRoute.

A example using all this will be:

const route = await this.lzMap?.startAnimateRoute( config, {}, // Use default configuration { iconRotationTime: 1, callBack: ({ isFinished, step }) => { if (isFinished) { console.log("I know that the animation finished") } else { console.log("Started to animated step ", step) } }, } )

Pause the animation

You can pause the animation at any time with pauseAnimateRoute.

This will pause the ongoing animation.

If this method is called when there isn’t a ongoing route animation on the map, like:

  • There isn’t a route on the map.
  • There is a route on the map, but was added with addRoute or addStepAnimation
  • There is an already paused route.
  • There is an already finished route.

It will throw a Error. This method only function with the animation started with startAnimateRoute

Resume the animation

You can resume a paused animation with resumeAnimateRoute.

Only function with a animation paused by pauseAnimateRoute, else will throw a Error.

Restart the animation

You can restart a animation at any time with restartAnimateRoute.

Only function with a animation added by startAnimateRoute, else will throw a Error.

Animate step by step

You can also animate a route step by step using addStepAnimation. This will animate only a step at a time.

Add the step by step animation

You start adding the step animation using addStepAnimation.

This will add the route prepared to animate the first step of the route. The marker always start with bearing 0.

This function use similar arguments that startAnimateRoute with the difference that in addStepAnimation is permitted to pass the information of an already obtained route as the first arguments.

For example, is you animated a route with startAnimateRoute and know you wish to show a step by step animation, inverting the default colors for the paths, it will be

const newRoute = await this.lzMap?.addStepAnimation( route, // The route information already obtained with startAnimateRoute { behindPathStyle: { type: "Solid", color: "#757575" }, aheadPathStyle: { type: "Solid", color: "#0076B6" }, }, { iconRotationTime: 1, callBack: ({ isFinished, step }) => { if (isFinished) { console.log("I know that the animation finished") } else { console.log("Started to animated step ", step) } }, } )

Animate to next step

To animate the current displayed step, you need to call nextStepAnimation.

The animation starts by rotating the icon to align it with the path of the step, and then moving along the route until it has completed the entire step.

Return to previous step

To return to a previous step, you need to call previousStepAnimation.

This will change the display as if you have finished to animate the before previous step, and if you call now a nextStepAnimation, it will animate the previous step.

Animation configuration options

All timing and behavior options are set through AnimationConfig, the third argument to startAnimateRoute and addStepAnimation.

PropertyTypeDefaultDescription
stepTimenumber3Time in seconds to animate each step.
minimumSpeednumber40Minimum speed in m/s. When the calculated speed for a step falls below this value, this value is used instead. Prevents very short steps from animating too slowly.
changeFloorTimenumber0Time in seconds to pause when the animation crosses a floor boundary. Useful for showing a floor-change indicator before the route continues on the new floor.
iconRotationTimenumber0Time in seconds to rotate the icon when the route changes direction.
callBack(status: AnimationStatus) => voidCalled at the start of each step and once more with { isFinished: true, step: null } when the animation completes.
autoFitByPlace{ enabled: boolean; padding?: PaddingOptions }Automatically adjusts the map view when the animation enters a new building or place. Disabled by default.

Controlling animation speed

Use stepTime and minimumSpeed together to tune pacing. stepTime sets the target duration per step, but if the step is so short that the resulting speed would fall below minimumSpeed, the minimum speed caps the animation instead.

const route = await map.startAnimateRoute( config, {}, { stepTime: 5, // Each step takes up to 5 seconds minimumSpeed: 20, // Never slower than 20 m/s on very short steps } )

Pausing on floor changes

Set changeFloorTime to give users a moment to see the floor-transition indicator before the animation continues on the new floor.

const route = await map.startAnimateRoute( config, {}, { changeFloorTime: 2, // 2-second pause at each floor transition iconRotationTime: 1, } )

Tracking animation progress with callBack

The callBack receives an AnimationStatus object on every step and once more when the animation finishes. Use it to update a turn-by-turn instruction panel or trigger other UI changes.

const route = await map.startAnimateRoute( config, {}, { callBack: ({ isFinished, step }) => { if (isFinished) { showArrivalBanner() } else { updateInstructionPanel(step) } }, } )

Auto-fitting the map to the current building

When a route crosses multiple buildings, autoFitByPlace re-fits the map view each time the animation enters a new place. Set enabled: true and optionally provide PaddingOptions to control the inset around the fitted bounds.

const route = await map.startAnimateRoute( config, {}, { autoFitByPlace: { enabled: true, padding: { top: 100, bottom: 100, left: 80, right: 80 }, }, } )

When padding is omitted, it defaults to { top: 150, right: 150, bottom: 150, left: 150 }.

Map view helpers

centerOnCurrentStepAnimation

centerOnCurrentStepAnimation moves the map camera to the current icon position in a step-by-step animation. Call it any time the user needs the map to re-center, for example after they have panned away.

// Center on the active step of the most recently added route map.centerOnCurrentStepAnimation() // Center on a specific route when multiple routes are on the map map.centerOnCurrentStepAnimation(route.id)

fitRouteByPlace

fitRouteByPlace filters the route steps that start or end inside a given building and fits the map bounds to show only those steps. This is the manual counterpart to autoFitByPlace in AnimationConfig and is useful when you need to trigger the fit yourself, for example when the user taps a building name in a sidebar.

// Fit the map to show only the steps inside building "building-abc" map.fitRouteByPlace(route, "building-abc") // With custom fit options map.fitRouteByPlace(route, "building-abc", { padding: { top: 120, bottom: 120, left: 80, right: 80 }, duration: 500, onComplete: () => console.log("Camera settled"), })

FitOptions also accepts bearing and pitch to orient the camera as it fits.

Multiple simultaneous route animations

You can have multiple routes on the map at the same time. Each route gets a unique id that you can use to manage animations independently:

// Animate two routes with different styles const routeA = await map.startAnimateRoute(configA, { aheadPathStyle: { type: "Solid", color: "#757575" }, behindPathStyle: { type: "Solid", color: "#0076B6" }, }) const routeB = await map.startAnimateRoute(configB, { aheadPathStyle: { type: "Solid", color: "#BDBDBD" }, behindPathStyle: { type: "Solid", color: "#E53935" }, }) // Pause only route A map.pauseAnimateRoute(routeA.id) // Resume only route A map.resumeAnimateRoute(routeA.id) // Remove a specific route map.removeRoute(routeA.id) // Remove all routes map.removeAllRoutes()
Last updated on