Animate a Marker
Animate a Marker smoothly across the map using requestAnimationFrame and setLngLat().
Animate a Marker with requestAnimationFrame
javascript
const marker = new mapmetricsgl.Marker({ color: '#3b82f6' })
.setLngLat([0, 0])
.addTo(map);
let t = 0;
function animate() {
t += 0.005;
// Move in a sine wave pattern
const lng = (t * 30) % 360 - 180;
const lat = Math.sin(t) * 40;
marker.setLngLat([lng, lat]);
requestAnimationFrame(animate);
}
animate();Animate Along Waypoints
javascript
const waypoints = [[2.35, 48.85], [-0.12, 51.50], [13.40, 52.52]];
let step = 0;
const stepsPerSegment = 100;
let subStep = 0;
function animate() {
const from = waypoints[step];
const to = waypoints[(step + 1) % waypoints.length];
const t = subStep / stepsPerSegment;
marker.setLngLat([
from[0] + (to[0] - from[0]) * t,
from[1] + (to[1] - from[1]) * t
]);
subStep++;
if (subStep > stepsPerSegment) {
subStep = 0;
step = (step + 1) % waypoints.length;
}
requestAnimationFrame(animate);
}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>
<script>
const map = new mapmetricsgl.Map({ container: 'map', style: '<StyleFile_URL_with_Token>', center: [0, 20], zoom: 1.5 });
const marker = new mapmetricsgl.Marker({ color: '#3b82f6' }).setLngLat([0, 20]).addTo(map);
let t = 0;
function animate() {
t += 0.005;
marker.setLngLat([(t * 30) % 360 - 180, Math.sin(t) * 40]);
requestAnimationFrame(animate);
}
map.on('load', animate);
</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 AnimateMarker = () => {
const mapContainer = useRef(null);
const map = useRef(null);
const animId = useRef(null);
useEffect(() => {
if (map.current) return;
map.current = new mapmetricsgl.Map({ container: mapContainer.current, style: '<StyleFile_URL_with_Token>', center: [0, 20], zoom: 1.5 });
const marker = new mapmetricsgl.Marker({ color: '#3b82f6' }).setLngLat([0, 20]).addTo(map.current);
let t = 0;
const animate = () => {
t += 0.005;
marker.setLngLat([(t * 30) % 360 - 180, Math.sin(t) * 40]);
animId.current = requestAnimationFrame(animate);
};
map.current.on('load', animate);
return () => {
if (animId.current) cancelAnimationFrame(animId.current);
map.current?.remove(); map.current = null;
};
}, []);
return <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />;
};
export default AnimateMarker;For more information, visit the MapMetrics GitHub repository.