最终效果总览,文章末尾git仓库
1、自定义标点
2、标点有波纹动画
3、点击标点有不同的弹框
技术栈
vue3,ts,less
需求
UI图↓
1、图标自定义
2、图标波纹动画
3、点击图标弹出相关信息
需求分析
1、为什么适用百度地图?
业务是为某区域做安全预警,整套系统都适用百度的经纬度,因此为图方便直接适用百度地图,而不是echarts、高德等。
2、依赖百度地图的图标自定义文档、等
相关文档:百度地图的图标自定义文档
3、弃用百度地图的3D画面(虽然真的很好看),原因如下
相关文档:百度地图mapv
4、确定思路:将初始地图渲染出来,引入自定义图标,围绕图标用css画波纹,添加点击事件
5、为数据大屏需要,地图要改底色
参考
查阅了以下文档,提供了很大的帮助
卡夫卡的baby——CSS3 实现圆圈动态发光特效动画的制作
云端的幻影——百度地图添加自定义图标标注以及自定义动画效果
关键代码
无论是标点的波纹、还是点击事件的弹出框,都是通过对dom绑定自己的css样式实现。
其中抓取百度地图的dom废了一番功夫
本次需求因为有筛选项,所以points要先filter再遍历
index.vue
/**
* @method 为标点增加波纹
* tip:不加setTimeout的话,point.markers.domElement是null
*/
const addWaves = () => {
setTimeout(() => {
myPoints.filter((point: MyPoints) => {
if (current.type === 0) {
return true
} else {
return point.info.scene === current.type
}
}).forEach((point: MyPoints) => {
let divElement = document.createElement('div');
divElement.className = 'before';
let divElement2 = document.createElement('div');
divElement2.className = 'after';
point.markers.domElement.innerHtml = point.markers.domElement.childNodes[0];
point.markers.domElement.appendChild(divElement);
point.markers.domElement.appendChild(divElement2);
point.markers.domElement.className = '';
point.markers.domElement.className = `dot ${point.info?.color || ""}`;
point.markers.domElement.style.overflow = '';
point.markers.domElement.firstChild.style.position = 'relative';
point.markers.domElement.firstChild.style.zIndex = '5';
})
}, 1000);
}
/**
* @method 刷新标点
*/
const initPoints = () => {
myPoints.filter((point: MyPoints) => {
if (current.type === 0) {
return true
} else {
return point.info.scene === current.type
}
}).forEach((point: MyPoints) => {
const pt = new BMapGL.Point(point.lng, point.lat);
const myIcon = new BMapGL.Icon(
pointDist[point.info.urgency]["point"],
new BMapGL.Size(22, 22)
);
const markers = new BMapGL.Marker(pt, { icon: myIcon });
// 点击事件
markers.addEventListener("click", () => {
//创建信息窗口
const sContent = `<div class='infoBox'>
<div>设备编号:设备编号</div>
<div>设备名称:设备名称</div>
<div>设备类型:设备类型</div>
<div>设备地址:设备地址</div>
<div>告警时间:告警时间</div>
</div>`;
var opts = {
width: 180,
title: `<div class='placebox'>${point.info?.urgencyLabel || ''}</div>`,
offset: new BMapGL.Size(120, 125),
customContent: sContent,
enableMessage: false,
};
current.bgColor = point.info?.color || "gray"
const infoWindow = new BMapGL.InfoWindow(sContent, opts);
infoWindow.setStyle;
markers.openInfoWindow(infoWindow);
// 根据情况配置不同的背景
nextTick(() => {
const BMap_bubble_pop: any = document.getElementsByClassName('BMap_bubble_pop')[0]
if (BMap_bubble_pop) {
BMap_bubble_pop.className = `BMap_bubble_pop set-${current.bgColor}-bg`
} else {
// 第一次dom未创建完毕,用settimeout延迟取
setTimeout(() => {
document.getElementsByClassName('BMap_bubble_pop')[0].className = `BMap_bubble_pop set-${current.bgColor}-bg`
}, 200)
}
})
});
point.markers = markers
map.addOverlay(markers);
});
}
index.less
@width: 22px;
@height: 22px;
@orange: orange;
@gray: gray;
@red: red;
.dot {
display: block;
width: @width;
height: @height;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: 50;
&>.before{
width: 100%;
height: 100%;
border-radius: 50%;
position: absolute;
top: 0px;
left: 0px;
&::after{
content: '';
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
opacity: 0.7;
animation: scale 1s infinite cubic-bezier(0,0,0.49,1.02);
}
}
&>.after{
width: 100%;
height: 100%;
opacity: 0.4;
border-radius: 50%;
position: absolute;
top: 0px;
left: 0px;
animation: scales 1s infinite cubic-bezier(0,0,0.49,1.02);
}
&:hover {
z-index: 100;
}
&>div {
z-index: 3;
top: 0;
left: 0;
}
}
.orange {
&>.before::after {
background-color: @orange;
}
&>.after {
background-color: @orange;
}
}
git 地址
如果对您有帮助,请给我点个赞/给git仓库点个收藏,谢谢(比心)