47 lines
1.5 KiB
Svelte
47 lines
1.5 KiB
Svelte
<script lang="ts">
|
|
import * as L from 'leaflet';
|
|
import 'leaflet/dist/leaflet.css';
|
|
import lmiUrl from 'leaflet/dist/images/marker-icon.png';
|
|
import lmi2Url from 'leaflet/dist/images/marker-icon-2x.png';
|
|
import lmsUrl from 'leaflet/dist/images/marker-shadow.png';
|
|
import { onMount, type Snippet } from "svelte";
|
|
import type { SvelteHTMLElements } from "svelte/elements";
|
|
|
|
if (import.meta.env.MODE === 'production') {
|
|
// Fix bundling bug for leaflet default marker icon on production
|
|
L.Icon.Default.prototype.options.iconUrl = lmiUrl;
|
|
L.Icon.Default.prototype.options.iconRetinaUrl = lmi2Url;
|
|
L.Icon.Default.prototype.options.shadowUrl = lmsUrl;
|
|
}
|
|
|
|
type Props = {
|
|
x: number,
|
|
y: number,
|
|
children?: Snippet,
|
|
} & SvelteHTMLElements['div']
|
|
|
|
let { x, y, children, ...rest }: Props = $props();
|
|
|
|
let mapDiv: HTMLDivElement;
|
|
let popupDiv: HTMLDivElement;
|
|
let map: L.Map;
|
|
|
|
onMount(() => {
|
|
map = L.map(mapDiv).setView([x, y], 13);
|
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxZoom: 19,
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
}).addTo(map);
|
|
const marker = L.marker([x, y]).addTo(map);
|
|
if (children !== undefined)
|
|
marker.bindPopup(popupDiv, { closeOnClick: false }).openPopup();
|
|
});
|
|
</script>
|
|
|
|
<div bind:this={mapDiv} {...rest}>
|
|
</div>
|
|
<div class="hidden">
|
|
<div bind:this={popupDiv} class="h-full w-full">
|
|
{@render children?.()}
|
|
</div>
|
|
</div> |