如何在vue中使⽤百度地图添加⾃定义覆盖物(⽔波纹)简介
⼀如既往,我来给⼤家分享⼀个项⽬中遇到的⽐较有意思的需求并介绍⼀下相应的实现过程。
话不多说,直接上图:
具体的应⽤场景简⽽⾔之就是需要我们在地图上添加如图中所⽰的⾃定义覆盖物。实现的过程作者分为以下两点给⼤家介绍介绍。
⽔波紋的实现
⾃定义覆盖物的实现
⽔波紋的实现
这个需求的实现肯定是离不开我们⾃⼰写⾃定义覆盖物的,那么⾸先我们来讨论⼀下⽔波纹动画的实现。
⾸先我们可以看到图中的覆盖物是由⼀个红⼼和⽔波紋组成,其中红⼼是固定不动的,那么我们可以直接这么写:
<div class="radar"></div>
.radar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: red;
}
这样⼦我们⾸先就实现了红⼼部分的样式。那么⽔波紋⼜是怎么实现的呢?
我们可以从图中观察得出先后总共有三个⽔波紋从⾥到外逐渐的往外扩散。我们单独从⼀个⽔波紋来看的话,其实往外扩散的原理是通过动画让⽔波紋的宽⾼逐渐递增到⼀定程度即可,具体扩散多⼤呢读者可以根据⾃⼰的需求设定⽔波紋的最后宽⾼。
⽔波紋的基本结构和样式实现如下:
<div class="radar">
<div class="ripple"></div>
<div class="ripple"></div>
<div class="ripple"></div>
</div>
.radar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: red;
position: relative;
.
ripple {
width: 40px;
height: 40px;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
border: 1px solid red;
animation: ripple 2s linear infinite;
}
}
之所以将⽔波紋的dom节点嵌套在radar节点⾥⾯主要是做⼀个“⼦绝⽗相”定位以达到⽔波紋居中对齐的效果,这个应该很容易理解。⾄于⽔波紋的初始宽⾼呢,为了⽅便动画延迟时间的计算,我就设置为跟红⼼宽⾼相等即可,如果读者有兴趣可以尝试⼀下宽⾼设置在0~40px任意值的看看效果(作者盲猜动画可能会有点瑕疵,可能也不会------>“⼿动狗头”))。
⾄于动画的实现呢,这个就很简单了,我们只需要同时将⽔波紋的宽⾼都逐渐变⼤即可,但是有个点要注意⼀下就是⽔波紋最后是会消失的,这⾥我们利⽤opacity:0配合动画达到逐渐消失的效果。
@keyframes ripple {
to {
width: 150px;
height: 150px;
opacity: 0;
}
}
代码到了这⾥,我们⽔波紋已经是实现了,但是不是少了点什么?说好的三个⽔波紋呢?
这个问题也很好解决,我们只需要给⽔波紋设置对应的动画延迟即可。
.radar :nth-child(1) {
animation-delay: 0.666s;
}
.radar :nth-child(2) {
animation-delay: 1.322s;
}
这样⼦我们就把⽔波紋给实现出来啦。
⾃定义覆盖物的实现
本次作者采⽤的是百度地图实现的需求,那么如何通过百度地图来实现⾃定义覆盖物呢?
其实百度地图开发⽂档中也很直⽩的向我们展⽰⾃定义覆盖物的开箱⽅法。这⾥作者⽤es6的class稍微改写了⼀下写法,道理都⼀样的,官⽅案例可以
⾃定义覆盖物实现分以下三步:
定义构造函数并继承Overlay
初始化⾃定义覆盖物
绘制覆盖物
定义构造函数并继承Overlay
按照官⽹的说法是:“⾸先您需要定义⾃定义覆盖物的构造函数,通过构造函数参数可以传递⼀些⾃由的变量。设置⾃定义覆盖物对象的prototype属性为Overlay的实例,以便继承覆盖物基类”。
运⽤es6 class我们可以很快的实现:
其中point传递的是坐标位置,⽤于后续计算覆盖物在地图上的位置。
class RadarOverlay extends BMap.Overlay {
constructor(point) {
super();
this.point = point;
}
}
初始化⾃定义覆盖物
官⽅的说法是:“实现initialize⽅法,当调⽤map.addOverlay⽅法时,API会调⽤此⽅法。当调⽤map.addOverlay⽅法添加⾃定义覆盖物时,API会调⽤该对象的initialize⽅法⽤来初始化覆盖物,在初始化过程中需要创建覆盖物所需要的DOM元素,并添加到地图相应的容器中。这⾥我们选择添加在容器markerPane上。”
其实意思⼤概就是说,因为百度地图在添加overLay时会调⽤⾃定义覆盖物构造函数中的initialize⽅法,
这个initialize⽅法是⽤来初始化覆盖物的,他会在初始化过程中创建所需要的DOM,因此我们要在我们⾃⼰的构造函数(这⾥我们⽤的是类)中实现⼀个initialize。
百度地图官⽹的⽅法:
那么我们就按照官⽹的要求,在类中定义⼀个initialize⽅法。其中template存的是我们初始化中所需要的DOM元素,这⾥的dom节点会⽐上⽂中实现⽔波纹的环节多了⼀个className为rader-box的⽗节点,因为在官⽹中我们也可以看到官⽅实例在创建DOM元素时给DOM节点添加了position:absolute的样式,但由于我们的radar节点的position为relative,所以我们需要在最外层多嵌套⼀层dom节点以确保整个dom相对于地图定位。当然啦该⽗节点的position也就为绝对定位
initialize(map) {
this._map = map;
const template = `<div class="radar-box">
<div class="radar">
<div class="ripple"></div>
<div class="ripple"></div>
<div class="ripple"></div>
</div>
</div>`;
// 创建⽂档碎⽚
const divFragment = ateRange().createContextualFragment(template);
const div = divFragment.querySelectorAll('.radar-box')[0];
// 将div添加到覆盖物容器中
this._div = div;
return div;
}
这样⼦我们就成功的在类中定义了⼀个initialize⽅法,⾄于为什么要将div添加到覆盖物容器中官⽹的也有如下说明:
⼤概就是说百度地图⾥⾯已经给我们提供了若⼲的覆盖物展⽰⽅法,我们⾃定义的覆盖物其实是保存在我们选择的其中某个覆盖物容器之下,有兴趣的⼩伙伴可以去了解⼀下各种覆盖物容器。。。
绘制覆盖物
这⾥作者继续抛砖引⽟阿,官⽅的说法是:“到⽬前为⽌,我们仅仅把覆盖物添加到了地图上,但是并没有将它放置在正确的位置上。您需要在draw⽅法中设置覆盖物的位置,每当地图状态发⽣变化(⽐如:位置移动、级别变化)时,API都会调⽤覆盖物的draw⽅法,⽤于重新计算覆盖物的位置。通过map.pointToOverlayPixel⽅法可以将地理坐标转换到覆盖物的所需要的像素坐标。”
简单来讲就是⽐如地图缩放⽐例之后,会重新调⽤覆盖物中的draw⽅法,⽤于重新鸡算覆盖物的位置。
那么问题来了,draw⽅法哪⾥来的?
所以官⽅的意思是我们在⾃定义覆盖物中的构造函数定义⼀个draw⽅法,⽅法中我们利⽤百度地图的
map.pointToOverlayPixel⽅法(⽤来将地理坐标转换为像素坐标)可以将地理坐标转换到覆盖物的所需要的像素坐标。
那么我们只需要在类中加⼊draw⽅法即可:
其中this.point就是我们构造函数中的point坐标点,40表⽰的是我们整个⽔波纹的初始宽⾼,读者其实可以将40改为可以传参的形式⽐如this.size,这样会⽅便后续代码的维护,这⾥为了直观的让读者理解就不讲太复杂了。
draw() {
// 根据地理坐标转换为像素坐标,并设置给容器
const position = this._map.pointToOverlayPixel(this.point);
this._div.style.left = `${position.x - 40 / 2}px`;
this._p = `${position.y - 40 / 2}px`;
}
到此,我们整个⾃定义覆盖物的类就已经实现了,整体代码图下(这⾥把40改为this.size代码维护起来稍微⽅便点):
class RadarOverlay extends BMap.Overlay {
constructor(point, size) {
super();
this.point = point;
this.size = size;
}
initialize(map) {
this._map = map;
const template = `<div class="radar-box">
<div class="radar">
<div class="ripple"></div>
<div class="ripple"></div>
<div class="ripple"></div>
</div>
</div>`;
const divFragment = ateRange().createContextualFragment(template);
const div = divFragment.querySelectorAll('.radar-box')[0];
border radius什么意思this._div = div;
return div;
}
draw() {
// 根据地理坐标转换为像素坐标,并设置给容器
const position = this._map.pointToOverlayPixel(this.point);
this._div.style.left = `${position.x - this.size / 2}px`;
this._p = `${position.y - this.size / 2}px`;
}
}
⾃定义覆盖物的使⽤
那既然我们都已经实现了⾃定义的覆盖物,第⼀件事当然就是把它给使⽤上,具体如下:
initMap() {
const map = new BMap.Map(this.$refs.map);
// 实例化我们要绘制⾃定义覆盖物的点坐标
const point = new BMap.Point(116.404, 39.915);
// 实例化⾃定义覆盖物,将坐标点和⽔波纹的尺⼨传进构造函数中
const radar = new RadarOverlay(point, 40);
// 添加⾃定义覆盖物
map.addOverlay(radar);
}
效果如图:
结语
⾄于构造⾃定义覆盖物的其他内容,⼤佬们如果要深⼊的话可以参考百度地图的⽂档,⾥⾯讲的肯定
要⽐作者更加详细(狗头)。如果⽂章的内容有问题话的欢迎留⾔点出,希望能与各路⼤佬们交流交流,喜欢作者的⽂章的话也别忘了给我点个赞,这对我来说很重要。
到此这篇关于如何在vue中使⽤百度地图添加⾃定义覆盖物(⽔波纹)的⽂章就介绍到这了,更多相关vue⽤百度地图添加⾃定义覆盖物内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论