Fit mobile searches above results sheet

This commit is contained in:
Edward Betts 2026-08-15 13:09:33 +01:00
parent 98b5951cbb
commit ae5ad9fabc
2 changed files with 71 additions and 11 deletions

View file

@ -270,6 +270,7 @@ function renderStops(data, fitMap = true, sortOrigin = null, preserveSelection =
radius: 7, color: '#0d6efd', fillColor: '#fff', fillOpacity: 1, weight: 3,
}).bindTooltip(data.location.label).addTo(map);
}
if (isMobile() && data.kind !== 'map') setPanel(true);
for (const stop of stops) {
const button = document.createElement('button');
@ -305,14 +306,15 @@ function renderStops(data, fitMap = true, sortOrigin = null, preserveSelection =
? 'No transport stops were found in this map area.'
: 'No transport stops were found within 1 km.';
list.appendChild(empty);
if (fitMap && data.location) moveMap(() => map.setView([data.location.lat, data.location.lon], 16));
if (fitMap && data.location) {
moveMap(() => centrePointInVisibleMap(data.location.lat, data.location.lon, 16));
}
} else if (fitMap) {
const bounds = markers.getBounds();
if (searchMarker) bounds.extend(searchMarker.getLatLng());
moveMap(() => map.fitBounds(bounds, {padding: [30, 30], maxZoom: 17}));
moveMap(() => map.fitBounds(bounds, visibleMapFitOptions()));
if (data.kind === 'atco' && stops.length === 1) selectStop(stops[0]);
}
if (isMobile() && data.kind !== 'map') setPanel(true);
}
/** Show UK-only Nominatim matches and wait for the user to choose one. */
@ -410,16 +412,37 @@ function clearHoveredStop() {
hoveredMarkerHalo = null;
}
/** Return how many map pixels are covered by the open mobile sheet. */
function mobilePanelOverlayHeight() {
if (isMobile() && byId('sidebar').classList.contains('panel-open')) {
return Math.min(map.getSize().y, byId('sidebar').getBoundingClientRect().height);
}
return 0;
}
/** Leaflet fit options that reserve the area hidden by the mobile sheet. */
function visibleMapFitOptions() {
const overlayHeight = mobilePanelOverlayHeight();
if (!overlayHeight) return {padding: [30, 30], maxZoom: 17};
return {
paddingTopLeft: [30, 30],
paddingBottomRight: [30, overlayHeight + 30],
maxZoom: 17,
};
}
/** Centre a coordinate in the portion of the map not covered by the mobile sheet. */
function centrePointInVisibleMap(lat, lon, zoom) {
const point = map.project(L.latLng(lat, lon), zoom);
const adjustedCenter = map.unproject(
point.add(L.point(0, mobilePanelOverlayHeight() / 2)), zoom
);
map.setView(adjustedCenter, zoom);
}
/** Centre a selected stop in the portion of the map not covered by the mobile sheet. */
function centreSelectedStop(stop) {
const zoom = Math.max(map.getZoom(), 17);
let verticalOffset = 0;
if (isMobile() && byId('sidebar').classList.contains('panel-open')) {
verticalOffset = Math.min(map.getSize().y, byId('sidebar').getBoundingClientRect().height) / 2;
}
const stopPoint = map.project(L.latLng(stop.lat, stop.lon), zoom);
const adjustedCenter = map.unproject(stopPoint.add(L.point(0, verticalOffset)), zoom);
map.setView(adjustedCenter, zoom);
centrePointInVisibleMap(stop.lat, stop.lon, Math.max(map.getZoom(), 17));
}
function osmUrl(stop, edit = false) {