From b4c3f5c88df738e41745f9559d1445be9919f1da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Mon, 27 Apr 2026 15:37:13 +0100 Subject: [PATCH] Improve map centering on mobile --- app/components/map.gjs | 27 +++++++++++++++++---------- app/styles/app.css | 4 ++-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/app/components/map.gjs b/app/components/map.gjs index fcf9995..7ccaee8 100644 --- a/app/components/map.gjs +++ b/app/components/map.gjs @@ -782,14 +782,19 @@ export default class MapComponent extends Component { // Check if mobile (width <= 768px matches CSS) if (size[0] <= 768) { // On mobile, the bottom 50% is covered by the sheet. - // We want the pin to be in the center of the TOP 50% (visible area). - // That means the pin should be at y = height * 0.25 (25% down from top). - // The map center is at y = height * 0.50. - // So the pin is "above" the center by 25% of the height in pixels. - // To put the pin there, the map center needs to be "below" the pin by that amount. + // We want the pin to be in the center of the TOP 50% (visible area), minus the header. const height = size[1]; - const offsetPixels = height * 0.25; // Distance from desired pin pos to map center + const headerEl = document.querySelector('.app-header'); + const headerHeight = headerEl ? headerEl.offsetHeight : 60; + + // Visible area is from headerHeight to height / 2 (bottom sheet covers bottom 50%) + const visibleCenterY = headerHeight + (height / 2 - headerHeight) / 2; + + // The map center is at y = height * 0.50. + // So the pin is "above" the center by (height/2 - visibleCenterY) pixels. + // To put the pin there, the map center needs to be "below" the pin by that amount. + const offsetPixels = height / 2 - visibleCenterY; // Distance from desired pin pos to map center const offsetMapUnits = offsetPixels * resolution; // Shift center SOUTH (decrease Y). @@ -849,6 +854,9 @@ export default class MapComponent extends Component { let targetPixelY = pixel[1]; let needsPan = false; + const headerEl = document.querySelector('.app-header'); + const headerHeight = headerEl ? headerEl.offsetHeight : 60; + // 1. Mobile Bottom Sheet Logic (Screen <= 768px) if (size[0] <= 768) { const height = size[1]; @@ -856,7 +864,7 @@ export default class MapComponent extends Component { // If in bottom half if (pixel[1] > splitPoint) { - targetPixelY = height * 0.25; // Target: Center of top half + targetPixelY = headerHeight + (height / 2 - headerHeight) / 2; // Target: Center of visible area above bottom sheet needsPan = true; } } @@ -877,11 +885,10 @@ export default class MapComponent extends Component { // 3. Header Logic (Any screen size) // Check if the (potentially new) target Y is under the header - const headerHeight = 60; - const minTopDistance = headerHeight + 20; // 80px + const minTopDistance = headerHeight + 20; // Provide some padding if (targetPixelY < minTopDistance) { - targetPixelY = minTopDistance + 30; // Move it to ~110px, clear of header + targetPixelY = minTopDistance + 30; // Move it clear of header needsPan = true; } diff --git a/app/styles/app.css b/app/styles/app.css index 3115383..0be48a5 100644 --- a/app/styles/app.css +++ b/app/styles/app.css @@ -1365,10 +1365,10 @@ span.icon { @media (width <= 768px) { /* Sidebar/Bottom Sheet is open (Mobile: Bottom 50%) */ - /* Center Y = (height/2) / 2 = height/4 = 25% */ + /* Center Y = (height/2) / 2 = height/4 = 25% + half header height */ .map-container.sidebar-open .map-crosshair { left: 50%; /* Reset desktop shift */ - top: 25%; + top: calc(25% + 30px); /* 30px approx half header height */ } }