利用自定义标注实现头像展示
11/21/2025, 12:21:31 PM
#地图API#历史文章迁移
API:百度地图
官网:http://lbsyun.baidu.com/
遇到一个需求是往地图上添加人员的坐标点,但是点的展示要用头像。刚开始我是利用Marker类来进行设置,因为里面有个icon属性,具体类参考见:http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a3b5。我的代码如下:
// 设置图片
let myIcon = new BMap.Icon(imgUrl, new BMap.Size(50, 50)); // 设置图片和可视大小
myIcon.setImageSize(new BMap.Size(50, 50)); // 设置图片大小
myIcon.setAnchor(new BMap.Size(25, 60)) // 设置偏移
let imgMarker = new BMap.Marker(new BMap.Point(longitude, latitude), { icon: myIcon });
// 设置点
let pointMarker = new BMap.Marker(new BMap.Point(longitude, latitude), {
// 初始化圆点形状
icon: new BMap.Symbol(BMap_Symbol_SHAPE_CIRCLE, {
scale: 5,
strokeWeight: 1,
fillColor: 'red',
fillOpacity: 1,
})
});
// 把图片和点都加到地图里
map.addOverlay(imgMarker);
map.addOverlay(pointMarker);
然后我看到的效果图是这样的:

我寻思了一下这也确实有点丑,可是关于样式的设置,我在api里面没找到,强行调样式好像也没起效,终于我把目标瞄到了自定义标注(步骤和自定义控件类似,但是注意继承的类是不一样的,而且还有draw方法)。官网示例:http://lbsyun.baidu.com/jsdemo.htm#c1_11。
琢磨了半天时间,终于把思路捋清了。代码如下:
先把构造方法写好,由于我传参时只需要设置坐标点和图片路径,所以只在构造方法里面写了两个参数,可根据自己需求来。
// 头像覆盖物
function ComplexCustomOverlay(point, img) {
this._point = point;
this._img = img;
}
然后进行继承Overlay类,并进行初始化。样式都是自己用js写,可根据项目原型图进行调整,若觉得有需要也可直接复制下面我已经调好的。
// 人员头像的自定义标注
ComplexCustomOverlay.prototype = new BMap.Overlay();
ComplexCustomOverlay.prototype.initialize = function (map) {
this._map = map;
// 头像背景框
let div = this._div = document.createElement("div");
div.style.position = "absolute";
div.style.zIndex = BMap.Overlay.getZIndex(this._point.lat);
div.style.backgroundColor = "#1890ff";
div.style.height = "60px";
div.style.width = "60px";
div.style.borderRadius = "50%";
// 头像
let img = this._span = document.createElement("img");
div.appendChild(img);
img.src = this._img; // 设置图片路径
img.style.width = "50px";
img.style.height = "50px";
img.style.borderRadius = "50%";
img.style.display = "block";
img.style.margin = "5px auto";
// 箭头
let arrow = this._arrow = document.createElement("div");
arrow.style.position = "absolute";
arrow.style.top = "55px";
arrow.style.left = "18px";
arrow.style.overflow = "hidden";
arrow.style.border = "12px rgba(0, 0, 0, 0) solid";
arrow.style.borderTopColor = "#1890ff";
div.appendChild(arrow);
// 点击事件
div.onclick = function () {
}
// 添加到地图
map.getPanes().labelPane.appendChild(div);
return div;
}
注意把标签加入后还要自己进行覆盖物的绘制,也就是位置的调整,这个一般都是根据经纬度来的。而且上方div的位置和偏移也只能通过下面来调整:
// 根据经纬度绘制
ComplexCustomOverlay.prototype.draw = function () {
let map = this._map;
let pixel = map.pointToOverlayPixel(this._point);
this._div.style.left = pixel.x - 30 + "px";
this._div.style.top = pixel.y - 72 + "px";
}
接下来就是最后一步,千万别忘记调用。如果有很多个点,循环就行了。
// 创建人员的坐标点
locationList.length !== 0 && locationList.map((val, ind) => {
points.push(new BMap.Point(val.longitude, val.latitude));
if (val.imgUrl !== null) {
// 调用构造方法绘制头像并加入到地图
let myCompOverlay = new ComplexCustomOverlay(new BMap.Point(val.longitude, val.latitude), val.imgUrl);
map.addOverlay(myCompOverlay);
}
let marker = new BMap.Marker(new BMap.Point(val.longitude, val.latitude), {
// 初始化圆点形状
icon: new BMap.Symbol(BMap_Symbol_SHAPE_CIRCLE, {
scale: 5,
strokeWeight: 1,
fillColor: 'red',
fillOpacity: 1,
})
});
map.addOverlay(marker);
});
最后的效果图如下:

终于比之前好看多了,大功告成。