如何在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稍微改写了一下写法,道理都一样的,官方案例可以参考百度地图demo

自定义覆盖物实现分以下三步:

  • 定义构造函数并继承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 = document.createRange().createContextualFragment(template);
  const div = divFragment.querySelectorAll('.radar-box')[0];
  // 将div添加到覆盖物容器中
  map.getPanes().markerPane.appendChild(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._div.style.top = `${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 = document.createRange().createContextualFragment(template);
  const div = divFragment.querySelectorAll('.radar-box')[0];
  map.getPanes().markerPane.appendChild(div);
  this._div = div;
  return div;
 }

 draw() {
  // 根据地理坐标转换为像素坐标,并设置给容器
  const position = this._map.pointToOverlayPixel(this.point);
  this._div.style.left = `${position.x - this.size / 2}px`;
  this._div.style.top = `${position.y - this.size / 2}px`;
 }
}

自定义覆盖物的使用

那既然我们都已经实现了自定义的覆盖物,第一件事当然就是把它给使用上,具体如下:

  initMap() {
   const map = new BMap.Map(this.$refs.map);
   map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);
   // 实例化我们要绘制自定义覆盖物的点坐标
   const point = new BMap.Point(116.404, 39.915);
	// 实例化自定义覆盖物,将坐标点和水波纹的尺寸传进构造函数中
   const radar = new RadarOverlay(point, 40);
   // 添加自定义覆盖物
   map.addOverlay(radar);
  }

效果如图:

结语

至于构造自定义覆盖物的其他内容,大佬们如果要深入的话可以参考百度地图的文档,里面讲的肯定要比作者更加详细(狗头)。如果文章的内容有问题话的欢迎留言点出,希望能与各路大佬们交流交流,喜欢作者的文章的话也别忘了给我点个赞,这对我来说很重要。

源码地址:https://gitee.com/zhao_jiahao/baidu-map-custom-cover

到此这篇关于如何在vue中使用百度地图添加自定义覆盖物(水波纹)的文章就介绍到这了,更多相关vue用百度地图添加自定义覆盖物内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决vue项目打包上服务器显示404错误,本地没出错的问题

    1.使用脚手架搭建一个vue项目 2.运行,在本地运行没问题,接着打包上服务器,遇到404的错误,如下 这是webpack打包的结果,解决办法如下 1.修改build文件夹下的utils.js文件,大约在51行添加 publicPath:"../../" if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader', publicPath:&quo

  • vue实现在线预览pdf文件和下载(pdf.js)

    最近做项目遇到在线预览和下载pdf文件,试了多种pdf插件,例如jquery.media.js(ie无法直接浏览) 最后选择了pdf.js插件(兼容ie10及以上.谷歌.安卓,苹果) 强烈推荐改插件,以下介绍用法 (1)下载插件 下载路径: pdf.js (2)将下载构建后的插件放到文件中public(vue/cli 3.0) (3)在vue文件中直接使用,贴上完整代码 <template> <div class="wrap"> <iframe :src=

  • vue项目打包后请求地址错误/打包后跨域操作

    vue项目 npm run dev时跨域请求正常,但是打包后请求地址就错误(请求地址不存在),请求不到数据. 在vue项目中常用的是proxyTable代理跨域,这个用起来比较方便,但是当项目打包后就遇到这个问题了. 解决办法如下: 打开config文件夹下的index.js文件,添加以下代码 pathRewrite: { '^api':'https://*****.com' //填写需要跨域的地址 } 2.配置开发环境地址,就是config文件夹下的dev.env.js文件,添加以下代码: '

  • 解决vue-pdf查看pdf文件及打印乱码的问题

    前言 vue中简单使用vue-pdf预览pdf文件,解决打印预览乱码问题 vue-pdf 使用 安装 npm install --save vue-pdf 引入 import pdf from "vue-pdf 自定义封装pdf预览组件 <template> <el-dialog :visible.sync="pdfDialog" :close-on-click-modal="false" :show-close="false&

  • vue实现打印功能的两种方法

    第一种方法:通过npm 安装插件 1,安装  npm install vue-print-nb --save 2,引入  安装好以后在main.js文件中引入 import Print from 'vue-print-nb' Vue.use(Print); //注册 3,现在就可以使用了 <div id="printTest" > <p>锄禾日当午</p> <p>汗滴禾下土 </p> <p>谁知盘中餐</p&

  • 如何在vue中使用百度地图添加自定义覆盖物(水波纹)

    简介 一如既往,我来给大家分享一个项目中遇到的比较有意思的需求并介绍一下相应的实现过程. 话不多说,直接上图: 具体的应用场景简而言之就是需要我们在地图上添加如图中所示的自定义覆盖物.实现的过程作者分为以下两点给大家介绍介绍. 水波紋的实现 自定义覆盖物的实现 水波紋的实现 这个需求的实现肯定是离不开我们自己写自定义覆盖物的,那么首先我们来讨论一下水波纹动画的实现. 首先我们可以看到图中的覆盖物是由一个红心和水波紋组成,其中红心是固定不动的,那么我们可以直接这么写: <div class="

  • vue中调用百度地图获取经纬度的实现

    项目中,需要实现获取当前位置的经纬度,或者搜索某个位置并获取经纬度信息,我使用的的是vue,地图使用的是百度地图. 默认自动获取当前位置经纬度 拖动小红标 获取经纬度 关键词 查询获取经纬度 前期准备 首先,我们需要取百度官方申请一个地图api秘钥,https://lbsyun.baidu.com/apiconsole/key 进入后在应用管理,我的应用去申请即可. 申请好以后,我们打开vue项目中public文件下的index.html文件,拼接百度AK值并引入 <script type=&quo

  • 如何在vue项目中使用百度地图API

    目录 1.在百度地图开放平台注册账号并登录 2.选择自己所需的地图版本: 3.在我们的vue项目中的public文件夹下的index.html中引入并记得替换上你的ak(这个ak不是其他的ak哈) 4.之后就可以随处使用我们的百度地图了: 5.标记点的添加并拥有点击弹窗效果: 6.为坐标点添加文本标记: 1.在百度地图开放平台注册账号并登录 网址:http://lbsyun.baidu.com/index.php?title=jspopularGL 2.选择自己所需的地图版本: 我个人使用2.0

  • 详解vue在项目中使用百度地图

    第一步,去百度地图开发者申请秘钥. 第二步在项目中引入,具体如下 其中index.html存放地图链接,代码如下 然后在APP.vue里面实现,代码如下 <template> <div id="app"> <div id="allmap" ref="allmap"></div> <router-view></router-view> </div> </tem

  • vue项目中使用百度地图的方法

    1.在百度地图申请密钥: http://lbsyun.baidu.com/  将 <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=密钥" ></script> 中的 密钥替换成你申请的,在 vue项目的index.html引用. 2. 在build 文件下下的 webpack.base.conf.js贴入代码 externals: {

  • 详解vue项目中调用百度地图API使用方法

    步骤一:申请百度地图密钥: JavaScript API v1.4以及以前的版本无序申请秘钥(ak),自v1.5版本开始需要先申请秘钥(ak),才可以使用,如需获取更高的配额,需要申请  认证企业用户.百度地图API 链接地址:http://lbsyun.baidu.com/apiconsole/key 步骤二:在index.html中添加百度地图JavaScript API接口: <script src="http://api.map.baidu.com/api?v=1.4"

  • 2种在vue项目中使用百度地图的简单方法

    地图在项目中用得很多,最近也用了几次,好长时间不用都记不清了,闲暇时整理了vue里使用百度地图的2种方法,方便自己查看,也分享给大家,希望可以帮助有需要的人. 普遍的方法是: 1.index.html 中引入 <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密钥"></script> 2.新建个组件maps 注意 :不要把组件命名为

  • Vue项目引用百度地图并实现搜索定位等功能(案例分析)

    目录 一.效果图及功能点 二.前期准备 三.引入百度地图 四.功能解析 本文给大家介绍如何在vue项目中引用百度地图,并设计实现简单的地图定位.地址搜索功能. Tip:本篇文章为案例分析,技术点较多,所以篇幅较长,认真阅览的你一定会学到很多知识. 前言:百度地图开放平台 给开发者们提供了丰富的地图功能与服务,使我们的项目中可以轻松地实现地图定位.地址搜索.路线导航等功能.本文给大家介绍如何在vue项目中引用百度地图,并设计实现简单的地图定位.地址搜索功能. 一.效果图及功能点 先来看一下效果图

  • 浅谈Vue下使用百度地图的简易方法

    Vue下使用百度地图的简易方法,分享给大家,具体如下: 最近的项目里面,需要用到将具体地址转换成百度坐标系的经纬度,需求比较简单,所以就没有采用GitHub里面的百度Vue插件. 废话不说,直接贴出代码: 引入:在需要用到百度地图的组件里面直接引入 export default { methods: { loadBMapScript () { let script = document.createElement('script'); script.src = 'http://api.map.b

  • vue用BMap百度地图实现即时搜索功能

    本文实例为大家分享了vue用BMap百度地图实现即时搜索功能的具体代码,供大家参考,具体内容如下 功能如下: 搜索框搜索---自动下拉---点击数据---数据显示在搜索框里---点击新增--数据显示在下方--点击删除--删除当前 代码: 首先去百度开发者申请一个key 然后将key引入到项目的 index.html: <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak

随机推荐