MapSnippets logoMapSnippets logo

Animated Data

Animate map features using requestAnimationFrame to visualize temporal changes Each library has its own approach: here's how they compare.

Quick Recommendations

MapLibre GL JS — The right choice when you need GPU-rendered animation with paint property updates driven by requestAnimationFrame for smooth 60fps transitions.

MapTiler SDK — Delivers MapLibre's animation approach for MapTiler SDK users, with simplified map initialization.

At a Glance

MapLibreSDK
Coordinates[lng, lat][lng, lat]
RenderingWebGL (GPU, 60fps)WebGL (GPU, 60fps)
Bundle size~250 KB gzipped~280 KB gzipped (includes MapLibre)
Learning curveModerate (source/layer model, expressions)Easy (MapLibre API with convenience helpers)
3D supportFull: terrain, fill-extrusion, globe, skyFull (same as MapLibre)
Code lines2925

Code Snippets

Click a library to expand its code. Each snippet shows only the core logic: the scaffold handles HTML boilerplate.

MapLibre GL JS29 linesShow code
arrow_forwardFull example
const map = new maplibregl.Map({
  container: 'map',
  style: 'https://api.maptiler.com/maps/dataviz-dark/style.json?key=YOUR_MAPTILER_KEY',
  center: [14.42, 50.08],
  zoom: 10
});
const points = [
  { coords: [14.42, 50.08], label: 'Prague' },
  { coords: [16.61, 49.20], label: 'Brno' },
  { coords: [18.26, 49.82], label: 'Ostrava' }
];
map.on('load', () => {
  map.addSource('pulses', { type: 'geojson', data: { type: 'FeatureCollection',
    features: points.map(p => ({ type: 'Feature', geometry: { type: 'Point', coordinates: p.coords }, properties: { label: p.label } })) } });
  map.addLayer({ id: 'pulse-ring', type: 'circle', source: 'pulses',
    paint: { 'circle-radius': 10, 'circle-color': 'transparent', 'circle-stroke-width': 2, 'circle-stroke-color': '#2196F3', 'circle-opacity': 1 } });
  map.addLayer({ id: 'pulse-center', type: 'circle', source: 'pulses',
    paint: { 'circle-radius': 5, 'circle-color': '#2196F3' } });
  let t = 0;
  function animate() {
    t = (t + 1) % 120;
    const r = 10 + (t / 120) * 40;
    const o = 1 - t / 120;
    map.setPaintProperty('pulse-ring', 'circle-radius', r);
    map.setPaintProperty('pulse-ring', 'circle-stroke-opacity', o);
    requestAnimationFrame(animate);
  }
  animate();
});
MapTiler SDK25 linesShow code
arrow_forwardFull example
maptilersdk.config.apiKey = 'YOUR_MAPTILER_KEY';
const map = new maptilersdk.Map({
  container: 'map',
  style: maptilersdk.MapStyle.STREETS,
  center: [-98, 39],
  zoom: 3
});
map.on('load', () => {
  map.addSource('quakes', {
    type: 'geojson',
    data: 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson'
  });
  map.addLayer({
    id: 'quake-circles', type: 'circle', source: 'quakes',
    paint: { 'circle-radius': 6, 'circle-color': '#9C27B0', 'circle-opacity': 0.7 }
  });
  const now = Date.now();
  function animate() {
    const elapsed = ((Date.now() - now) % 10000) / 10000;
    const cutoff = Date.now() - (1 - elapsed) * 30 * 24 * 3600 * 1000;
    map.setFilter('quake-circles', ['>=', ['get', 'time'], cutoff]);
    requestAnimationFrame(animate);
  }
  animate();
});

Things to Know

Implementation-specific details that matter for animated data.

MapLibre GL JS

Animation updates paint properties (e.g., circle-radius) each frame using setPaintProperty(); the GPU handles rendering efficiently.

MapTiler SDK

Identical animation pattern to MapLibre: same setPaintProperty() calls in a requestAnimationFrame loop.

Which Library to Use?

auto_awesome

Build Maps with AI

Generate code like these examples using mapping library skills in your IDE.