flyTo follows the Van Wijk and Nuij zoom-and-pan path, which arcs out to a wider
zoom during a long move and derives its own duration from the distance travelled: crossing a
continent takes longer than nudging to a neighbouring country, without anyone tuning a number.
Interpolating centre and scale linearly instead feels wrong, because perceived motion is
logarithmic in scale, and that difference is what separates a camera that reads as cinematic from
one that reads as a slideshow.
The camera is a screen-space transform, and no amount of translating it can reach the far side
of a sphere. So on an azimuthal projection the same flyTo({ center }) turns the
globe instead of panning it: this one opens facing Brazil, and India is behind the planet.
The rotation interpolates as a quaternion slerp, which is what makes it take the short way
round and hold a steady angular pace rather than wobbling, and its duration comes from the
angle covered, so a hop to Iceland does not take as long as a flip to the antipodes. Drag it
too: the gestures and the camera agree about where the globe is.
Click two flights in quick succession. The second does not queue behind the first and does not snap: it starts from wherever the camera has interpolated to. In a scroll-driven story the reader can outrun any animation at any moment, so every move has to be interruptible or the map ends up somewhere the narrative did not ask for. Panning or zooming by hand stops an in-flight move for the same reason.
map.camera.flyTo({ center: [2.35, 48.86], zoom: 8 }) // Van Wijk path, derived duration
map.camera.easeTo({ center: [2.35, 48.86], zoom: 8, duration: 400, ease: 'cubicInOut' })
map.camera.jumpTo({ zoom: 4 })
map.camera.fitBounds(worldBounds, { padding: 40, maxZoom: 12 })
await map.frameFeature('France', { padding: 40 })
await map.resetView()
// One step about the centre of the plot: what the on-screen +/- buttons and the
// +/- keys do, so host chrome behaves exactly like the built-in controls.
map.zoomIn()
map.zoomOut()
// Same call, orthographic projection: turns the sphere rather than panning it.
await globe.camera.flyTo({ center: [79, 22] })
Every one of these honours prefers-reduced-motion by jumping instead of animating,
rather than by breaking.