Fixed touch events management on the map

This commit is contained in:
Fabio Manganiello 2025-03-31 20:22:04 +02:00
parent 91a05fdd9d
commit 3183799185
Signed by: blacklight
GPG key ID: D90FBA7F76362774
3 changed files with 49 additions and 124 deletions

View file

@ -51,7 +51,7 @@
:devices="devices" :devices="devices"
:disabled="loading" :disabled="loading"
:resolution="resolutionMeters" :resolution="resolutionMeters"
@refresh="locationQuery = $event" @refresh="onFormUpdate"
@set-resolution="setResolution" /> @set-resolution="setResolution" />
</div> </div>
<FilterButton @input="showControls = !showControls" <FilterButton @input="showControls = !showControls"
@ -284,7 +284,7 @@ export default {
return return
} }
this.locationQuery = nextPageQuery this.locationQuery = new LocationQuery(nextPageQuery)
}, },
fetchPrevPage() { fetchPrevPage() {
@ -293,7 +293,7 @@ export default {
return return
} }
this.locationQuery = prevPageQuery this.locationQuery = new LocationQuery(prevPageQuery)
}, },
async resetPage() { async resetPage() {
@ -410,6 +410,10 @@ export default {
this.locationQuery.maxId = null this.locationQuery.maxId = null
}, },
onFormUpdate(event: any) {
this.locationQuery = new LocationQuery(event)
},
onTimelinePointHover(point: GPSPoint) { onTimelinePointHover(point: GPSPoint) {
if (!this.pointsLayer) { if (!this.pointsLayer) {
return return
@ -450,7 +454,7 @@ export default {
Math.max(startPoint[1], endPoint[1]), Math.max(startPoint[1], endPoint[1]),
] ]
this.locationQuery = { this.locationQuery = new LocationQuery({
...this.locationQuery, ...this.locationQuery,
startDate: null, startDate: null,
endDate: null, endDate: null,
@ -460,14 +464,14 @@ export default {
minLatitude: startLat, minLatitude: startLat,
maxLongitude: endLon, maxLongitude: endLon,
maxLatitude: endLat, maxLatitude: endLat,
} })
}, },
onSelectOverlayButtonClick() { onSelectOverlayButtonClick() {
if (!this.hasSelectionBox) { if (!this.hasSelectionBox) {
this.showSelectOverlay = true this.showSelectOverlay = true
} else { } else {
this.locationQuery = { this.locationQuery = new LocationQuery({
...this.locationQuery, ...this.locationQuery,
minId: null, minId: null,
maxId: null, maxId: null,
@ -475,7 +479,7 @@ export default {
minLatitude: null, minLatitude: null,
maxLongitude: null, maxLongitude: null,
maxLatitude: null, maxLatitude: null,
} })
} }
}, },

View file

@ -6,13 +6,13 @@
</div> </div>
<div class="overlay" <div class="overlay"
ref="overlay" ref="overlay"
@mousedown="onOverlayDragStart" @mousedown="onSelectionStart"
@mouseup="onOverlayDragEnd" @mouseup="onSelectionEnd"
@mousemove="onOverlayMove" @mousemove="onSelectionEdit"
@touchstart="onOverlayDragStart" @touchstart.stop.prevent="onSelectionStart"
@touchend="onOverlayDragEnd" @touchend.stop.prevent="onSelectionEnd"
@touchmove="onOverlayMove" @touchmove.stop.prevent="onSelectionEdit"
@click="onOverlayDragEnd"> @click="onSelectionEnd">
<div class="box" <div class="box"
:style="selectionBoxStyle" :style="selectionBoxStyle"
v-if="selectionBox.length > 1" /> v-if="selectionBox.length > 1" />
@ -86,21 +86,30 @@ export default {
}, },
getXY(event: MouseEvent | TouchEvent): number[] { getXY(event: MouseEvent | TouchEvent): number[] {
if (event instanceof MouseEvent) { let [x, y] = [null, null]
return [event.clientX, event.clientY]
}
if (event instanceof TouchEvent) { if (event instanceof TouchEvent) {
const touches = event.touches?.length ? event.touches : this.latestTouchEvent?.touches if (event.touches?.length) {
if (!touches?.length) { x = event.touches[0].clientX
return [] y = event.touches[0].clientY
} else if (event.changedTouches?.length) {
x = event.changedTouches[0].clientX
y = event.changedTouches[0].clientY
} else if (this.latestTouchEvent) {
x = this.latestTouchEvent.changedTouches[0].clientX
y = this.latestTouchEvent.changedTouches[0].clientY
} else {
return
} }
} else {
this.latestTouchEvent = null x = event.clientX
return [touches[0].clientX, touches[0].clientY] y = event.clientY
} }
return [] if (x == null || y == null) {
return []
}
return [x, y]
}, },
setSelectionBoxCoordinates(event: MouseEvent | TouchEvent) { setSelectionBoxCoordinates(event: MouseEvent | TouchEvent) {
@ -117,13 +126,21 @@ export default {
this.selectionBox = newBox this.selectionBox = newBox
}, },
onOverlayDragStart(event: MouseEvent | TouchEvent) { onSelectionStart(event: MouseEvent | TouchEvent) {
this.selectionBox = [] this.selectionBox = []
this.setSelectionBoxCoordinates(event) this.setSelectionBoxCoordinates(event)
this.overlayDragging = true this.overlayDragging = true
}, },
onOverlayDragEnd(event: MouseEvent | TouchEvent) { onSelectionEdit(event: MouseEvent | TouchEvent) {
if (!this.overlayDragging || this.selectionBox.length < 1) {
return
}
this.setSelectionBoxCoordinates(event)
},
onSelectionEnd(event: MouseEvent | TouchEvent) {
if (this.selectionBox.length < 1) { if (this.selectionBox.length < 1) {
this.selectionBox = [] this.selectionBox = []
return return
@ -135,6 +152,7 @@ export default {
this.setSelectionBoxCoordinates(event) this.setSelectionBoxCoordinates(event)
this.overlayDragging = false this.overlayDragging = false
this.latestTouchEvent = null
if (this.hasDistinctPoints) { if (this.hasDistinctPoints) {
this.$emit( this.$emit(
@ -148,18 +166,6 @@ export default {
) )
} }
}, },
onOverlayMove(event: MouseEvent | TouchEvent) {
if (!this.overlayDragging || this.selectionBox.length < 1) {
return
}
this.setSelectionBoxCoordinates(event)
if (event instanceof TouchEvent) {
this.latestTouchEvent = event
}
},
} }
} }
</script> </script>

View file

@ -1,85 +0,0 @@
<script lang="ts">
export default {
data() {
return {
selectionBox: [] as number[][],
}
},
computed: {
selectionBoxStyle(): Record<string, string> {
if (this.selectionBox.length < 2) {
return {}
}
const [minX, minY, maxX, maxY] = [
Math.min(this.selectionBox[0][0], this.selectionBox[1][0]),
Math.min(this.selectionBox[0][1], this.selectionBox[1][1]),
Math.max(this.selectionBox[0][0], this.selectionBox[1][0]),
Math.max(this.selectionBox[0][1], this.selectionBox[1][1]),
]
return {
top: minY + 'px',
left: minX + 'px',
width: `${maxX - minX}px`,
height: `${maxY - minY}px`,
}
},
},
methods: {
scaledPointerCoordinates(event: MouseEvent): number[] {
// @ts-ignore
const offsetLeft = this.$refs.overlay?.getBoundingClientRect().left || 0
// @ts-ignore
const offsetTop = this.$refs.overlay?.getBoundingClientRect().top || 0
return [
event.clientX - offsetLeft,
event.clientY - offsetTop,
]
},
setSelectionBoxCoordinates(event: MouseEvent) {
const coords = this.scaledPointerCoordinates(event)
let newBox = JSON.parse(JSON.stringify(this.selectionBox)) as number[][]
if (newBox.length === 1 || !newBox[1]) {
newBox.push(coords)
} else {
newBox[1] = coords
}
newBox = newBox.sort((a: number[], b: number[]) => a[0] - b[0])
this.selectionBox = newBox
},
onOverlayDragStart(event: MouseEvent) {
this.setSelectionBoxCoordinates(event)
},
onOverlayDragEnd(event: MouseEvent) {
if (this.selectionBox.length < 1) {
this.selectionBox = []
return
}
this.setSelectionBoxCoordinates(event)
if (this.selectionBox.length > 1 && (
this.selectionBox[0][0] === this.selectionBox[1][0] && this.selectionBox[0][1] === this.selectionBox[1][1])
) {
this.selectionBox = []
}
},
onOverlayMove(event: MouseEvent) {
if (this.selectionBox.length < 1) {
return
}
this.setSelectionBoxCoordinates(event)
},
},
}
</script>