📌 学习目标
- 掌握点击符号时居中地图的实现方法
- 理解相关API的使用
- 能够独立完成类似功能开发
MapLibre GL JS 从入门到精通 - 130+实战案例
🎯 核心概念
点击符号时将地图居中到该符号位置。
💻 完 整 代 码
代码示例
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [-90.96, -0.47],
zoom: 7.5
});
map.on('load', async () => {
// 添加图像作为自定义标记
const image = await map.loadImage('https://maplibre.org/maplibre-gl-js/docs/assets/custom_marker.png');
map.addImage('custom-marker', image.data);
// 添加包含3个点的GeoJSON源。
map.addSource('points', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': [
-91.395263671875,
-0.9145729757782163
]
}
},
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': [
-90.32958984375,
-0.6344474832838974
]
}
},
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': [
-91.34033203125,
0.01647949196029245
]
}
}
]
}
});
// 添加符号图层
map.addLayer({
'id': 'symbols',
'type': 'symbol',
'source': 'points',
'layout': {
'icon-image': 'custom-marker'
}
});
// 当点击'symbols'图层中的任何符号时,将地图居中到该符号的坐标。
map.on('click', 'symbols', (e) => {
map.flyTo({
center: e.features[0].geometry.coordinates
});
});
// 当鼠标进入'symbols'图层中的要素时,将光标更改为指针。
map.on('mouseenter', 'symbols', () => {
map.getCanvas().style.cursor = 'pointer';
});
// 当鼠标离开时,将其改回默认光标。
map.on('mouseleave', 'symbols', () => {
map.getCanvas().style.cursor = '';
});
});
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<title>Center the map on a clicked symbol</title>
<meta property="og:description" content="使用事件和 flyTo 将地图居中在符号上。" />
<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: [-90.96, -0.47],
zoom: 7.5
});
map.on('load', async () => {
// 添加图像作为自定义标记
const image = await map.loadImage('https://maplibre.org/maplibre-gl-js/docs/assets/custom_marker.png');
map.addImage('custom-marker', image.data);
// 添加包含3个点的GeoJSON源。
map.addSource('points', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': [
-91.395263671875,
-0.9145729757782163
]
}
},
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': [
-90.32958984375,
-0.6344474832838974
]
}
},
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': [
-91.34033203125,
0.01647949196029245
]
}
}
]
}
});
// 添加符号图层
map.addLayer({
'id': 'symbols',
'type': 'symbol',
'source': 'points',
'layout': {
'icon-image': 'custom-marker'
}
});
// 当点击'ssymbols'图层中的任何符号时,将地图居中到该符号的坐标。
map.on('click', 'symbols', (e) => {
map.flyTo({
center: e.features[0].geometry.coordinates
});
});
// 当鼠标进入'ssymbols'图层中的要素时,将光标更改为指针。
map.on('mouseenter', 'symbols', () => {
map.getCanvas().style.cursor = 'pointer';
});
// 当鼠标离开时,将其改回默认光标。
map.on('mouseleave', 'symbols', () => {
map.getCanvas().style.cursor = '';
});
});
</script>
</body>
</html>
🔍 代码解析
1. 初始化地图
使用 new maplibregl.Map() 创建地图实例,配置厄瓜多尔区域作为初始视图。
2. 关键配置项
- map.loadImage(): 异步加载自定义标记图像
- map.addImage(): 将图像添加到地图作为图标使用
- map.flyTo(): 平滑飞到目标位置
- mouseenter/mouseleave: 鼠标交互改变光标样式
⚙️ 参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| center | [number, number] | 是 | flyTo目标中心点 |
| essential | boolean | 否 | 动画是否必要,默认false |
🎨 效果说明

运行代码后,地图显示厄瓜多尔区域,包含3个标记点。鼠标悬停在标记上时光标变为指针,点击任意标记,地图会以平滑飞行动画居中到该标记位置。
💡 常 见 问 题
Q1: 点击标记没有反应?
A: 检查以下几点:
- 确认图层已正确添加
map.addLayer() - 确认事件监听器绑定在正确的图层ID上
- 检查浏览器控制台是否有错误
Q2: 飞行动画可以自定义吗?
A: 可以,flyTo支持speed、curve等参数控制动画效果:
map.flyTo({
center: coordinates,
speed: 2,
curve: 1.5
});
Q3: 如何禁止飞行动画瞬间跳转?
A: 不调用flyTo而使用setCenter即可瞬间跳转:
map.setCenter(coordinates);
📝 练习任务
- 基础练习:修改GeoJSON数据中的坐标,添加更多标记点
- 进阶挑战:为飞行添加缩放和旋转效果
- 拓展思考:如何在飞行动画过程中显示进度?
- 综合实践:创建一个点击跳转的地图导览功能
🌟 最佳实践
- 动画平滑: 使用flyTo替代setCenter提供更好的用户体验
- 视觉反馈: 鼠标悬停时改变光标提示可点击
- 性能考虑: 避免频繁触发飞行动画
- 中止处理: 新飞行请求应中止当前动画
- 无障碍: 考虑提供键盘导航支持
🔗 延伸阅读
-
[下一课预告]:将继续学习地图图层的基础知识
本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏
171



被折叠的 条评论
为什么被折叠?



