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:

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 colorsrouteIcon— provide a completely customHTMLElementas 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
GetRouteConfigurationto define the route to animate. - The second correspond to a
AnimationDrawingConfigto define the style used to draw the route during the animation. A difference from the style used onaddRoute, 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 onAnimationConfig.
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
addRouteoraddStepAnimation - 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.
| Property | Type | Default | Description |
|---|---|---|---|
stepTime | number | 3 | Time in seconds to animate each step. |
minimumSpeed | number | 40 | Minimum 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. |
changeFloorTime | number | 0 | Time 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. |
iconRotationTime | number | 0 | Time in seconds to rotate the icon when the route changes direction. |
callBack | (status: AnimationStatus) => void | — | Called 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()