根据业务场景结合vue+iview在百度lushu的prototype中新增一些回调属性如:_pauseCallback、_endCallback、_sliderPos进行回放进度、回放速度的控制
涉及到的交互及限制:
- 回放进度(暂停时拖动,播放中无法控制)
- 回放速度(移动中需要到下一个坐标点,若距离太长两点之间无法变更速度)
tip:
- 测试数据中相邻坐标点的间隔不匀会导致进度条的快慢不等
- 进度条位置_sliderPos的算法不太精确需要再做优化可自行修改
代码
<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...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。