
本文介绍如何在 mapbox gl js 中同时实现标记点(marker)的路径动画,并让相机始终居中跟随该标记,即“上帝视角”式追踪效果。通过结合官方动画示例与自由相机(free camera)api,可精准控制相机位置与朝向。
在 Mapbox GL JS v2.12+ 中,freeCamera 模式为高级相机控制提供了强大支持——它允许你完全绕过传统 center/zoom/pitch/bearing 的约束,直接以三维空间坐标(Mercator 坐标系)定义相机位置、朝向与焦距。这正是实现“标记点动画 + 自动跟随”效果的关键。
核心思路如下:
- 使用 requestAnimationFrame 驱动时间连续的标记位置更新;
- 每帧中,先更新 marker.setLngLat(...),再同步计算相机应处的三维坐标(正上方固定高度);
- 调用 camera.lookAtPoint(...) 确保相机始终垂直下视标记中心;
- 最后通过 map.setFreeCameraOptions(camera) 应用更新后的相机状态。
以下是一个完整、可运行的示例代码(已适配最新 Mapbox GL JS v2.13+):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Animated Marker with Follow Camera</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.css" rel="stylesheet" />
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.js"></script>
<script>
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN'; // ? 替换为你的 token
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [0, 0],
zoom: 2,
// 启用自由相机模式(必须)
cooperativeGestures: true
});
// 创建红色标记
const marker = new mapboxgl.Marker({ color: '#F84C4C' });
function animateMarker(timestamp) {
const radius = 25; // 圆形路径半径(度)
// 动画逻辑:沿单位圆运动(经度/纬度随时间变化)
const lng = Math.cos(timestamp / 1000) * radius;
const lat = Math.sin(timestamp / 1000) * radius;
marker.setLngLat([lng, lat]);
marker.addTo(map); // 确保 marker 已添加(安全重复调用)
// 获取当前自由相机配置
const camera = map.getFreeCameraOptions();
const altitude = 4e6; // 相机高度(单位:米,约 4000 km,适合全球尺度)
// 将经纬度 + 高度转换为 Mercator 坐标(用于 camera.position)
camera.position = mapboxgl.MercatorCoordinate.fromLngLat(
{ lng, lat },
altitude
);
// 设置相机朝向:精确对准标记所在经纬度(俯视)
camera.lookAtPoint({ lng, lat });
// 应用更新后的相机参数
map.setFreeCameraOptions(camera);
// 继续下一帧
requestAnimationFrame(animateMarker);
}
// 启动动画
requestAnimationFrame(animateMarker);
</script>
</body>
</html>✅ 关键注意事项:
- ✅ 必须使用 mapbox-gl-js >= v2.12,且启用 cooperativeGestures: true(否则自由相机可能被手势中断);
- ✅ camera.position 必须使用 MercatorCoordinate.fromLngLat(..., altitude) 构造,不能直接传入 [lng, lat] 数组;
- ✅ lookAtPoint 接收的是地理坐标 {lng, lat},而非 Mercator 坐标,务必保持类型一致;
- ✅ 若需更自然的跟随(如缓动、偏移视角),可引入 lerp 插值或 map.flyTo() 辅助过渡,但本例采用硬跟随以保证实时性与稳定性;
- ⚠️ 免费版 Mapbox Token 有请求限制,请勿在生产环境暴露 token,建议配合代理或私有托管。
通过此方案,你不仅能实现平滑的标记路径动画,还能获得电影级的“航拍跟随”体验——无论是物流轨迹回放、设备移动模拟,还是地理叙事可视化,都具备极强的表达力与专业感。










