8.0 KiB
8.0 KiB
点标记 (Markers)
高德地图 JSAPI v2.0 提供了多种类型的点标记,适用于不同的业务场景。
1. 基础点标记 (Marker)
最常用的点标记,支持自定义图标或 DOM 内容。
// 默认蓝色水滴图标
const marker = new AMap.Marker({
position: [116.397, 39.909], // 位置
icon: new AMap.Icon({
size: new AMap.Size(40, 50),
image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
imageSize: new AMap.Size(40, 50),
}),
title: '北京', // 鼠标悬停文本
});
map.add(marker);
// 自定义图标
const iconMarker = new AMap.Marker({
position: [116.397, 39.909],
icon: new AMap.Icon({
size: new AMap.Size(40, 50),
image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
imageSize: new AMap.Size(40, 50),
}),
offset: new AMap.Pixel(-20, -50), // 锚点偏移
});
// 自定义 DOM 内容 (灵活性最强,但性能消耗较高)
const contentMarker = new AMap.Marker({
position: [116.397, 39.909],
content: '<div class="custom-marker">我的标记</div>',
offset: new AMap.Pixel(-15, -15),
});
自定义图标样式
以下是几种常用的 Marker 样式,可直接复制使用。
带徽标的定位点
适用于用户头像、 Logo 等场景。
const marker = new AMap.Marker({
position: [116.397, 39.909],
content: `
<div class="avatar-marker">
<img src="https://example.com/avatar.jpg" alt="头像" />
<span class="status online"></span>
</div>
`,
offset: new AMap.Pixel(-20, -20),
});
.avatar-marker {
position: relative;
width: 40px;
height: 40px;
}
.avatar-marker img {
width: 40px;
height: 40px;
border-radius: 50%;
border: 2px solid #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
object-fit: cover;
}
.avatar-marker .status {
position: absolute;
bottom: 2px;
right: 2px;
width: 10px;
height: 10px;
border-radius: 50%;
border: 2px solid #fff;
}
.avatar-marker .status.online { background: #52c41a; }
.avatar-marker .status.offline { background: #999; }
.avatar-marker .status.busy { background: #f5222d; }
信息卡片式 Marker
适用于 POI 展示、信息等场景。
const marker = new AMap.Marker({
position: [116.397, 39.909],
content: `
<div class="card-marker">
<div class="card-content">
<span class="card-price">¥288</span>
<span class="card-unit">/晚</span>
</div>
<div class="card-arrow"></div>
</div>
`,
offset: new AMap.Pixel(-40, -52),
});
.card-marker {
position: relative;
cursor: pointer;
transition: transform 0.2s;
}
.card-marker:hover {
transform: scale(1.05);
}
.card-content {
background: #fff;
border-radius: 8px;
padding: 6px 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
white-space: nowrap;
}
.card-price {
font-size: 14px;
font-weight: 600;
color: #1890ff;
}
.card-unit {
font-size: 12px;
color: #999;
}
.card-arrow {
position: absolute;
bottom: -6px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #fff;
}
/* 选中状态 */
.card-marker.active .card-content {
background: #1890ff;
}
.card-marker.active .card-price,
.card-marker.active .card-unit {
color: #fff;
}
.card-marker.active .card-arrow {
border-top-color: #1890ff;
}
带数字序号的 Marker
适用于路线规划、排序展示等场景。
function createNumberMarker(number, isStart = false, isEnd = false) {
let bgColor = '#1890ff';
if (isStart) bgColor = '#52c41a';
if (isEnd) bgColor = '#f5222d';
return new AMap.Marker({
position: [116.397, 39.909],
content: `
<div class="number-marker" style="background: ${bgColor}">
<span>${number}</span>
</div>
`,
offset: new AMap.Pixel(-15, -15),
});
}
// 使用示例
const startMarker = createNumberMarker('起', true);
const endMarker = createNumberMarker('终', false, true);
const waypoint = createNumberMarker(1);
.number-marker {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 14px;
font-weight: 600;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
border: 2px solid #fff;
}
分类图标 Marker
适用于 POI 分类展示。
// 定义分类图标
const categoryIcons = {
restaurant: { icon: '🍽️', color: '#fa8c16' },
hotel: { icon: '🏨', color: '#1890ff' },
scenic: { icon: '🏞️', color: '#52c41a' },
shopping: { icon: '🛍️', color: '#eb2f96' },
hospital: { icon: '🏥', color: '#f5222d' },
};
function createCategoryMarker(category, name) {
const { icon, color } = categoryIcons[category] || { icon: '📍', color: '#1890ff' };
return new AMap.Marker({
position: [116.397, 39.909],
content: `
<div class="category-marker" style="--marker-color: ${color}">
<div class="marker-icon">${icon}</div>
<div class="marker-label">${name}</div>
<div class="marker-arrow"></div>
</div>
`,
offset: new AMap.Pixel(-50, -58),
});
}
// 使用示例
const restaurantMarker = createCategoryMarker('restaurant', '海底捞火锅');
.category-marker {
display: flex;
flex-direction: column;
align-items: center;
}
.marker-icon {
width: 36px;
height: 36px;
background: var(--marker-color);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
border: 2px solid #fff;
}
.marker-label {
margin-top: 4px;
padding: 2px 8px;
background: #fff;
border-radius: 4px;
font-size: 12px;
color: #333;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
white-space: nowrap;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
}
.marker-arrow {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #fff;
}
2. 带文字标记
const marker = new AMap.Marker({
position: [116.397, 39.909],
label: {
content: '北京天安门',
direction: 'top', // top, right, bottom, left, center
offset: new AMap.Pixel(0, -5),
},
});
2. 海量标注 (LabelMarker)
强烈推荐用于海量点位(千级/万级以上)展示。它是基于 WebGL 的矢量标注,支持文字和图标避让,性能极佳。
注意:必须配合
LabelsLayer图层使用。
// 1. 创建图层
const layer = new AMap.LabelsLayer({
zooms: [3, 20],
zIndex: 1000,
collision: true, // 开启碰撞避让
allowCollision: false, // 允许被避让隐藏
});
map.add(layer);
// 2. 创建 LabelMarker
const labelMarker = new AMap.LabelMarker({
position: [116.397, 39.909],
icon: {
type: 'image',
image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
size: [6, 10],
anchor: 'bottom-center',
},
text: {
content: '北京天安门',
direction: 'top',
style: {
fontSize: 12,
fillColor: '#fff',
strokeColor: '#000',
strokeWidth: 1,
}
}
});
// 3. 添加到图层
layer.add(labelMarker);
3. 灵活点标记 (ElasticMarker)
适用于随地图缩放需要动态改变样式或大小的场景。
const elasticMarker = new AMap.ElasticMarker({
position: [116.397, 39.909],
zooms: [14, 20],
styles: [{
icon: {
img: '...',
size: [16, 16],
ancher: [8, 16],
fitZoom: 14, // 适用于 zoom >= 14
scaleFactor: 2, // 缩放比例
}
}]
});
map.add(elasticMarker);
常用操作
marker.setPosition([lng, lat]); // 更新位置
marker.setMap(null); // 从地图移除
marker.hide(); // 隐藏
marker.show(); // 显示