From 1eebfc90faef5f0d94593bd78eea6cb5f04b7d2d Mon Sep 17 00:00:00 2001 From: Franzz Date: Tue, 9 Jun 2026 23:42:38 +0200 Subject: [PATCH] Fix center on pitched map --- src/components/project.vue | 57 +++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/src/components/project.vue b/src/components/project.vue index 959131e..c662a7d 100644 --- a/src/components/project.vue +++ b/src/components/project.vue @@ -63,6 +63,8 @@ export default { mapInitializing: false, markerHeight: 32, //FIXME mapPadding: 16 + 32, //1rem + marker height + maxZoom: 15, + initialPitch: 45, lightbox: null, hikes: { colors: {}, @@ -477,7 +479,8 @@ export default { this.map.jumpTo({ center: new LngLat(oDefaultProject.longitude, oDefaultProject.latitude), zoom: Math.log2(iWorldSize / this.map.transform.tileSize), - pitch: 0 + pitch: 0, + bearing: 0 }); } //Direct link to marker @@ -485,34 +488,74 @@ export default { this.map.jumpTo({ center: new LngLat(oHashMarker.longitude, oHashMarker.latitude), zoom: 13, - pitch: 45 + pitch: this.initialPitch }); } //Blog Mode: Fit to last marker else if(this.project.mode == this.consts.modes.blog && oLastMarker) { this.map.jumpTo({ center: new LngLat(oLastMarker.longitude, oLastMarker.latitude), - zoom: 15, - pitch: 45 + zoom: this.maxZoom, + pitch: this.initialPitch, + bearing: 0 }); } //Pre Mode, Histo Mode, Blog Mode without markers or missing direct link marker: Fit to track else { let oBounds = new LngLatBounds(); + const aoTrackCoordinates = []; for(const iFeatureId in this.track.features) { oBounds = this.track.features[iFeatureId].geometry.coordinates.reduce( - (bounds, coord) => bounds.extend(coord), + (bounds, coord) => { + aoTrackCoordinates.push(coord); + return bounds.extend(coord); + }, oBounds ); } + this.map.fitBounds(oBounds, { padding: this.mapPadding, animate: false, - maxZoom: 15, - pitch: 45 + maxZoom: this.maxZoom, + pitch: this.initialPitch, + bearing: 0 }); + + this.fixPitchedCameraCenter(aoTrackCoordinates); } }, + fixPitchedCameraCenter(aoTrackCoordinates) { + //Project min/max coords (lat, lng) onto map rectangle corner points (x, y) + const oScreenBounds = aoTrackCoordinates.reduce((oBounds, coord) => { + const oPoint = this.map.project(coord); + return { + minX: Math.min(oBounds.minX, oPoint.x), + minY: Math.min(oBounds.minY, oPoint.y), + maxX: Math.max(oBounds.maxX, oPoint.x), + maxY: Math.max(oBounds.maxY, oPoint.y) + }; + }, { + minX: Infinity, + minY: Infinity, + maxX: -Infinity, + maxY: -Infinity + }); + + //Current Rectangle center + const oTrackCenter = { + x: (oScreenBounds.minX + oScreenBounds.maxX) / 2, + y: (oScreenBounds.minY + oScreenBounds.maxY) / 2 + }; + + //Convert back center point (x, y) to coords and Move map to the track center + this.map.jumpTo({ + center: this.map.unproject([ + oTrackCenter.x, + oTrackCenter.y + ]) + }); + }, addNewMarkers(aoMarkers) { //FIXME Use its own marker update API this.markers.push(...aoMarkers); aoMarkers.forEach(this.addMarker);