Pan map on mobile when pin obscured by sidebar
This commit is contained in:
parent
360e511849
commit
fa4115b714
@ -359,6 +359,8 @@ export default class MapComponent extends Component {
|
|||||||
// Force reflow
|
// Force reflow
|
||||||
void this.selectedPinElement.offsetWidth;
|
void this.selectedPinElement.offsetWidth;
|
||||||
this.selectedPinElement.classList.add('active');
|
this.selectedPinElement.classList.add('active');
|
||||||
|
|
||||||
|
this.panIfObscured(coords);
|
||||||
} else {
|
} else {
|
||||||
this.selectedPinElement.classList.remove('active');
|
this.selectedPinElement.classList.remove('active');
|
||||||
// Hide it effectively by moving it away or just relying on display:none in CSS
|
// 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)
|
// Re-fetch bookmarks when the version changes (triggered by parent action or service)
|
||||||
updateBookmarks = modifier(() => {
|
updateBookmarks = modifier(() => {
|
||||||
// Depend on the tracked storage.savedPlaces to automatically update when they change
|
// Depend on the tracked storage.savedPlaces to automatically update when they change
|
||||||
|
|||||||
@ -312,3 +312,23 @@ span.icon {
|
|||||||
opacity: 1;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user