最近在做项目,有一个轨迹回放的需求,还得支持进度条拖动播放。轨迹播放的功能高德的文档示例都很完整清楚,但是进度条播放的功能,我网上找了很久,一直没找到适合我需求的实现。于是结合着网上搜索的资料和高德文档,基本实现了我的需求。正好做个记录,也可以让有相关需求的朋友作个参考。
//初始化地图
initMap() {
this.map = new AMap.Map("container", {
resizeEnable: true,
center: this.lineArr[0],
zoom: 18,
});
// 移动点
this.marker = new AMap.Marker({
map: this.map,
position: this.lineArr[0],
icon: this.locationIcon,
offset: new AMap.Pixel(-20, -20),
});
// 起始点
this.startMarker = new AMap.Marker({
map: this.map,
position: this.lineArr[0],
icon: startIcon,
offset: new AMap.Pixel(-20, -20),
});
},
// 绘制轨迹
initPloyLine() {
this.polyline = new AMap.Polyline({
map: this.map,
path: this.lineArr,
showDir: true,
strokeColor: "#28F", //线颜色
strokeWeight: 6, //线宽
});
const _this = this;
// 监听轨迹移动
this.marker.on("moving", function (e) {
// 获取移动的点位索引 同步进度条
const index = _this.lineArr.findIndex(
(item) => item[2] === e.passedPos[2]
);
_this.sliderVal = Math.round(
((index + 1) / _this.lineArr.length) * 100
);
_this.passedPolyline.setPath([..._this.passedPath, ...e.passedPath]);// 把当前运动的轨迹和进度条拖动的轨迹拼接
_this.map.setCenter(e.target.getPosition(), true);
});
// 监听轨迹移动结束,这个方法找了好久
this.marker.on("movealong", function (e) {
_this.stop();
});
this.map.setFitView();
},
getLine() {
const _this = this;
// JSAPI2.0 使用覆盖物动画必须先加载动画插件
AMap.plugin("AMap.MoveAnimation", function () {
_this.initMap();
_this.initPloyLine();
});
},
以上轨迹基础部分也可直接参考高德 lbs.amap.com/demo/javasc…
开始播放
start() {
// 调用this.passedPolyline.destroy()后,已运行轨迹就被销毁了,所以每次开始都必须重新定义,否者再次运行就没这些配置的颜色了
this.passedPolyline = new AMap.Polyline({
map: this.map,
strokeColor: "#AF5", //线颜色
strokeWeight: 6, //线宽
});
this.marker.moveAlong(this.linePath, {
// 每一段的时长
duration: 500, //可根据实际采集时间间隔设置
// JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
autoRotation: true,
});
this.playStatus = 1;
},
接下来是进度条拖动播放,也是我搞了最久的部分
// 手动拖动滑块
onUpdate(value) {
if (this.playStatus === 1) {
this.pause(); // 如果是播放状态就先暂停,不是播放状态 暂停会导致后续无法播放
}
const index = Math.round((value / 100) * this.lineArr.length);
this.marker.setPosition(this.lineArr[index]); // 进度条停止移动后,重新设置marker点位置
this.linePath = this.lineArr.slice(index); // 拖动进度条后,接下来点位要运动的轨迹就不是整条了,要截取剩余的轨迹
this.passedPath = this.lineArr.filter((item, ind) => index > ind);//已经拖动的部分也要保存,不然已经运动的轨迹无法改变颜色
this.passedPolyline.setPath(this.passedPath); // 设置已经拖动的路线
//this.start();
},
最后轨迹运动结束调用stop(),把进度条、播放状态还原至初始状态。
stop() {
if (this.lineArr.length) {
this.marker.stopMove();
this.passedPolyline.destroy()
}
this.playStatus = 0;
this.sliderVal = 0;
this.passedPath = [];
this.linePath = this.lineArr;
},
以上就是我本次完成的轨迹回放功能,不过还是有不完善,比如:
-
结束后我想清除轨迹回放,但是调用this.passedPolyline.setPath([]),并没起作用。调用 this.passedPolyline.destroy()就可以清除已播放轨迹 -
还有我在拖动滑块后就调用了start()方法,因为之后手动无法触发。不要在非播放状态下使用暂停方法就可以解决
详细的方法基本都可以在文档找到高德文档找到
如果朋友们有更好的方法,欢迎讨论和指正。
第一次写文章记录,希望表达清楚了。感谢