maplair
Version:
JavaScript library for mobile-friendly interactive maps
192 lines (191 loc) • 5.44 kB
JavaScript
import { setOptions } from "../core/Util.js";
import { Point } from "../geometry/Point.js";
import { setPosition, toBack, toFront } from "../dom/DomUtil.js";
import { LatLng } from "../geo/LatLng.js";
import { Layer } from "./Layer.js";
import { FeatureGroup } from "./FeatureGroup.js";
//#region src/layer/DivOverlay.js
var DivOverlay = class DivOverlay extends Layer {
static {
this.setDefaultOptions({
interactive: false,
offset: [0, 0],
className: "",
pane: void 0,
content: ""
});
}
constructor(options, source) {
super();
if (options instanceof LatLng || Array.isArray(options)) {
this._latlng = new LatLng(options);
setOptions(this, source);
} else {
setOptions(this, options);
this._source = source;
}
if (this.options.content) this._content = this.options.content;
this.callInitHooks(DivOverlay);
}
openOn(map) {
map = arguments.length ? map : this._source._map;
if (!map.hasLayer(this)) map.addLayer(this);
return this;
}
close() {
this._map?.removeLayer(this);
return this;
}
toggle(layer) {
if (this._map) this.close();
else {
if (arguments.length) this._source = layer;
else layer = this._source;
this._prepareOpen();
this.openOn(layer._map);
}
return this;
}
onAdd(map) {
this._zoomAnimated = map._zoomAnimated;
if (!this._container) this._initLayout();
if (map._fadeAnimated) this._container.style.opacity = 0;
clearTimeout(this._removeTimeout);
this.getPane().appendChild(this._container);
this.update();
if (map._fadeAnimated) this._container.style.opacity = 1;
this.bringToFront();
if (this.options.interactive) {
this._container.classList.add("maplair-interactive");
this.addInteractiveTarget(this._container);
}
}
onRemove(map) {
if (map._fadeAnimated) {
this._container.style.opacity = 0;
this._removeTimeout = setTimeout(() => this._container.remove(), 200);
} else this._container.remove();
if (this.options.interactive) {
this._container.classList.remove("maplair-interactive");
this.removeInteractiveTarget(this._container);
}
}
getLatLng() {
return this._latlng;
}
setLatLng(latlng) {
this._latlng = new LatLng(latlng);
if (this._map) {
this._updatePosition();
this._adjustPan();
}
return this;
}
getContent() {
return this._content;
}
setContent(content) {
this._content = content;
this.update();
return this;
}
getElement() {
return this._container;
}
update() {
if (!this._map) return;
this._container.style.visibility = "hidden";
this._updateContent();
this._updateLayout();
this._updatePosition();
this._container.style.visibility = "";
this._adjustPan();
}
getEvents() {
const events = {
zoom: this._updatePosition,
viewreset: this._updatePosition
};
if (this._zoomAnimated) events.zoomanim = this._animateZoom;
return events;
}
isOpen() {
return !!this._map && this._map.hasLayer(this);
}
bringToFront() {
if (this._map) toFront(this._container);
return this;
}
bringToBack() {
if (this._map) toBack(this._container);
return this;
}
_prepareOpen(latlng) {
let source = this._source;
if (!source._map) return false;
if (source instanceof FeatureGroup) {
source = null;
for (const layer of Object.values(this._source._layers)) if (layer._map) {
source = layer;
break;
}
if (!source) return false;
this._source = source;
}
if (!latlng) {
if (source.getCenter) latlng = source.getCenter();
else if (source.getLatLng) latlng = source.getLatLng();
else if (source.getBounds) latlng = source.getBounds().getCenter();
else throw new Error("Unable to get source layer LatLng.");
}
this.setLatLng(latlng);
if (this._map) this.update();
return true;
}
_updateContent() {
if (!this._content) return;
const node = this._contentNode;
const content = typeof this._content === "function" ? this._content(this._source ?? this) : this._content;
if (typeof content === "string") node.innerHTML = content;
else {
while (node.hasChildNodes()) node.removeChild(node.firstChild);
node.appendChild(content);
}
this.fire("contentupdate");
}
_updatePosition() {
if (!this._map) return;
const pos = this._map.latLngToLayerPoint(this._latlng), anchor = this._getAnchor();
let offset = new Point(this.options.offset);
if (this._zoomAnimated) setPosition(this._container, pos.add(anchor));
else offset = offset.add(pos).add(anchor);
const bottom = this._containerBottom = -offset.y, left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x;
this._container.style.bottom = `${bottom}px`;
this._container.style.left = `${left}px`;
}
_getAnchor() {
return [0, 0];
}
static register(MaplairMap) {
MaplairMap.include({ _initOverlay(OverlayClass, content, latlng, options) {
let overlay = content;
if (!(overlay instanceof OverlayClass)) overlay = new OverlayClass(options).setContent(content);
if (latlng) overlay.setLatLng(latlng);
return overlay;
} });
Layer.include({ _initOverlay(OverlayClass, old, content, options) {
let overlay = content;
if (overlay instanceof OverlayClass) {
setOptions(overlay, options);
overlay._source = this;
} else {
overlay = old && !options ? old : new OverlayClass(options, this);
overlay.setContent(content);
}
return overlay;
} });
}
};
//#endregion
export { DivOverlay };
//# sourceMappingURL=DivOverlay.js.map