Group Home/zoom/base-map into one top-left stack, NPS-style
Home was alone at top-left and zoom (NavigationControl) was down at bottom-right with GeolocateControl — split across two corners instead of grouped together like the National Park Service's own map controls (https://www.nps.gov/, screenshot: Home, zoom in/out, base map, all stacked in one place). Moved NavigationControl up to join Home (showCompass: false — this map never rotates, so a bearing-reset button would be dead weight), and added MapLayersButton, a small map-corner control that's a second entry point into the same Online/Offline panel LayerToggleControl already manages in the page's sidebar (both go through the same toggle() now, so there's one source of truth for whether the panel's open). GeolocateControl stays alone at bottom-right — it's a different action (go to my actual location) from Home (reset to the app's default view), which was worth clarifying since the two are easy to conflate.
This commit is contained in:
1 parent
be6d61e136
commit
215957382a
2 files changed
+70
-3
No files matched your search
+56
-2
@@ -127,6 +127,13 @@ class LayerToggleControl {
|
||||
if (open) notifySidePanelOpen(this._panel);
|
||||
}
|
||||
|
||||
// Public wrapper so a second entry point (MapLayersButton, a map corner
|
||||
// control) can open/close the same panel without reaching into a
|
||||
// "private" method by convention only.
|
||||
toggle() {
|
||||
this._togglePanel();
|
||||
}
|
||||
|
||||
setActive(name) {
|
||||
this._panel.querySelectorAll(".basemap-panel__option").forEach((button) => {
|
||||
button.classList.toggle("active", button.dataset.style === name);
|
||||
@@ -142,6 +149,38 @@ class LayerToggleControl {
|
||||
}
|
||||
}
|
||||
|
||||
// A small map-corner button (grouped with Home/zoom, see below) that's a
|
||||
// second entry point to the same panel LayerToggleControl already manages
|
||||
// in the page's own sidebar — matching the National Park Service's own
|
||||
// map control layout, which keeps zoom/home/base-map together on the map
|
||||
// rather than split between the map and a separate side rail.
|
||||
class MapLayersButton {
|
||||
constructor(layerToggle) {
|
||||
this._layerToggle = layerToggle;
|
||||
}
|
||||
|
||||
onAdd() {
|
||||
this._container = document.createElement("div");
|
||||
this._container.className = "maplibregl-ctrl maplibregl-ctrl-group";
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.title = "Base map";
|
||||
button.setAttribute("aria-label", "Base map");
|
||||
button.innerHTML = LAYERS_ICON;
|
||||
button.addEventListener("click", () => this._layerToggle.toggle());
|
||||
this._container.appendChild(button);
|
||||
return this._container;
|
||||
}
|
||||
|
||||
onRemove() {
|
||||
this._container.remove();
|
||||
}
|
||||
|
||||
getDefaultPosition() {
|
||||
return "top-left";
|
||||
}
|
||||
}
|
||||
|
||||
const map = new MaplibreMap({
|
||||
container: "map",
|
||||
style: ONLINE_STYLE,
|
||||
@@ -155,7 +194,6 @@ const map = new MaplibreMap({
|
||||
hash: "map",
|
||||
});
|
||||
|
||||
map.addControl(new NavigationControl(), "bottom-right");
|
||||
map.addControl(
|
||||
new GeolocateControl({
|
||||
positionOptions: { enableHighAccuracy: true },
|
||||
@@ -164,19 +202,34 @@ map.addControl(
|
||||
}),
|
||||
"bottom-right",
|
||||
);
|
||||
|
||||
// A compact top-left stack — Home, zoom, base map — matching the National
|
||||
// Park Service's own map control layout. Added in this order since
|
||||
// MapLibre stacks same-position controls in add order.
|
||||
//
|
||||
// homePosition/zoom pinned to the app's own default rather than left to the
|
||||
// button's own fallback (current center/zoom at construction) — now that
|
||||
// the URL hash can restore any view on load (see the Hash option above),
|
||||
// "current view" and "the default view" are no longer the same thing, and
|
||||
// a home button that resets to wherever you happened to load the page
|
||||
// wouldn't be a home button.
|
||||
// wouldn't be a home button. This is *not* "go to my location" — that's
|
||||
// GeolocateControl, above.
|
||||
map.addControl(new HomeButton({ homePosition: CENTER, zoom: ZOOM }), "top-left");
|
||||
// showCompass: false — this map never rotates, so a bearing-reset button
|
||||
// (NavigationControl's default third button) would just be dead weight.
|
||||
map.addControl(new NavigationControl({ showCompass: false }), "top-left");
|
||||
|
||||
const sidebar = document.getElementById("sidebar");
|
||||
|
||||
const layerToggle = new LayerToggleControl(applyStyle);
|
||||
layerToggle.mount(sidebar);
|
||||
layerToggle.setActive("online");
|
||||
// The sidebar already has a "Base map" icon (opens the same panel) —
|
||||
// this is a second entry point for it, grouped with Home/zoom on the map
|
||||
// itself rather than off in the page's own side rail, matching NPS's
|
||||
// layout. Added after mount() since it reuses that panel/toggle state.
|
||||
const mapLayersButton = new MapLayersButton(layerToggle);
|
||||
map.addControl(mapLayersButton, "top-left");
|
||||
|
||||
const profilePanel = new TrackProfilePanel(map);
|
||||
profilePanel.mount();
|
||||
@@ -202,6 +255,7 @@ fetch("/api/offline-tiles")
|
||||
applyStyle("offline");
|
||||
} else {
|
||||
layerToggle.remove();
|
||||
map.removeControl(mapLayersButton);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
Reference in new issue
Block a user