小车动画支持调节速率
This commit is contained in:
parent
6ea549fde2
commit
d4aba4100a
@ -87,7 +87,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="absolute bg-amber-50 rounded-tl z-max text-left absolute-bottom-right pl-1.5" style="width: 350px" v-if="view.lines.length > 0">
|
<div class="absolute bg-amber-50 rounded-tl z-max text-left absolute-bottom-right pl-1.5" style="width: 350px" v-if="view.lines.length > 0">
|
||||||
路径数量: {{view.lines.length}}
|
<div class="flex justify-between">
|
||||||
|
<div>
|
||||||
|
路径数量: {{view.lines.length}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<q-btn dense @click="changeAnimateRate">动画速率: {{view.animateRate}}</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<q-scroll-area :style="{height: view.lines.length * 22 > 250 ?'250px':view.lines.length * 22 + 'px'}" class="overflow-auto"
|
<q-scroll-area :style="{height: view.lines.length * 22 > 250 ?'250px':view.lines.length * 22 + 'px'}" class="overflow-auto"
|
||||||
:thumb-style="scrollArea.thumbStyle"
|
:thumb-style="scrollArea.thumbStyle"
|
||||||
@ -99,7 +106,10 @@
|
|||||||
<template v-slot:label="opt">
|
<template v-slot:label="opt">
|
||||||
<div class="row items-center">
|
<div class="row items-center">
|
||||||
<span>{{ opt.label }}</span>
|
<span>{{ opt.label }}</span>
|
||||||
<q-icon @click.stop="play(opt)" name="fas fa-play" color="teal" size="0.625em" class="q-ml-sm" />
|
<q-icon v-if="view.animating === opt.value"
|
||||||
|
@click.stop="stop"
|
||||||
|
name="fas fa-stop" color="negative" size="0.625em" class="q-ml-sm"></q-icon>
|
||||||
|
<q-icon v-else @click.stop="play(opt)" name="fas fa-play" color="teal" size="0.625em" class="q-ml-sm" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</q-option-group>
|
</q-option-group>
|
||||||
@ -110,7 +120,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||||
import {onMounted, reactive, ref} from "vue";
|
import {onMounted, onUnmounted, reactive, ref} from "vue";
|
||||||
import DateTimeSelector from "matrix-middle-service-web/src/components/DateTimeSelector.vue";
|
import DateTimeSelector from "matrix-middle-service-web/src/components/DateTimeSelector.vue";
|
||||||
import {useQuasar} from "quasar";
|
import {useQuasar} from "quasar";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
@ -124,7 +134,7 @@ import {
|
|||||||
import {fixedLocationHandler} from "matrix-middle-service-web/src/views/record/logic/location";
|
import {fixedLocationHandler} from "matrix-middle-service-web/src/views/record/logic/location";
|
||||||
import {drawMarkers} from "matrix-middle-service-web/src/views/record/logic/markers";
|
import {drawMarkers} from "matrix-middle-service-web/src/views/record/logic/markers";
|
||||||
import {drawLines} from "matrix-middle-service-web/src/views/record/logic/lines";
|
import {drawLines} from "matrix-middle-service-web/src/views/record/logic/lines";
|
||||||
import {playAnimation} from "matrix-middle-service-web/src/views/record/logic/play";
|
import {pauseAnimation, playAnimation, stopAnimation} from "matrix-middle-service-web/src/views/record/logic/play";
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const scrollArea = reactive({
|
const scrollArea = reactive({
|
||||||
thumbStyle: {
|
thumbStyle: {
|
||||||
@ -159,9 +169,29 @@ const date = ref({
|
|||||||
const feature = reactive({
|
const feature = reactive({
|
||||||
showFixed: false
|
showFixed: false
|
||||||
})
|
})
|
||||||
|
function changeAnimateRate(){
|
||||||
|
const animateRate = [1,2,5,10,20,30,60,120]
|
||||||
|
let curIndex = animateRate.findIndex(item=>item === view.animateRate)
|
||||||
|
let nextIndex = curIndex + 1
|
||||||
|
view.animateRate = nextIndex >= animateRate.length ? animateRate[0] : animateRate[nextIndex]
|
||||||
|
|
||||||
|
if(view.animating !== -1){
|
||||||
|
let index = view.animating
|
||||||
|
pauseAnimation(data)
|
||||||
|
setTimeout(()=>{
|
||||||
|
play(options.lines[index])
|
||||||
|
},100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function stop(){
|
||||||
|
stopAnimation(map,data,view)
|
||||||
|
}
|
||||||
function play(item){
|
function play(item){
|
||||||
console.log(item,view.lines,data.polylines)
|
console.log(item,view.lines,data.polylines)
|
||||||
playAnimation(map,data,view.lines[item.value])
|
options.showLines = [item.value]
|
||||||
|
changeShowLines()
|
||||||
|
view.animating = item.value
|
||||||
|
playAnimation(map,data,view.lines[item.value],view.animateRate,view,item.value)
|
||||||
}
|
}
|
||||||
// 地图实例 和 数据不要交给 vue 管理 否则性能大打折扣 且 会有各种奇葩问题
|
// 地图实例 和 数据不要交给 vue 管理 否则性能大打折扣 且 会有各种奇葩问题
|
||||||
let map = {}
|
let map = {}
|
||||||
@ -183,10 +213,19 @@ const view = reactive({
|
|||||||
},
|
},
|
||||||
lines: [],
|
lines: [],
|
||||||
loginStatus: false,
|
loginStatus: false,
|
||||||
|
animateRate: 1,
|
||||||
|
animating: -1
|
||||||
})
|
})
|
||||||
onMounted(()=>{
|
onMounted(()=>{
|
||||||
view.loginStatus = checkLoginStatus()
|
view.loginStatus = checkLoginStatus()
|
||||||
})
|
})
|
||||||
|
onUnmounted(()=>{
|
||||||
|
clearMap()
|
||||||
|
map.remove(data.labelsLayer || {})
|
||||||
|
map.remove(data.tmpMarker || {})
|
||||||
|
map.remove(data.animateMarker || {})
|
||||||
|
map.remove(data.infoWindow || {})
|
||||||
|
})
|
||||||
const layers = reactive({
|
const layers = reactive({
|
||||||
satellite: {
|
satellite: {
|
||||||
inst: {},
|
inst: {},
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
export function playAnimation(map,data,line){
|
let index = 0
|
||||||
|
|
||||||
|
export function playAnimation(map,data,line,animateRate,view,itemIndex){
|
||||||
console.log("playAnimation",line)
|
console.log("playAnimation",line)
|
||||||
if(!data.animateMarker){
|
if(data.animateMarker){
|
||||||
data.animateMarker = new AMap.Marker({
|
map.remove(data.animateMarker)
|
||||||
map: map,
|
|
||||||
position: [0,0],
|
|
||||||
icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
|
|
||||||
offset: new AMap.Pixel(-13, -26),
|
|
||||||
autoRotation: true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
data.animateMarker = new AMap.Marker({
|
||||||
|
map: map,
|
||||||
|
position: [0,0],
|
||||||
|
icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
|
||||||
|
offset: new AMap.Pixel(-13, -26),
|
||||||
|
autoRotation: true
|
||||||
|
})
|
||||||
|
|
||||||
if(!data.infoWindow){
|
if(!data.infoWindow){
|
||||||
data.infoWindow = new AMap.InfoWindow({
|
data.infoWindow = new AMap.InfoWindow({
|
||||||
@ -18,25 +21,34 @@ export function playAnimation(map,data,line){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = line.map((item) => {
|
if(itemIndex !== view.animating){
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
let path = line.slice(index).map((item) => {
|
||||||
return new AMap.LngLat(item.longitude, item.latitude)
|
return new AMap.LngLat(item.longitude, item.latitude)
|
||||||
})
|
})
|
||||||
|
|
||||||
let index = 0
|
|
||||||
data.animateMarker.stopMove();
|
data.animateMarker.stopMove();
|
||||||
data.animateMarker.on("movealong",()=>{})
|
data.animateMarker.on("movealong",()=>{})
|
||||||
|
let lastMovingIndex = 0
|
||||||
data.animateMarker.on("moving",(e)=>{
|
data.animateMarker.on("moving",(e)=>{
|
||||||
|
if(lastMovingIndex != e.index){
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
lastMovingIndex = e.index
|
||||||
|
console.log("index",index,path.length,line.length)
|
||||||
let lastLocation = e.passedPath[e.passedPath.length - 1];
|
let lastLocation = e.passedPath[e.passedPath.length - 1];
|
||||||
data.infoWindow.setPosition(lastLocation);
|
data.infoWindow.setPosition(lastLocation);
|
||||||
let speed = ((line[e.index].speed||0) * 3.6).toFixed(2)
|
let speed = ((line[index].speed||0) * 3.6).toFixed(2)
|
||||||
data.infoWindow.setContent(`<div style="width:100px;background: #fff;border-radius: 5px">${speed} km/h</div>`);
|
data.infoWindow.setContent(`<div style="width:100px;background: #fff;border-radius: 5px">${speed} km/h</div>`);
|
||||||
map.setCenter(e.target.getPosition(),true)
|
map.setCenter(e.target.getPosition(),true)
|
||||||
})
|
})
|
||||||
data.animateMarker.on("moveend",()=>{
|
data.animateMarker.on("moveend",()=>{
|
||||||
index++
|
if(index >= line.length-1){
|
||||||
|
|
||||||
if(index === line.length-1){
|
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
|
view.animating = -1
|
||||||
|
index = 0
|
||||||
|
data.animateMarker.stopMove()
|
||||||
map.remove(data.animateMarker)
|
map.remove(data.animateMarker)
|
||||||
data.infoWindow.close()
|
data.infoWindow.close()
|
||||||
},100)
|
},100)
|
||||||
@ -46,8 +58,24 @@ export function playAnimation(map,data,line){
|
|||||||
path: path,
|
path: path,
|
||||||
})
|
})
|
||||||
data.animateMarker.moveAlong(polyline.getPath(),{
|
data.animateMarker.moveAlong(polyline.getPath(),{
|
||||||
duration: 1000/60,
|
duration: 1000/animateRate,
|
||||||
autoRotation: true
|
autoRotation: true
|
||||||
});
|
});
|
||||||
data.infoWindow.open(map, data.animateMarker.getPosition())
|
data.infoWindow.open(map, data.animateMarker.getPosition())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stopAnimation(map,data,view){
|
||||||
|
if(!data.animateMarker){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pauseAnimation(data)
|
||||||
|
view.animating = -1
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pauseAnimation(data){
|
||||||
|
if(!data.animateMarker){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data.animateMarker.stopMove()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user