nidus-sync/static/js/map-locator-ro.js
Eli Ribble 31947c848a
Move static outside HTML. Start work on TypeScript bundle
It's not strictly HTML, so that's just correct.

This is just worth doing while building the new TypeScript bundle
2026-03-21 03:06:59 +00:00

125 lines
2.7 KiB
JavaScript

// A map that can be used to locate a single point by setting its location explicitly
// or by allowing the user to move a marker.
class MapLocatorReadOnly extends HTMLElement {
constructor() {
super();
// Create a shadow DOM
this.attachShadow({ mode: "open" });
// Initial render
this.render();
// markers shown on the map. Should be none or 1, generally.
this._markers = [];
}
// Lifecycle: when element is added to the DOM
connectedCallback() {
// Initialize the map when the element is added to the DOM
setTimeout(() => this._initializeMap(), 0);
}
disconnectedCallback() {
if (this._map) {
this._map.remove();
}
}
_initializeMap() {
console.log("Setting up the locator read-only...");
const marker_str = this.getAttribute("marker");
const marker = JSON.parse(marker_str);
const mapElement = this.shadowRoot.querySelector("#map");
this._map = new maplibregl.Map({
container: mapElement,
center: marker.coordinates,
//style: "https://tiles.stadiamaps.com/styles/alidade_smooth.json",
style: "https://tiles.stadiamaps.com/styles/osm_bright.json",
zoom: 16,
});
this._map.on("load", () => {
console.log("map locator read-only loaded");
const m = new maplibregl.Marker({
color: "#FF0000",
draggable: true,
})
.setLngLat(marker.coordinates)
.addTo(this._map);
this.dispatchEvent(
new CustomEvent("load", {
bubbles: true,
composed: true, // Allows event to cross shadow DOM boundary
detail: {
map: this,
},
}),
);
});
this._map.on("zoomend", (e) => {
this.dispatchEvent(
new CustomEvent("zoomend", {
bubbles: true,
composed: true,
detail: e,
}),
);
});
}
// Initial render of component
render() {
this.shadowRoot.innerHTML = `
<style>
@import url("//unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.css");
#map {
height: 100%;
width:100%;
}
#map img {
max-width: none;
min-width: 0px;
height: auto;
}
</style>
<div id="map"></div>
`;
}
GetZoom() {
return this._map.getZoom();
}
JumpTo(args) {
this._map.jumpTo(args);
}
PanTo(coords, options) {
this._map.panTo(coords, options);
}
SetMarker(coords) {
console.log("Setting map marker", coords);
this._markers.forEach((marker) => marker.remove());
const marker = new maplibregl.Marker({
color: "#FF0000",
draggable: true,
})
.setLngLat(coords)
.addTo(this._map);
marker.on("dragend", (e) => {
const markerDraggedEvent = new CustomEvent("markerdragend", {
detail: {
marker: marker,
},
});
this.dispatchEvent(markerDraggedEvent);
});
this._markers = [marker];
}
}
customElements.define("map-locator-ro", MapLocatorReadOnly);