El efecto es el siguiente y
el código es el siguiente
<!-- 轨迹回放 -->
<template>
<view class="wrap" @tap="handleWrapTap">
<map style="width: 100%; height: 100vh" id="myMap" :latitude="latitude" :longitude="longitude"
:include-points="points" :polyline="polyline" :markers="markers"></map>
<view class="tips">
<view class="item tips_time">
<!-- 月日 -->
<text class="mr10">{
{
tipsDate }}</text>
<!-- 时分秒 -->
</view>
<!-- <view class="item tips_speed">{
{
`当前时速${
spd}km/h`}}</view> -->
<!-- <view class="item tips_mile">{
{
`已行驶${
mlg > 0 ? mlg / 10 : 0}km`
}}</view> -->
</view>
<view class="bottom_wrap">
<!-- <view class="header">
<view class="license">{
{
carInfo.license }}</view>
<view @tap="handleChange" class="change">查看历史车辆</view>
</view>
<view class="flex">
<view class="label">托运货物:</view>
<view v-if="carInfo.goods.length" class="value">
<text v-for="(item, index) in carInfo.goods" :key="index">{
{
item.goods_name }}{
{
item.goods_count
}}{
{
item.goods_unit }}</text>
</view>
<view class="value" v-else>暂无数据</view>
</view> -->
<view class="progress_wrap">
<view class="flex">
<view class="start">{
{
carInfo.start_time }}</view>
<view class="end">{
{
carInfo.arrive_time }}</view>
</view>
<view class="progress">
<view id="group" class="btn_group" v-if="showGroup">
<image id="group1" @tap="speedMove" class="img speed mb20" mode="aspectFit"
src="../../static/images/add-speed.png" />
<image id="group2" @tap="reduceMove" class="img speed mb20" mode="aspectFit"
src="../../static/images/reduce-speed.png" />
<image id="group3" @tap="!startMove ? startMoveCar() : stopMove()" class="img" mode="aspectFit"
:src="
!startMove
? '../../static/images/start-icon.png'
: '../../static/images/stop-icon.png'
" />
</view>
<image id="image" @tap="handleStartMove" v-else class="img_start" mode="aspectFit" :src="
!startMove
? '../../static/images/start-icon.png'
: '../../static/images/stop-icon.png'
" />
<progress class="item" id="progress" @tap="handleTapProgress" @activeend="handleActiveEnd"
@touchmove="handletouchmove" @touchstart="handletouchstart" @touchend="handletouchend"
:active="false" active-mode="forwards" :percent="percent" stroke-width="16" duration="10" border-radius="10" activeColor="#5a7bee"/>
</view>
</view>
</view>
<tab-bar current="1" class="tabbar"></tab-bar>
</view>
</template>
<script>
/* import tabBar from "../components/tabBar";*/
import common from "@/utils/common";
export default {
/* components: {
tabBar,
}, */
data() {
return {
token:'',
// 车辆所有数据
carData: {
// 路线点
track: [],
},
carInfo: null,
percent: 0,
showGroup: false,
// 搜索条件
formData: {
license: "",
startTime: "",
endTime: "",
},
// 中心经纬度
latitude: "",
longitude: "",
// 标记点
markers: [{
}, {
}, {
}],
posi: {
latitude: 0,
longitude: 0,
iconPath: "../../static/images/car-icon.png",
callout: {
content: "", // 车牌信息
display: "BYCLICK",
fontWeight: "bold",
color: "#5A7BEE", //文本颜色
fontSize: "12px",
bgColor: "#ffffff", //背景色
padding: 5, //文本边缘留白
textAlign: "center",
},
anchor: {
x: 0.5,
y: 0.6,
},
width: 40,
height: 40,
id: 9,
},
// 线数据
polyline: [{
points: [],
color: "#3591fc",
arrowLine: true, //带箭头的线
width: 8,
}, ],
lineArr: [], // 所有轨迹点数组
points: [],
timer: null,
width: "",
startX: "",
spd: 0,
mlg: 0,
gtm: "",
tipsDate: null, // 日期提示
wait: 50,
wait2: 50,
iNum: 0, // 当前运动点在所有轨迹点数组的下标
startMove: false, // 开始移动
mapContext: null,
clientX_start: 0,
clientX_end: 0,
posi_x: 0,
};
},
watch: {
// 车辆当前时间点
gtm: {
handler() {
if (this.gtm) {
this.tipsDate =
this.carData.track.locationtime
}
},
deep: true,
immediate: true,
},
},
methods: {
handletouchmove(e) {
this.startMove = false;
let currentX = e.touches[0].pageX;
let currentY = e.touches[0].pageY;
let tx = currentX - this.lastX;
let ty = currentY - this.lastY;
let text = "";
// this.mindex = -1;
//左右方向滑动
if (Math.abs(tx) > Math.abs(ty)) {
if (tx < 0) {
text = "向左滑动";
} else if (tx > 0) {
text = "向右滑动";
}
}
//上下方向滑动
else {
if (ty < 0) {
text = "向上滑动";
} else if (ty > 0) {
text = "向下滑动";
}
}
//将当前坐标进行保存以进行下一次计算
this.lastX = currentX;
this.lastY = currentY;
this.text = text;
this.clientX_end = currentX;
},
handletouchstart(e) {
this.clientX_start = e.touches[0].pageX;
},
handletouchend(e) {
uni.showLoading({
title: "加载中",
});
// 清楚定时器
this.startMove = false;
clearInterval(this.timer);
this.timer = null;
let endX = parseInt(e.detail.x);
let x = parseInt(this.clientX_end - this.clientX_start);
this.posi_x += parseInt(this.clientX_end - this.clientX_start);
this.posi_x = this.posi_x > 0 ? this.posi_x : 0;
// 点击进度条 设置进度
this.percent =
this.posi_x > 0 ? (this.posi_x / this.width).toFixed(2) * 100 : 0;
// 获取当前进度节点对应的 经纬度数据
let index =
this.posi_x > 0 ?
parseInt((this.posi_x / this.width) * this.lineArr.length) :
0;
index = index > this.lineArr.length ? this.lineArr.length - 1 : index;
let posi = {
...this.posi,
latitude: this.lineArr[index].lat,
longitude: this.lineArr[index].lon,
};
this.$set(this.markers, 1, posi);
/* this.spd = this.lineArr[index].spd;
this.mlg = this.lineArr[index].mlg;
this.gtm = this.lineArr[index].gtm.split("/"); */
this.iNum = parseInt(this.percent / (100 / this.lineArr.length));
console.log(this.iNum, "num");
setTimeout(function() {
uni.hideLoading();
}, 1000);
},
handleChange() {
clearInterval(this.timer);
uni.navigateTo({
url: "/pages/car/carList",
});
},
// 点击 控制标签(开始、加速、减速)以外的部分就隐藏控制标签
handleWrapTap(e) {
let arr = ["group", "group1", "group2", "group3", "image"];
let isInclude = arr.includes(e.target.id);
this.showGroup = isInclude;
},
// 点击进度条
handleTapProgress(e) {
console.log("进度条");
// 清楚定时器
this.startMove = false;
clearInterval(this.timer);
let endX = parseInt(e.detail.x);
let x = endX - this.startX;
// 点击进度条 设置进度
this.percent = (x / this.width).toFixed(2) * 100;
this.posi_x = this.percent * (this.width / 100);
// 获取当前进度节点对应的 经纬度数据
let index = parseInt((x / this.width) * this.lineArr.length);
index = index > this.lineArr.length ? this.lineArr.length - 1 : index;
let posi = {
...this.posi,
latitude: this.lineArr[index].lat,
longitude: this.lineArr[index].lon,
};
this.$set(this.markers, 1, posi);
/* this.spd = this.lineArr[index].spd;
this.mlg = this.lineArr[index].mlg;
this.gtm = this.lineArr[index].gtm.split("/"); */
this.iNum = parseInt(this.percent / (100 / this.lineArr.length));
// console.log(this.iNum, "num");
},
// 播放完毕
handleActiveEnd(e) {
console.log("播放完毕")
this.stopMove();
},
// 点击开始图标
handleStartMove() {
this.showGroup = true;
this.startMoveCar();
},
startMoveCar() {
common.toast("开始播放");
this.startMove = true;
this.start();
},
// 暂停播放
stopMove() {
this.startMove = false;
clearInterval(this.timer);
common.toast("暂停播放");
},
// 加速播放
speedMove() {
if (this.wait2 / this.wait === 8) {
common.toast(`当前播放速度为×8,以达到最大,无法再加速`);
} else {
clearInterval(this.timer);
this.startMove = false;
this.wait = this.wait / 2;
common.toast(`当前播放速度为×${
this.wait2 / this.wait}`);
this.startMove = true;
this.start();
}
},
// 减速播放
reduceMove() {
if (this.wait2 / this.wait === 0.25) {
common.toast(`当前播放速度为0.25,以达到最小,无法再减速`);
} else {
clearInterval(this.timer);
this.startMove = false;
this.wait = this.wait * 2;
common.toast(`当前播放速度为×${
this.wait2 / this.wait}`);
this.startMove = true;
this.start();
}
},
// 开始播放
start() {
clearInterval(this.timer);
this.timer = null;
this.mapContext = uni.createMapContext("myMap", this);
this.startMove ?
(this.timer = setInterval(() => {
this.startMove ?
this.mapContext.translateMarker({
markerId: 9,
destination: {
longitude: this.lineArr[this.iNum].lon,
latitude: this.lineArr[this.iNum].lat,
},
//rotate: parseInt(this.lineArr[this.iNum].agl),
autoRotate:true,
duration: 200,
animationEnd: function() {
console.log("轨迹回放完成")
this.tipsDate = this.lineArr[this.iNum].locationtime;
this.percent = (100 / this.lineArr.length) * this.iNum;
this.posi_x = this.percent * (this.width / 100);
if (this.iNum === this.lineArr.length - 1) {
this.percent = 100;
clearInterval(this.timer);
}
this.iNum++;
this.start();
}.bind(this),
fail(e) {
console.log("轨迹回放失败")
},
}) :
"";
clearInterval(this.timer);
}, this.wait)) :
"";
},
// 设置 标记点
setMarkers() {
this.$set(this.posi, "latitude", this.lineArr[0].lat);
this.$set(this.posi, "longitude", this.lineArr[0].lon);
this.points = [];
this.lineArr.forEach((v) => {
this.points.push({
latitude: v.lat,
longitude: v.lon,
});
});
this.markers = [{
latitude: this.lineArr[0].lat,
longitude: this.lineArr[0].lon,
iconPath: "../../static/images/begin.png",
width: 21,
height: 21,
id: 8,
},
{
...this.posi,
},
{
latitude: this.lineArr[this.lineArr.length - 1].lat,
longitude: this.lineArr[this.lineArr.length - 1].lon,
iconPath: "../../static/images/end.png",
width: 21,
height: 21,
id: 10,
},
];
console.log("setMarkers"+this.markers+JSON.stringify(this.markers))
},
// 设置 路线
setPolyline() {
let obj = {
};
this.lineArr.forEach((line) => {
this.polyline[0].points.push({
longitude: line.lon,
latitude: line.lat,
});
});
console.log("pppppppppp"+JSON.stringify(this.polyline))
},
getGuiji() {
var imei = '86478404274139';
var date = '2021-09-07';
uni.request({
url: this.apiServier + "/findSportLocusByDate?imei=" + imei + "&date=" +
date,
method: 'GET',
header: {
'token': this.token,
},
success: (res) => {
console.log("rrrrrrrrr" + JSON.stringify(res));
if (res.data.code === 20000) {
uni.showToast({
title: '查询成功'
})
var data2 = res.data.data;
this.carData.track = data2;
console.log("this.carData.track" + JSON.stringify(this.carData.track));
this.latitude = data2[0].lat;
this.longitude = data2[0].lon;
this.tipsDate = data2[0].locationtime;
this.getData();
}
if (res.data.code === 50000) {
uni.showToast({
title: '该日期暂无轨迹'
})
}
},
fail: (res) => {
uni.showToast({
title: '服务器错误'
})
}
})
},
// 获取车辆轨迹数据
getData(data) {
// 获取后台数据
this.lineArr = this.carData.track;
console.log("aaaaaaaaaaaaa"+this.lineArr);
// 设置车牌号
// 设置初始标记点 起点 终点
this.setMarkers();
this.setPolyline();
},
},
mounted() {
// 获取progress进度条的长度
const query = uni.createSelectorQuery().in(this);
query
.select("#progress")
.boundingClientRect((data) => {
this.width = data.width;
this.startX = data.left;
})
.exec();
},
onLoad(query) {
this.token = uni.getStorageSync("token");
this.getGuiji();
},
};
</script>
<style lang="scss" scoped>
.tips {
position: absolute;
top: 20%;
left: 30rpx;
.mr10 {
margin-right: 10rpx;
}
.item {
//height: 50rpx;
width: 255rpx;
background: #ffffff;
border-radius: 50rpx;
margin-bottom: 20rpx;
font-weight: bold;
font-size: 26rpx;
line-height: 50rpx;
text-align: center;
color: #5a7bee;
}
}
.bottom_wrap {
position: absolute;
bottom: 168rpx;
width: 100%;
background: #fff;
padding: 30rpx;
box-sizing: border-box;
.header {
display: flex;
justify-content: space-between;
.license {
font-weight: bold;
font-size: 34rpx;
line-height: 48rpx;
color: #000000;
}
.change {
font-size: 34rpx;
line-height: 48rpx;
color: #5a7bee;
}
}
.flex {
display: flex;
font-size: 24rpx;
line-height: 34rpx;
color: #888888;
}
.progress_wrap {
//margin: 30rpx 0 40rpx;
position: relative;
top:0;
.flex {
display: flex;
justify-content: space-between;
font-weight: bold;
font-size: 24px;
line-height: 34px;
padding-left: 100rpx;
color: #000000;
}
.progress {
display: flex;
position: relative;
padding-left: 100rpx;
.img_start {
width: 56rpx;
height: 56rpx;
position: absolute;
left: 0;
bottom: -10rpx;
}
.btn_group {
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
left: 0;
bottom: -20rpx;
padding: 20rpx 10rpx;
background: #ffffff;
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25);
border-radius: 50rpx;
.img {
width: 56rpx;
height: 56rpx;
// margin-bottom: 40rpx;
}
.mb20 {
margin-bottom: 40rpx;
}
.speed {
width: 43rpx;
height: 36rpx;
}
}
}
}
.bottom {
display: flex;
.average_speed {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 33.3%;
.value {
width: 100%;
text-align: center;
font-weight: bold;
font-size: 34rpx;
line-height: 48rpx;
color: #5a7bee;
}
.label {
width: 100%;
text-align: center;
font-weight: normal;
font-size: 26rpx;
line-height: 36rpx;
color: #000000;
}
}
}
}
</style>