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
| MapLibre | SDK | |
|---|---|---|
| Coordinates | [lng, lat] | [lng, lat] |
| Rendering | WebGL (GPU, 60fps) | WebGL (GPU, 60fps) |
| Bundle size | ~250 KB gzipped | ~280 KB gzipped (includes MapLibre) |
| Learning curve | Moderate (source/layer model, expressions) | Easy (MapLibre API with convenience helpers) |
| 3D support | Full: terrain, fill-extrusion, globe, sky | Full (same as MapLibre) |
| Code lines | 29 | 25 |
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
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
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.
Animation updates paint properties (e.g., circle-radius) each frame using setPaintProperty(); the GPU handles rendering efficiently.
Identical animation pattern to MapLibre: same setPaintProperty() calls in a requestAnimationFrame loop.
Which Library to Use?
Animate a circle layer's radius paint property over time to visualize temporal data changes with requestAnimationFrame.
The right choice when you need GPU-rendered animation with paint property updates driven by requestAnimationFrame for smooth 60fps transitions.
Animate map features over time by updating paint properties in a requestAnimationFrame loop with MapTiler SDK.
Delivers MapLibre's animation approach for MapTiler SDK users, with simplified map initialization.
Build Maps with AI
Generate code like these examples using mapping library skills in your IDE.