一直以来都是用new Amap.Circle结合api文档的方法实现水波纹效果,今天研究下项目代码,发现有前辈居然用css实现了这种功能。赶紧抄下来学以致用一下。
请根据实际情况慎重使用
效果如图:
废话不说上代码
// 地图初始化
mapInit() {
this.screenMap = new AMap.Map("map-container");
this.screenMap.on("complete", () => {
this.addMarkers(mockData)
});
}
// 添加覆盖物
addMarkers(_data = []) {
let markerData = [];
let height = 2, count = 0;
_data.forEach(e => {
if (count !== e.count * 1) {
height += 0.4; // 根据数量设置波纹高度
count = e.count * 1;
}
markerData.push({
position: e.position,
content: `
<div
class="circle-marker-content"
>
<span class="item_count" >${e.count}</span>
<div class="item item1"
style='
height:${height}vh;
width:${height}vh;
'></div>
<div class="item item2" style='
height:${height}vh;
width:${height}vh;
'></div>
<div class="item item3" style='
height:${height}vh;
width:${height}vh;
'></div>
<div class="item item4" style='
height:${height}vh;
width:${height}vh;
'></div>
<div class="item item5" style='
height:${height}vh;
width:${height}vh;
'></div>
</div>`,
})
})
for (let i = 0; i < markerData.length; i++) {
let marker = new AMap.Marker(markerData[i]);
this.screenMap.add(marker)
}
},
设置五个div元素类名命名为item,主要在before设置动画效果
// 模拟数据
let mockData = [{
"count": "100",
"position": [113.280637,23.125178]
}, {
"count": "67",
"position": [113.122717,23.02876]
}, {
"count": "43",
"position": [113.382391,22.52111]
}, {
"count": "18",
"position": [109.508268,18.24787]
}, {
"count": "25",
"position": [110.919229,21.65975]
},
{"count": "59",
"position": [106.616285,23.897742]
}
]
<div>
<div id="map-container"></div>
</div>
...
...
<style lang="less">
@circleColor: #4196ff;
#map-container {
width: 100%;
height: 78vh;
}
.amap-marker {
.amap-marker-content {
position: relative;
.circle-marker-content {
position: absolute;
top: 50%;
left: 50%;
height: 1.8vh;
width: 1.8vh;
transform: translate(-50%, -50%);
border-radius: 100%;
text-align: center;
background: @circleColor;
border: 1px solid @circleColor;
box-shadow: 0px 0px 14px @circleColor;
.item_count {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #1C77C3;
font-weight: bold;
font-size: 13px;
z-index: 10;
}
@keyframes scaless {
0% {
transform: scale(0);
opacity: 1;
}
100% {
transform: scale(2);
opacity: 0;
}
}
.item {
width: 100%;
height: 100%;
position: absolute;
border-radius: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.item:before {
content: "";
position: absolute;
left: -1px;
top: -1px;
display: inline-block;
width: 100%;
height: 100%;
border: 1px solid @circleColor;
border-radius: 100%;
opacity: 0;
background-color: @circleColor;
animation: scaless 5s infinite cubic-bezier(0, 0, 0.49, 1.02);
}
.item1:before {
animation-delay: 0s;
}
.item2:before {
animation-delay: 1s;
}
.item3:before {
animation-delay: 2s;
}
.item4:before {
animation-delay: 3s;
}
.item5::before {
animation-delay: 4s;
}
}
}
}
</style>
一般能用css解决的就不用js啦,毕竟性能能优化很多。研究了一下发现,其实就是利用css动画的圆点扩散效果来实现,cubic-bezier函数来缓慢过渡。css真是博大精深🚬