Let users move the view around

* Let user move the view around, without automatic refocusing.
* Add a button to refocus view.
This commit is contained in:
Lucas Verney 2018-07-01 22:02:54 +02:00
parent ac518944d1
commit c15ad9ab56
2 changed files with 56 additions and 19 deletions

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="fill-height fill-width"> <div class="fill-height fill-width">
<v-lmap :center="latlng" :zoom="this.zoom" :minZoom="this.minZoom" :maxZoom="this.maxZoom" :options="{ zoomControl: false }" @contextmenu="handleLongPress"> <v-lmap :center="latLng" :zoom="this.zoom" :minZoom="this.minZoom" :maxZoom="this.maxZoom" :options="{ zoomControl: false }" @contextmenu="handleLongPress" @moveend="onMoveEnd" @movestart="onMoveStart">
<v-ltilelayer :url="tileServer" :attribution="attribution"></v-ltilelayer> <v-ltilelayer :url="tileServer" :attribution="attribution"></v-ltilelayer>
<v-lts v-if="heading" :lat-lng="latlng" :options="markerOptions"></v-lts> <v-lts v-if="heading" :lat-lng="positionLatLng" :options="markerOptions"></v-lts>
<v-lcirclemarker v-else :lat-lng="latlng" :color="markerOptions.color" :fillColor="markerOptions.fillColor" :fillOpacity="1.0" :weight="markerOptions.weight" :radius="markerRadius"></v-lcirclemarker> <v-lcirclemarker v-else :lat-lng="positionLatLng" :color="markerOptions.color" :fillColor="markerOptions.fillColor" :fillOpacity="1.0" :weight="markerOptions.weight" :radius="markerRadius"></v-lcirclemarker>
<v-lcircle v-if="shouldDisplayAccuracy" :lat-lng="latlng" :radius="radiusFromAccuracy"></v-lcircle> <v-lcircle v-if="shouldDisplayAccuracy" :lat-lng="latlng" :radius="radiusFromAccuracy"></v-lcircle>
@ -41,16 +41,19 @@ export default {
default: null, default: null,
}, },
heading: Number, heading: Number,
lat: Number, latLng: Array,
lng: Number,
markers: Array, markers: Array,
onLongPress: Function, onLongPress: Function,
onMoveEnd: Function,
onMoveStart: Function,
positionLatLng: Array,
}, },
computed: { computed: {
radiusFromAccuracy() { radiusFromAccuracy() {
if (this.accuracy) { if (this.accuracy) {
return this.accuracy / ( return this.accuracy / (
(constants.EARTH_RADIUS * 2 * Math.PI * Math.cos(this.lat * (Math.PI / 180))) / (constants.EARTH_RADIUS * 2 * Math.PI * Math.cos(this.latLng[0] *
(Math.PI / 180))) /
(2 ** (this.zoom + 8)) (2 ** (this.zoom + 8))
); );
} }
@ -63,9 +66,6 @@ export default {
this.radiusFromAccuracy > this.markerRadius this.radiusFromAccuracy > this.markerRadius
); );
}, },
latlng() {
return [this.lat, this.lng];
},
markerOptions() { markerOptions() {
return { return {
fillColor: '#00ff00', fillColor: '#00ff00',

View File

@ -1,8 +1,21 @@
<template> <template>
<v-container fluid fill-height class="no-padding"> <v-container fluid fill-height class="no-padding">
<v-layout row wrap fill-height> <v-layout row wrap fill-height>
<v-flex xs12 fill-height v-if="lat && lng"> <v-flex xs12 fill-height v-if="latLng">
<Map :lat="lat" :lng="lng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onLongPress="showReportDialog"></Map> <Map :latLng="mapLatLng" :positionLatLng="latLng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onLongPress="showReportDialog" :onMoveEnd="onMapMoveEnd" :onMoveStart="onMapMoveStart"></Map>
<v-btn
fixed
dark
fab
bottom
left
color="blue"
class="overlayButton"
v-if="hasMapMoved"
@click.native.stop="recenterMap"
>
<v-icon>my_location</v-icon>
</v-btn>
<v-btn <v-btn
fixed fixed
dark dark
@ -64,15 +77,23 @@ export default {
latLng: [report.attributes.lat, report.attributes.lng], latLng: [report.attributes.lat, report.attributes.lng],
})); }));
}, },
mapLatLng() {
if (this.hasMapMoved) {
return this.mapMovedLatLng;
}
return this.latLng;
},
}, },
data() { data() {
return { return {
accuracy: null, accuracy: null,
centering: false,
dialog: false, dialog: false,
error: null, error: null,
hasMapMoved: false,
heading: null, heading: null,
lat: null, latLng: null,
lng: null, mapMovedLatLng: null,
noSleep: null, noSleep: null,
reportLat: null, reportLat: null,
reportLng: null, reportLng: null,
@ -119,17 +140,16 @@ export default {
this.error = `Error ${error.code}: ${error.message}`; this.error = `Error ${error.code}: ${error.message}`;
}, },
setPosition(position) { setPosition(position) {
if (this.lat && this.lng) { if (this.latLng) {
const distanceFromPreviousPoint = distance( const distanceFromPreviousPoint = distance(
[this.lat, this.lng], [this.latLng[0], this.latLng[1]],
[position.coords.latitude, position.coords.longitude], [position.coords.latitude, position.coords.longitude],
); );
if (distanceFromPreviousPoint > constants.UPDATE_REPORTS_DISTANCE_THRESHOLD) { if (distanceFromPreviousPoint > constants.UPDATE_REPORTS_DISTANCE_THRESHOLD) {
this.$store.dispatch('fetchReports'); this.$store.dispatch('fetchReports');
} }
} }
this.lat = position.coords.latitude; this.latLng = [position.coords.latitude, position.coords.longitude];
this.lng = position.coords.longitude;
this.heading = position.coords.heading ? position.coords.heading : null; this.heading = position.coords.heading ? position.coords.heading : null;
this.accuracy = position.coords.accuracy ? position.coords.accuracy : null; this.accuracy = position.coords.accuracy ? position.coords.accuracy : null;
}, },
@ -147,8 +167,8 @@ export default {
this.reportLat = latlng.lat; this.reportLat = latlng.lat;
this.reportLng = latlng.lng; this.reportLng = latlng.lng;
} else { } else {
this.reportLat = this.lat; this.reportLat = this.latLng[0];
this.reportLng = this.lng; this.reportLng = this.latLng[1];
} }
this.dialog = !this.dialog; this.dialog = !this.dialog;
}, },
@ -183,6 +203,23 @@ export default {
window.addEventListener('touchmove', this.handleFirstUserInteraction, false); window.addEventListener('touchmove', this.handleFirstUserInteraction, false);
window.addEventListener('MSPointerMove', this.handleFirstUserInteraction, false); window.addEventListener('MSPointerMove', this.handleFirstUserInteraction, false);
}, },
recenterMap() {
this.mapMovedLatLng = null;
this.centering = true;
this.hasMapMoved = false;
},
onMapMoveStart() {
if (!this.centering) {
this.hasMapMoved = true;
}
},
onMapMoveEnd(ev) {
const latLng = ev.target.getCenter();
if (!this.hasMapMoved) {
this.mapMovedLatLng = [latLng.lat, latLng.lng];
}
this.centering = false;
},
}, },
}; };
</script> </script>