Skip to content

Slowly Fly to a Location ​

Create a cinematic, slow-panning camera movement using flyTo with reduced speed and a long duration.

The Key Parameters ​

javascript
map.flyTo({
  center: [lng, lat],
  zoom: 12,

  // Speed: fraction of default (1.2). Lower = slower.
  speed: 0.25,   // ~5× slower than default

  // Curve: how high the arc flies. Higher = more zoom-out.
  curve: 1.8,

  // Or override with a fixed duration in ms
  // duration: 8000,

  // Respect user's reduced-motion preference (optional)
  // essential: true means it ignores prefers-reduced-motion
  essential: true,
});

speed vs duration ​

OptionDescription
speedMultiplier relative to default (1.2). 0.25 ≈ 5× slower. Scales with distance.
durationFixed time in milliseconds, regardless of distance.
Both setduration takes precedence over speed.

Stop an In-Progress Animation ​

javascript
// Cancel any ongoing camera animation
map.stop();

Listen for Animation End ​

javascript
map.flyTo({ center: [lng, lat], zoom: 12, speed: 0.3 });

map.once('moveend', () => {
  console.log('Arrived at destination');
});

Cinematic Pan (no zoom change) ​

javascript
// Slow pan without changing zoom
map.easeTo({
  center: [lng, lat],
  duration: 6000,
  easing: t => t, // linear
});

Complete Example ​

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css" rel="stylesheet" />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
    <style>#map { height: 500px; width: 100%; }</style>
  </head>
  <body>
    <div id="map"></div>
    <button id="ny">New York</button>
    <button id="paris">Paris</button>
    <button id="cancel">Cancel</button>
    <script>
      const map = new mapmetricsgl.Map({
        container: 'map',
        style: '<StyleFile_URL_with_Token>',
        center: [0, 20],
        zoom: 2
      });

      function slowFly(center, zoom) {
        map.flyTo({ center, zoom, speed: 0.25, curve: 1.8, essential: true });
      }

      document.getElementById('ny').addEventListener('click', () => slowFly([-74, 40.7], 11));
      document.getElementById('paris').addEventListener('click', () => slowFly([2.35, 48.85], 11));
      document.getElementById('cancel').addEventListener('click', () => map.stop());
    </script>
  </body>
</html>
jsx
import React, { useEffect, useRef } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

const destinations = [
  { name: 'New York', center: [-74.0, 40.7] },
  { name: 'Paris', center: [2.35, 48.85] },
  { name: 'Tokyo', center: [139.7, 35.7] },
  { name: 'Rio', center: [-43.2, -22.9] },
];

const SlowlyFlyToLocation = () => {
  const mapContainer = useRef(null);
  const map = useRef(null);

  useEffect(() => {
    if (map.current) return;
    map.current = new mapmetricsgl.Map({
      container: mapContainer.current,
      style: '<StyleFile_URL_with_Token>',
      center: [0, 20],
      zoom: 2
    });
    return () => { map.current?.remove(); map.current = null; };
  }, []);

  const slowFly = (center) => {
    map.current?.flyTo({ center, zoom: 11, speed: 0.25, curve: 1.8, essential: true });
  };

  return (
    <div>
      <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />
      <div style={{ marginTop: 10, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        {destinations.map(d => (
          <button key={d.name} onClick={() => slowFly(d.center)}
            style={{ padding: '8px 14px', cursor: 'pointer', borderRadius: 6, border: 'none', background: '#3b82f6', color: 'white' }}>
            {d.name}
          </button>
        ))}
        <button onClick={() => map.current?.stop()}
          style={{ padding: '8px 14px', cursor: 'pointer', borderRadius: 6, border: 'none', background: '#6b7280', color: 'white' }}>
          Cancel
        </button>
      </div>
    </div>
  );
};

export default SlowlyFlyToLocation;

For more information, visit the MapMetrics GitHub repository.