📌 学习目标
- 掌握动画化标记的实现方法
- 理解相关API的使用
- 能够独立完成类似功能开发
🎯 核心概念
通过在每帧更新标记位置来动画化标记。
💻 完 整 代 码
<!DOCTYPE html>
<html lang="en">
<head>
<title>Animate a marker</title>
<meta property="og:description" content="通过在每一帧更新位置来动画化标记的位置。" />
<meta property="og:created" content="2006-06-25" />
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [0, 0],
zoom: 2
});
const marker = new maplibregl.Marker();
function animateMarker(timestamp) {
const radius = 20;
// 根据动画时间戳将数据更新到新位置。
// 表达式 `timestamp / 1000` 中的除数控制动画速度。
marker.setLngLat([
Math.cos(timestamp / 1000) * radius,
Math.sin(timestamp / 1000) * radius
]);
// 确保将其添加到地图。如果已经添加,调用此方法是安全的。
marker.addTo(map);
// 请求动画的下一帧。
requestAnimationFrame(animateMarker);
}
// 开始动画。
requestAnimationFrame(animateMarker);
</script>
</body>
</html>
🔍 代码解析
1. 初始化地图
使用 new maplibregl.Map() 创建地图实例,配置了以赤道为中心的全球视图。
2. 关键配置项
- requestAnimationFrame: 浏览器原生动画API,实现60fps流畅动画
- Math.cos/sin: 使用三角函数计算圆形运动轨迹
- timestamp: 动画时间戳,用于计算当前位置
- setLngLat(): 更新标记位置
⚙️ 参数说明
| radius | number | 是 | 圆形运动半径(度数) |
| speed | number | 是 | 动画速度控制(timestamp除数) |
| timestamp | number | 是 | requestAnimationFrame传入的时间戳 |
🎨 效果说明

运行代码后,地图显示全球视图,标记以20度为半径围绕地图中心(0, 0)做匀速圆周运动。动画平滑流畅,标记位置每帧更新一次。
💡 常 见 问 题
Q1: 动画不流畅? A: 检查以下几点:
Q2: 如何停止动画? A: 使用cancelAnimationFrame停止动画:
const animationId = requestAnimationFrame(animateMarker);
// 停止动画
cancelAnimationFrame(animationId);
Q3: 如何实现其他运动轨迹? A: 修改位置计算逻辑:
// 直线运动
marker.setLngLat([
startLng + (endLng – startLng) * progress,
startLat + (endLat – startLat) * progress
]);
// 椭圆运动
marker.setLngLat([
Math.cos(timestamp / 1000) * radiusX,
Math.sin(timestamp / 1000) * radiusY
]);
📝 练习任务
🌟 最佳实践
🔗 延伸阅读
-
Map API文档
-
MapLibre GL JS 官方文档
-
[下一课预告]:将继续学习地图图层的基础知识
本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏


