Examples
Animating with Mapbox

Animations with Mapbox GL

The following provides an example of Maps radar animations integrated with the Mapbox GL API (opens in a new tab) library. For an example using our JS SDK, please visit the Xweather Javascript SDK docs.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Mapbox GL Animation - Xweather Raster Maps</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #map {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
 
<div id="map"></div>
 
<script>
 
const frameCount = 10; // total intervals
const startMinutes = -60; // start time offset relative to now, where negative means past
const endMinutes = 0;
 
const MAPBOX_TOKEN = 'MAPBOX_TOKEN';
const AERIS_ID = 'CLIENT_ID';
const AERIS_KEY = 'CLIENT_SECRET';
const NUM_COLORS = '256'; // set to empty string for true color png
const TILE_SIZE = 256;
 
// layer to include on the map
// uncomment more layers or add more!
const layers = [
    // 'alerts',
    // 'satellite',
    'radar',
    'stormcells'
];
 
function getTilePath(server, interval) {
    return `https://maps${server}.aerisapi.com/${AERIS_ID}_${AERIS_KEY}/${layers.join(',')}/{z}/{x}/{y}/${interval}min.png${NUM_COLORS}`;
}
 
window.addEventListener('load', () => {
    mapboxgl.accessToken = MAPBOX_TOKEN;
 
    const map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-95, 40],
        zoom: 4
    });
 
    function addRasterLayer(map, interval, opacity = 0) {
        const id = `amp-${layers.join('::')}-${interval}`;
        map.addSource(id, {
            type: 'raster',
            tiles: [1, 2, 3, 4].map((s) => getTilePath(s, interval)),
            tileSize: TILE_SIZE,
            attribution: '<a href="https://www.aerisweather.com/">Xweather</a>'
        });
        map.addLayer({
            id, 
            type: 'raster',
            source: id,
            minzoom: 0,
            maxzoom: 22,
            paint: {
                'raster-opacity': opacity,
                'raster-opacity-transition': {
                    duration: 0,
                    delay: 0
                }
            }
        });
 
        return id;
    }
 
    function setRasterLayerOpacity(map, id, opacity) {
        map.setPaintProperty(id, 'raster-opacity', opacity);
    }
 
    map.on('load', () => {
        const interval = (endMinutes - startMinutes) / frameCount;
        // set up the animation frames and layers
        const frames = [];
        for (let i = 0; i < frameCount; i += 1) {
            const opacity = (i === 0) ? 1 : 0;
            const timeOffset = startMinutes + interval * i;
            const id = addRasterLayer(map, timeOffset, opacity);
            frames.push(id);
        }
 
        // wait time determines how long to wait and allow frames to load before
        // beginning animation playback
        const waitTime = 5000;
 
        // step time determines the time in milliseconds each frame holds before advancing
        const stepTime = 1000;
 
        let currentOffset = 0;
        let previousOffset = currentOffset;
 
        setTimeout(() => {
            setInterval(() => {
                previousOffset = currentOffset;
                currentOffset += 1;
                if (currentOffset === frames.length - 1) {
                    currentOffset = 0;
                }
                setRasterLayerOpacity(map, frames[previousOffset], 0);
                setRasterLayerOpacity(map, frames[currentOffset], 1);
            }, stepTime);
        }, waitTime);
    });
});
</script>
 
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js" async defer></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
 
</body>
</html>