Fix centering of the map, fix #5

This commit is contained in:
Lucas Verney 2018-07-02 18:27:35 +02:00
parent 60c5b3a7cf
commit 1b3082d02a
3 changed files with 72 additions and 60 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="fill-height fill-width"> <div class="fill-height fill-width">
<v-lmap ref="map" :center="latLng" :zoom="this.zoom" :minZoom="this.minZoom" :maxZoom="this.maxZoom" :options="{ zoomControl: false }" @contextmenu="handleLongPress" @mousedown="onMouseDown" @mouseup="onMouseUp" @moveend="onMoveEndWrapper" @movestart="onMoveStartWrapper"> <v-lmap ref="map" :minZoom="this.minZoom" :maxZoom="this.maxZoom" :options="{ zoomControl: false }" @contextmenu="handleLongPress" @mousedown="onMouseDown" @mouseup="onMouseUp" @movestart="onMoveStart" @zoomstart="onZoomStart">
<v-ltilelayer :url="tileServer" :attribution="attribution"></v-ltilelayer> <v-ltilelayer :url="tileServer" :attribution="attribution"></v-ltilelayer>
<v-lts v-if="heading" :lat-lng="positionLatLng" :options="markerOptions"></v-lts> <v-lts v-if="heading" :lat-lng="positionLatLng" :options="markerOptions"></v-lts>
@ -42,11 +42,8 @@ export default {
default: null, default: null,
}, },
heading: Number, heading: Number,
latLng: Array,
markers: Array, markers: Array,
onLongPress: Function, onLongPress: Function,
onMoveEnd: Function,
onMoveStart: Function,
positionLatLng: Array, positionLatLng: Array,
}, },
computed: { computed: {
@ -77,14 +74,22 @@ export default {
}, },
}, },
mounted() { mounted() {
const map = this.$refs.map.mapObject; this.map = this.$refs.map.mapObject;
const north = L.control({ position: 'topright' }); if (this.map.getZoom() !== this.zoom) {
north.onAdd = () => { this.isProgrammaticZoom = true;
const div = L.DomUtil.create('div', 'compassIcon legend'); this.map.once('zoomend', () => { this.isProgrammaticZoom = false; });
div.innerHTML = `<img src="${compassNorthIcon}">`; }
return div; this.map.setView(this.positionLatLng, this.zoom);
}; this.showCompass();
north.addTo(map); },
updated() {
if (!this.recenterButton) {
if (this.map.getZoom() !== this.zoom) {
this.isProgrammaticZoom = true;
this.map.once('zoomend', () => { this.isProgrammaticZoom = false; });
}
this.map.setView(this.positionLatLng, this.zoom);
}
}, },
data() { data() {
return { return {
@ -95,6 +100,9 @@ export default {
maxZoom: constants.MAX_ZOOM, maxZoom: constants.MAX_ZOOM,
tileServer: constants.TILE_SERVER, tileServer: constants.TILE_SERVER,
isMouseDown: false, isMouseDown: false,
isProgrammaticZoom: false,
recenterButton: null,
map: null,
}; };
}, },
methods: { methods: {
@ -109,16 +117,52 @@ export default {
onMouseUp() { onMouseUp() {
this.isMouseDown = false; this.isMouseDown = false;
}, },
onMoveStartWrapper(ev) { onMoveStart() {
if (this.isMouseDown) { if (this.isMouseDown && !this.recenterButton) {
this.onMoveStart(ev); this.showRecenterButton();
} }
}, },
onMoveEndWrapper(ev) { onZoomStart() {
if (this.isMouseDown) { if (!this.isProgrammaticZoom) {
this.onMoveEnd(ev); this.showRecenterButton();
} }
}, },
showCompass() {
const north = L.control({ position: 'topright' });
north.onAdd = () => {
const div = L.DomUtil.create('div', 'compassIcon legend');
div.innerHTML = `<img src="${compassNorthIcon}">`;
return div;
};
this.map.addControl(north);
},
showRecenterButton() {
if (!this.recenterButton) {
this.recenterButton = L.control({ position: 'bottomleft' });
this.recenterButton.onAdd = () => {
const btn = L.DomUtil.create('button', 'overlayButton btn btn--floating btn--large theme--dark blue legend');
btn.type = 'button';
btn.addEventListener('click', this.recenterMap);
btn.innerHTML = '<div class="btn__content"><i aria-hidden="true" class="icon material-icons">my_location</i></div>';
return btn;
};
this.map.addControl(this.recenterButton);
}
},
hideRecenterButton() {
if (this.recenterButton) {
this.map.removeControl(this.recenterButton);
this.recenterButton = null;
}
},
recenterMap() {
this.hideRecenterButton();
if (this.map.getZoom() !== this.zoom) {
this.isProgrammaticZoom = true;
this.map.once('zoomend', () => { this.isProgrammaticZoom = false; });
}
this.map.setView(this.positionLatLng, this.zoom);
},
}, },
}; };
</script> </script>
@ -131,11 +175,16 @@ export default {
.compassIcon { .compassIcon {
background-color: white; background-color: white;
border-radius: 50%; border-radius: 50%;
width: 56px; width: 42px;
height: 56px; height: 42px;
box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12); box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);
-webkite-box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12); -webkite-box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);
} }
.compassIcon img {
width: 100%;
height: 100%;
}
</style> </style>
<style scoped> <style scoped>

View File

@ -49,7 +49,7 @@ export const REPORT_TYPES = {
}; };
export const MOCK_LOCATION = false; export const MOCK_LOCATION = false;
export const MOCK_LOCATION_UPDATE_INTERVAL = 30 * 1000; export const MOCK_LOCATION_UPDATE_INTERVAL = 10 * 1000;
export const UPDATE_REPORTS_DISTANCE_THRESHOLD = 500; export const UPDATE_REPORTS_DISTANCE_THRESHOLD = 500;

View File

@ -2,24 +2,12 @@
<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="latLng"> <v-flex xs12 fill-height v-if="latLng">
<Map :latLng="mapLatLng" :positionLatLng="latLng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onLongPress="showReportDialog" :onMoveEnd="onMapMoveEnd" :onMoveStart="onMapMoveStart"></Map> <Map :positionLatLng="latLng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onLongPress="showReportDialog"></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
fab fab
large
bottom bottom
right right
color="orange" color="orange"
@ -77,12 +65,6 @@ 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 {
@ -90,10 +72,8 @@ export default {
centering: false, centering: false,
dialog: false, dialog: false,
error: null, error: null,
hasMapMoved: false,
heading: null, heading: null,
latLng: null, latLng: null,
mapMovedLatLng: null,
noSleep: null, noSleep: null,
reportLat: null, reportLat: null,
reportLng: null, reportLng: null,
@ -203,23 +183,6 @@ 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>