mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-31 15:43:25 +00:00
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
![]() |
import { TrackPoint, Waypoint } from "gpx";
|
||
|
import mapboxgl from "mapbox-gl";
|
||
|
import { tick } from "svelte";
|
||
|
import { get, writable, type Writable } from "svelte/store";
|
||
|
import MapPopupComponent from "./MapPopup.svelte";
|
||
|
|
||
|
export type PopupItem<T = Waypoint | TrackPoint | any> = {
|
||
|
item: T;
|
||
|
fileId?: string;
|
||
|
};
|
||
|
|
||
|
export class MapPopup {
|
||
|
map: mapboxgl.Map;
|
||
|
popup: mapboxgl.Popup;
|
||
|
item: Writable<PopupItem | null> = writable(null);
|
||
|
maybeHideBinded = this.maybeHide.bind(this);
|
||
|
|
||
|
constructor(map: mapboxgl.Map, options?: mapboxgl.PopupOptions) {
|
||
|
this.map = map;
|
||
|
this.popup = new mapboxgl.Popup(options);
|
||
|
|
||
|
let component = new MapPopupComponent({
|
||
|
target: document.body,
|
||
|
props: {
|
||
|
item: this.item
|
||
|
}
|
||
|
});
|
||
|
|
||
|
tick().then(() => this.popup.setDOMContent(component.container));
|
||
|
}
|
||
|
|
||
|
setItem(item: PopupItem | null) {
|
||
|
this.item.set(item);
|
||
|
if (item === null) {
|
||
|
this.hide();
|
||
|
} else {
|
||
|
tick().then(() => this.show());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
show() {
|
||
|
const i = get(this.item);
|
||
|
if (i === null) {
|
||
|
this.hide();
|
||
|
return;
|
||
|
}
|
||
|
this.popup.setLngLat(this.getCoordinates()).addTo(this.map);
|
||
|
this.map.on('mousemove', this.maybeHideBinded);
|
||
|
}
|
||
|
|
||
|
maybeHide(e: mapboxgl.MapMouseEvent) {
|
||
|
const i = get(this.item);
|
||
|
if (i === null) {
|
||
|
this.hide();
|
||
|
return;
|
||
|
}
|
||
|
if (this.map.project(this.getCoordinates()).dist(this.map.project(e.lngLat)) > 60) {
|
||
|
this.hide();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hide() {
|
||
|
this.popup.remove();
|
||
|
this.map.off('mousemove', this.maybeHideBinded);
|
||
|
}
|
||
|
|
||
|
remove() {
|
||
|
this.popup.remove();
|
||
|
}
|
||
|
|
||
|
getCoordinates() {
|
||
|
const i = get(this.item);
|
||
|
if (i === null) {
|
||
|
return new mapboxgl.LngLat(0, 0);
|
||
|
}
|
||
|
return (i.item instanceof Waypoint || i.item instanceof TrackPoint) ? i.item.getCoordinates() : new mapboxgl.LngLat(i.item.lon, i.item.lat);
|
||
|
}
|
||
|
}
|