fix(map): centre a clicked place above the bottom inspector panel

Selecting a place panned/flew it to the dead centre of the screen, where it sat
behind the detail card. Both overlays now bias the target into the visible area
above the bottom panel (Leaflet offsets the pan by the inspector inset; Mapbox
passes the padding to flyTo).
This commit is contained in:
Maurice
2026-06-11 15:44:44 +02:00
parent 6ec452917a
commit 0936103f04
2 changed files with 13 additions and 1 deletions
+11 -1
View File
@@ -134,7 +134,17 @@ function SelectionController({ places, selectedPlaceId, dayPlaces, paddingOpts }
// Pan to the selected place without changing zoom // Pan to the selected place without changing zoom
const selected = places.find(p => p.id === selectedPlaceId) const selected = places.find(p => p.id === selectedPlaceId)
if (selected?.lat && selected?.lng) { if (selected?.lat && selected?.lng) {
map.panTo([selected.lat, selected.lng], { animate: true }) const latlng: [number, number] = [selected.lat, selected.lng]
const tl = (paddingOpts as { paddingTopLeft?: [number, number] }).paddingTopLeft
const br = (paddingOpts as { paddingBottomRight?: [number, number] }).paddingBottomRight
if (tl && br && typeof map.project === 'function' && typeof map.unproject === 'function') {
// Bias the place into the area above the bottom inspector panel instead of
// dead-centre, so it doesn't sit behind the detail card.
const point = map.project(latlng).add([(br[0] - tl[0]) / 2, (br[1] - tl[1]) / 2])
map.panTo(map.unproject(point), { animate: true })
} else {
map.panTo(latlng, { animate: true })
}
} }
} }
prev.current = selectedPlaceId prev.current = selectedPlaceId
+2
View File
@@ -553,6 +553,8 @@ export function MapViewGL({
zoom: Math.max(map.getZoom(), 14), zoom: Math.max(map.getZoom(), 14),
pitch: mapbox3d ? 45 : 0, pitch: mapbox3d ? 45 : 0,
duration: 400, duration: 400,
// Bias the place above the bottom inspector panel instead of dead-centre.
padding: paddingOpts,
}) })
} catch { /* noop */ } } catch { /* noop */ }
}, [selectedPlaceId, mapbox3d]) // eslint-disable-line react-hooks/exhaustive-deps }, [selectedPlaceId, mapbox3d]) // eslint-disable-line react-hooks/exhaustive-deps