根據業務場景結合vue+iview在百度lushu的prototype中新增一些回調屬性如:_pauseCallback、_endCallback、_sliderPos進行回放進度、回放速度的控制
涉及到的交互及限制:vue
tip:算法
<template> <div> <div id="allmap"></div> <div class="slideBar track"> <Row type="flex" justify="center" align="middle"> <Col span='6'>回放進度</Col> <Col span='15'> <Slider v-model="progressVal" :disabled='sliderStatus' @on-input='progressChange'></Slider> </Col> </Row> <Row type="flex" justify="center" align="middle"> <Col span='6'>回放速度</Col> <Col span='15'> <Slider v-model="speedVal" :min='1' :max='10' :disabled='sliderStatus' @on-input='speedChange'></Slider> </Col> </Row> <Row type="flex" justify="center"> <Col span='10'> <Button class='btn' size="large" @click='pause' :disabled='pauseStatus'>暫停</Button> </Col> <Col span='8'> <Button type='primary' size="large" @click='run' :disabled='playStatus'>播放</Button> </Col> </Row> </div> </div> </template> <script> export default { methods:{ init(){ this.map = new BMap.Map('allmap',{enableMapClick:false}); this.map.enableScrollWheelZoom(true) this.map.centerAndZoom('杭州', 12); this.iconStart = new BMap.Icon(mobike, new BMap.Size(36,39),{anchor : new BMap.Size(18, 39)}); BMapLib.LuShu.prototype._addMarker=function(callback) { if (this._marker) { this.stop(); this._map.removeOverlay(this._marker); clearTimeout(this._timeoutFlag); } //移除以前的overlay this._overlay && this._map.removeOverlay(this._overlay); var marker = new BMap.Marker(this._path[0].point); this._opts.icon && marker.setIcon(this._opts.icon); this._map.addOverlay(marker); this._marker = marker; } BMapLib.LuShu.prototype._setLabel=(me,pointInfo)=>{ me._map.removeOverlay(me._marker.getLabel()); me._marker.setLabel(new BMap.Label(this.getContentTemplate(pointInfo,false),{offset:new BMap.Size(40,-10)})) } BMapLib.LuShu.prototype._move=function(initPos,targetPos,effect,initPosInfo,targetPosInfo) { var pointsArr=[initPos,targetPos]; //點數組 var me = this, //當前的幀數 currentCount = 0, //步長,米/秒 timer = 10, step = this._opts.speed / (1000 / timer), //初始座標 init_pos = this._projection.lngLatToPoint(initPos), //獲取結束點的(x,y)座標 target_pos = this._projection.lngLatToPoint(targetPos), //總的步長 count = Math.round(me._getDistance(init_pos, target_pos) / step); //若是小於1直接移動到下一點 if (count < 1) { me._moveNext(++me.i); return; } me._intervalFlag = setInterval(function() { //兩點之間當前幀數大於總幀數的時候,則說明已經完成移動 if (currentCount >= count) { me._endCallback(initPosInfo,targetPosInfo) clearInterval(me._intervalFlag); //移動的點已經超過總的長度 if(me.i > me._path.length){ return; } //運行下一個點 me._moveNext(++me.i); }else { currentCount++; var x = effect(init_pos.x, target_pos.x, currentCount, count), y = effect(init_pos.y, target_pos.y, currentCount, count), pos = me._projection.pointToLngLat(new BMap.Pixel(x, y)); //設置marker if(currentCount == 1){ var proPos = null; if(me.i - 1 >= 0){ proPos = me._path[me.i - 1].point; } if(me._opts.enableRotation == true){ me.setRotation(proPos,initPos,targetPos); } if(me._opts.autoView){ if(!me._map.getBounds().containsPoint(pos)){ me._map.setCenter(pos); } } } //設置label me._setLabel(me,initPosInfo) //正在移動 me._marker.setPosition(pos,initPos); //設置自定義overlay的位置 me._setInfoWin(pos); me._sliderPos(initPos,targetPos,initPosInfo,targetPosInfo) } },timer); }; BMapLib.LuShu.prototype._moveNext= function(index) { var me = this; if (index < this._path.length - 1) { me._move(me._path[index].point, me._path[index + 1].point, me._tween.linear,me._path[index],me._path[index+1]); } }, BMapLib.LuShu.prototype.pause = function() { clearInterval(this._intervalFlag); //標識是不是按過pause按鈕 this._fromPause = true; this._clearTimeout(); this._pauseCallback() }; BMapLib.LuShu.prototype._sliderPos=(initPos,targetPos,initPosInfo)=>{ this.currentPoint = this.pointList.map((item)=>{ return item.locationTime}).indexOf(initPosInfo.locationTime) this.progressVal = Number(((this.currentPoint/this.pointList.length)*100).toFixed(0)) this.handler = false }; BMapLib.LuShu.prototype._endCallback=(initPosInfo,targetPosInfo)=>{ if (targetPosInfo.locationTime==this.pointList.slice().pop().locationTime) { this.progressVal=100 this.handler = true this.playStatus = false this.pauseStatus =true this.$Message.success('播放完成') } }; BMapLib.LuShu.prototype._pauseCallback=()=>{ this.handler =true }; BMapLib.LuShu.prototype.removeOverlay=function(){ this._map.removeOverlay(this._marker) } }, run(){ if (this.progressVal==100) { this.restart = true this.$Message.info({ top: 50, duration: 3, render: h => { return h('span', [ '播放已完成,是否', h('a', { on:{ 'click':()=>{ if (this.restart) { this.progressVal = 0; this.restart = false setTimeout(()=>{ this.pauseStatus = false this.run() },400) } } } },'從新播放'),'?' ]) } }); return }else{ this.pauseStatus = false this.playStatus = true this.start.hide() } if (this.type==='pause') { this.lushu.start() return } //this.map.clearOverlays(); //this.map.addOverlay(this.polyline); this.lushu = new BMapLib.LuShu(this.map,this.pointList.slice(this.cut),{ //defaultContent:"粵A30780",//"從天安門到百度大廈" autoView:false,//是否開啓自動視野調整,若是開啓那麼路書在運動過程當中會根據視野自動調整 icon : this.iconStart, speed: this.speed, enableRotation:false,//是否設置marker隨着道路的走向進行旋轉 landmarkPois:[] }); this.lushu.start() }, pause(){ this.playStatus = false this.type = 'pause' this.lushu.pause() }, speedChange(val){ this.lushu._opts.speed = val*30 this.speed=val*30 }, } } </script>
百度lushu源碼參考 http://api.map.baidu.com/libr...