插件git地址为 github.com/spiritJun/T…
demo的git地址为 github.com/spiritJun/t…
场景:
(在上面两篇文章之后呢迎来了这个比较有意思的动画类emmm)在上述文章中在高德地图实例加载完毕之后并且轨迹纠偏画线之后的操作,在这个时候其实小车已经出现在了我们的视图当中因为在画线结束的时候小车就出来了
需要思考的问题:
1.还是承接上面的问题谁也无法控制后端什么时候返回数据,所以小车移动的时候也要控制小车跑的是哪一段的路程,跟上述轨迹纠偏之后的数组一一对应上,但是此时小车移动的时候是需要一个二维数组并且格式并不是纠偏之后的格式格式为:[[116.478935,39.997761]]
2.只有在小车跑完的时候才需要特殊处理新画线的部分让小车继续跑这个时候之前的跑过去的索引就派上了大用场可以通过它过滤数据并且小车移动的时候不对数据进行操作的时候会减轻浏览器不少压力
轨迹动画中的实现思路:
1.在工厂类中将画线实例对象传递并进行存储这一步很重要因为画线与小车移动需要单独解耦因为后端数据来了就要纠偏画线这不能耽误还需要单独配置全局变量小车是否停止、小车跑到了哪一段的页码变量、以及初始化小车移动之后的画线部分
2.单独处理画线类中的小车纠偏之后的数据并对其进行二维数据处理,并且对小车也就是Marker类执行moveAlong事件并且传入二维数据以及对小车进行moving监听并且设置小车正在移动的变量并且监听movealong事件,此事件是在小车移动结束后触发此时我们需要重新对当前页码和画线的数据进行数据过滤以及重新执行小车的moveAlong事件
因为我的项目中有实时动态轨迹以及历史轨迹的所以有一些特殊的业务校验,此类中的props以及向外抛出的__proto__事件中是如下图所示
代码如下所示,因为太长我就压缩了
/** * 轨迹回放或者播放功能 * 轨迹动画类 * props ==>{ * map -- 当前地图的实例 * AMap --高德地图的构造函数 * historyLineInstance --轨迹的实例对象需要传参 继承初始化轨迹实例没有意义 * isRealTime --是否是实时轨迹 如果是的话 需要把画线方法放开以及动态画线等等 * strokeObj --线的样式一坨 * } * __proto__ ==>{ * reStartAnimation --重新播放轨迹回放 * addRedressRunning --轨迹新增之后调用方法 判断小车是否在跑 如果在跑就特殊处理 * } */export default class TrackReplay { constructor(props) { this.props = { ...props }; // console.log(this.props); this.FatherInstance = this.props.historyLineInstance;//取自WriteHistoryLine类 this.currentMarkerBox = this.FatherInstance.currentMarkerBox; this.renderPageNo = 0;//默认从1开始跑车 跟父类的deepNum 相对应 这样数据就可以对的上了 this.isCarDrivingEnd = false;//默认小车是非静止状态 this.passedPolyline = null; this._init();//使用监听的方法实现轨迹回放和实时轨迹 } _init () { let initRuningArr = this._parseLine(this.FatherInstance.historyAfterRedress); this._renderLineAndAnimate(initRuningArr); } _initPolyLine () { let strokeObj = this.props.strokeObj || { strokeColor: "#28F", //线颜色 strokeOpacity: 0.8, //线透明度 strokeWeight: 5, //线宽 strokeStyle: "solid", //线样式 lineJoin: "round", zIndex: 70, strokeDasharray: [10, 5] //补充线样式 } this.passedPolyline = new this.props.AMap.Polyline({ map: this.props.map, ...strokeObj }); } //每次推送或者初始化有轨迹之后的渲染 _renderLineAndAnimate (runingArr) { //先取到纠偏完的数据 每次先从父类里取数据 并且记录当前的滑动的数据 this.props.isRealTime && this._initPolyLine(); this.currentMarkerBox.on('moving', (e) => { if (this.isCarDrivingEnd) this.isCarDrivingEnd = false; // this.props.map.setFitView(); this.props.isRealTime && this.passedPolyline.setPath(e.passedPath); }); //这个才是真真正正的结束完事儿后的事件儿啊 this.currentMarkerBox.on('movealong', (e) => { //明天问下吧还是 this.isCarDrivingEnd = true; this._commonRunningFn(); }); this.currentMarkerBox.moveAlong(runingArr, 10000); } //处理公共方法 _commonRunningFn () { let addRedressArr = this.FatherInstance.historyAfterRedress.filter((item, index, arr) => { console.log(this.renderPageNo) return index + 1 > this.renderPageNo; }); if (addRedressArr.length > 0) { this.props.isRealTime && this._initPolyLine(); let addRedressLines = this._parseLine(addRedressArr); setTimeout(() => { this.currentMarkerBox.moveAlong(addRedressLines, 10000); }, 100) } } //新增了轨迹之后都调一下此方法 addRedressRunning () { //如果小车没在跑的话 就特殊处理一下 console.log(this.isCarDrivingEnd); if (this.isCarDrivingEnd) { this._commonRunningFn(); } } //重新播放轨迹回放 reStartAnimation () { this.renderPageNo = 0; // this.passedPolyline.setOptions({strokeColor:"#28F"}) // this.passedPolyline.setPath(new Array()); this.currentMarkerBox.moveAlong(this._parseLine(this.FatherInstance.historyAfterRedress), 10000); // setTimeout(()=>{ // this.currentMarkerBox.moveAlong(this._parseLine(this.FatherInstance.historyAfterRedress),60); // },500) } /* 特殊处理一下纠偏后的轨迹这块儿 因为moveAlone要的数据格式是 [[116.478935,39.997761]] 但是纠偏完的数据格式是[{1:[{x,y} 500条]}] */ _parseLine (historyAfterRedress = []) { let arr = []; for (let i = 0; i < historyAfterRedress.length; i++) { let item = historyAfterRedress[i][this.renderPageNo + 1]; this.renderPageNo += 1; if (item.length) { for (let k = 0; k < item.length; k++) { arr.push([item[k].x, item[k].y]) } } else { continue; } } return arr; }}