Pan map on mobile when pin obscured by sidebar

This commit is contained in:
Râu Cao 2026-01-21 19:38:55 +07:00
parent 360e511849
commit fa4115b714
Signed by: raucao
GPG Key ID: 37036C356E56CC51
2 changed files with 57 additions and 0 deletions

View File

@ -359,6 +359,8 @@ export default class MapComponent extends Component {
// Force reflow
void this.selectedPinElement.offsetWidth;
this.selectedPinElement.classList.add('active');
this.panIfObscured(coords);
} else {
this.selectedPinElement.classList.remove('active');
// Hide it effectively by moving it away or just relying on display:none in CSS
@ -366,6 +368,41 @@ export default class MapComponent extends Component {
}
});
panIfObscured(coords) {
if (!this.mapInstance) return;
const size = this.mapInstance.getSize();
// Check if mobile (width <= 768px matches CSS)
if (size[0] > 768) return;
const pixel = this.mapInstance.getPixelFromCoordinate(coords);
const height = size[1];
// Sidebar covers the bottom 50%
const splitPoint = height / 2;
// If the pin is in the bottom half (y > splitPoint), it is obscured
if (pixel[1] > splitPoint) {
// Target position: Center of top half = height * 0.25
const targetY = height * 0.25;
const deltaY = pixel[1] - targetY;
const view = this.mapInstance.getView();
const center = view.getCenter();
const resolution = view.getResolution();
// Move the map center SOUTH (decrease Y) to move the pin UP (decrease pixel Y)
const deltaMapUnits = deltaY * resolution;
const newCenter = [center[0], center[1] - deltaMapUnits];
view.animate({
center: newCenter,
duration: 500,
easing: (t) => t * (2 - t) // Ease-out
});
}
}
// Re-fetch bookmarks when the version changes (triggered by parent action or service)
updateBookmarks = modifier(() => {
// Depend on the tracked storage.savedPlaces to automatically update when they change

View File

@ -312,3 +312,23 @@ span.icon {
opacity: 1;
}
}
@media (max-width: 768px) {
.sidebar {
top: auto;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 50vh;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
.sidebar-content {
overflow-y: auto;
/* Ensure content doesn't get hidden behind bottom safe areas on mobile */
padding-bottom: env(safe-area-inset-bottom, 20px);
}
}