【出人意料】一种基于Vue2监听器(watch)和定时器(setInterval)的轨迹播放方法实现方案

1、需求

数据库中有设备的经纬度记录,前端需要实现从数据库中取到数据后在地图上显示轨迹,显示轨迹的方式就是一个一个点地有序显示。点与点之间用线段连接,最终构成一条轨迹线。

2、场景过程

  1. 前端定义一个播放暂停按钮;
  2. 点击播放时,定时器开启;
  3. 播放阶段,每隔1秒打一个坐标锚点,超过1个点时,点与点之间进行线段连接;
  4. 点击暂停时,停止打点和绘制线段;
  5. 再点击播放时,接着上述暂停时的锚点继续开始新的坐标锚点绘制和线段绘制;
  6. 播放完数据,停止打点和线段绘制。

在这里插入图片描述

3、实现思路

旧的实现思路,采用定时器的开启、暂停来实现,找了相关资料,未发现有很好的例子。

基于Vue2,考虑到其带有监听器的功能,如果监听打点数的数值发生变化,就往地图上赛锚点和线段。岂不是一种简约的实现方式。

4、实现代码

<template>

  <div style="width: 100%; height: 100%">
    <!-- 工具条   -->
    <div class="map_box">
      <el-form :inline="true" :model="form">
          <el-button @click="onStart" :type=" isStart ? 'success':'primary'" >
            <svg-icon :icon-class="isStart ? 'stop':'start'" />
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 地图   -->
    <div class="amap-container">
      <el-amap view-mode="3D" :center="center" :zoom="zoom" map-style="amap://styles/d6bf8c1d69cea9f5c696185ad4ac4c86">

        <!--轨迹 -->
        <el-amap-polyline :editable="polyline.editable"
                          :visible="polyline.visible"
                          :stroke-weight="2"
                          :stroke-color="polyline.strokeColor"
                          :draggable="polyline.draggable"
                          :path="polyline.path"></el-amap-polyline>

        <!--标注 -->
        <el-amap-layer-labels>
          <el-amap-label-marker v-for="(marker, index) in markers"
                                :key="index"
                                :visible="true"
                                :position="marker.position"
                                :text="marker.text"
                                :icon="marker.icon"></el-amap-label-marker>
        </el-amap-layer-labels>

      </el-amap>
    </div>
  </div>

</template>

<script>

export default {
  data(){
    return{
      center: [105.602725,37.076636],
      zoom:5,
      pointData:[],
      markers:[],
      polyline:{
        editable: false,
        visible: false,
        draggable: false,
        path:[],
        strokeColor: "#f10303"
      },
      isStart: false,
      isPause: true,
      playTimer: null,
      playCount:1,
      playSpeed: 500
    }
  },
  created() {
  },
  methods:{
    getData(){
    //this.pointData数据源
    },
    //计时打点
    addMarker(){
      //只有一个点打点后结束
      if (this.isPause){
        let marker = this.pointData[this.playCount - 1]
        //锚点打点
        this.markers.push(marker)
        this.center = marker.position
        //轨迹打点
        this.polyline.path.push(marker.position)
        this.polyline.visible = true
        //缩放地图倍数
        this.zoom = 14
        this.isPause = false
      }

      if (this.pointData.length === 1){
        return false
      }
      //开启计时器
      if (this.pointData.length > 1){
        let that = this
        this.playTimer = setInterval(()=>{
          that.playCount++
        },this.playSpeed)
      }
    },
    onStart(){
      this.isStart = !this.isStart
      if (this.isStart){
      	//加载一次数据
        if (this.isPause){
          this.getData()
        }
        this.addMarker()
      }else {
        //清除计时器
        if (this.playCount <= this.pointData.length){
          clearInterval(this.playTimer)
          this.playTimer = null
          this.tableScroll()
        }
      }
    }
  },
  watch:{
    playCount: {
      handler(newValue, oldValue) {
      
        if (newValue > this.pointData.length) {
          clearInterval(this.playTimer)
          this.playTimer = null
          this.isPause = true
          
        } else {
          let position = this.pointData[newValue - 1].position
          this.markers.push(this.pointData[newValue - 1])
          this.polyline.path.push(position)
          this.center = position
        }
      }
    }
  }
}
</script>

<style  scoped>
/deep/ .amap-container{
  width: 100%;
  height: 100%;
  top: 0.5%;
  bottom: 0.5%;
  border-radius: 15px;
}
.map_box{
  position: absolute;
  top: 1.5%;
  right: 0.5%;
  z-index: 66666;
}

.table-class{
  position: absolute;
  top: 12%;
  right: 1%;
  z-index: 66666;
}

</style>


5、思考

  1. 做功能时,尽量使用已有的功能,借助基础力量达到四两拨千斤的作用;
  2. 多思考Vue2的框架的特点,结合特点进行使用。
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追寻上飞

鼓励一下这只勤劳的小蜜蜂吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值