
本文介绍如何在 mapbox gl js 中结合标记动画与自由相机路径,实现摄像机始终居中并垂直俯视移动中的标记,达到“镜头跟随”效果。核心在于动态同步相机位置与标记经纬度,并利用 `setfreecameraoptions` 实时更新视角。
在 Mapbox GL JS 中,默认的 flyTo 或 jumpTo 无法满足持续、平滑的“镜头跟随”需求;而自由相机(Free Camera)模式提供了对视角的完全控制能力——这正是实现标记跟踪的关键。本方案不依赖地图的“锁定中心点”逻辑,而是通过 requestAnimationFrame 在每一帧中主动将相机定位到标记正上方,并朝向其坐标,从而构建出稳定、可定制的跟随体验。
核心实现逻辑
- 标记动画:使用 marker.setLngLat() 按时间函数(如正弦/余弦)更新位置;
-
相机同步:
- 使用 mapboxgl.MercatorCoordinate.fromLngLat() 将经纬度+高度转换为三维空间坐标(必需,因自由相机使用墨卡托坐标系);
- 设置 camera.position 为标记正上方(相同经纬度 + 固定海拔高度);
- 调用 camera.lookAtPoint() 确保镜头精确对准标记位置;
- 实时应用:每帧调用 map.setFreeCameraOptions(camera) 更新视图。
以下为完整可运行示例(已适配 Mapbox GL JS v2.13+):
Mapbox 跟随动画标记
注意事项与优化建议
- ✅ 高度设置关键:altitude 值直接影响视野范围和跟随稳定性。过低会导致镜头“贴地”,过高则缩小标记视觉尺寸;建议根据地图缩放等级动态调整(例如 altitude = 2000000 * Math.pow(2, 12 - map.getZoom()));
- ✅ 性能保障:避免在 animateMarker 中重复创建 MercatorCoordinate 或 lookAtPoint 对象;上述代码已采用复用方式;
- ⚠️ 标记 _lngLat 是私有属性:虽然当前版本可用,但官方不承诺长期支持。更健壮的做法是自行维护一个 currentPosition = { lng, lat } 变量,并在 setLngLat 后同步更新它;
- ? 兼容性:自由相机功能要求 Mapbox GL JS ≥ v2.9.0,且仅适用于 style 加载完成之后(确保 map.on('load', ...) 内启动动画更稳妥);
- ? 暂停/重置控制:可通过 cancelAnimationFrame() 和状态标志添加播放/暂停按钮,便于调试或交互增强。
通过以上方法,你不仅能实现流畅的标记移动,更能获得电影级的“航拍跟拍”视角——这是构建物流追踪、车辆监控、游戏化地理应用等场景的理想基础。










