• 【出人意料】一种基于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>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160

    5、思考

    1. 做功能时,尽量使用已有的功能,借助基础力量达到四两拨千斤的作用;
    2. 多思考Vue2的框架的特点,结合特点进行使用。
  • 相关阅读:
    【Qt】QGroundControl入门4:框架QGCApplication
    Windows NodeJS 二进制文件安装
    顺丰2023秋招笔试 第二题(C++ 二叉树思想)
    基于JAVA视频点播系统设计与实现 开题报告
    你是如何使用背景和文本属性的呢 ,如果还不太熟悉的话可以来看看我的喔。
    使用tkinter开发GUI程序5 -- tkinter常见控件的特征属性(第三部分)
    这几个数据分析项目,让我看到了什么才叫专业!!
    认识和使用容器
    【MySQL性能优化系列】select count(*)走二级索引比主键索引快几百倍,你敢信?
    Solon2 分布式事件总线的技术价值?
  • 原文地址:https://blog.csdn.net/qq_40657528/article/details/127894901