your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import type { Item } from '$lib/types';
3 import { MapLibre, Projection, Marker } from 'svelte-maplibre-gl';
4
5 let { item = $bindable() }: { item: Item } = $props();
6
7 let center = $state({ lng: parseFloat(item.cardData.lon), lat: parseFloat(item.cardData.lat) });
8 let showAttribution = $state(false);
9</script>
10
11<div class="absolute inset-0 isolate h-full w-full">
12 <MapLibre
13 class="h-full w-full"
14 style="https://tiles.openfreemap.org/styles/liberty"
15 zoom={item.cardData.zoom}
16 {center}
17 attributionControl={false}
18 dragPan={false}
19 dragRotate={false}
20 keyboard={false}
21 touchZoomRotate={true}
22 scrollZoom={true}
23 boxZoom={false}
24 pitchWithRotate={false}
25 touchPitch={false}
26 >
27 <Projection type="globe" />
28
29 <Marker bind:lnglat={center}>
30 {#snippet content()}
31 <div class="from-accent-400 size-10 rounded-full bg-radial via-transparent p-3">
32 <div class="bg-accent-500 size-4 rounded-full ring-2 ring-white"></div>
33 </div>
34 {/snippet}
35 </Marker>
36 </MapLibre>
37
38 {#snippet infoIcon()}
39 <svg
40 xmlns="http://www.w3.org/2000/svg"
41 width="24"
42 height="24"
43 fill-rule="evenodd"
44 viewBox="0 0 20 20"
45 >
46 <path
47 d="M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0"
48 />
49 </svg>
50 {/snippet}
51
52 {#snippet attributionText()}
53 <a
54 href="https://openfreemap.org"
55 target="_blank"
56 rel="noopener noreferrer"
57 class="text-black/75 no-underline hover:underline"
58 onclick={(e) => e.stopPropagation()}>OpenFreeMap</a
59 >
60 <a
61 href="https://openmaptiles.org"
62 target="_blank"
63 rel="noopener noreferrer"
64 class="text-black/75 no-underline hover:underline"
65 onclick={(e) => e.stopPropagation()}>© OpenMapTiles</a
66 >
67 Data from
68 <a
69 href="https://www.openstreetmap.org/copyright"
70 target="_blank"
71 rel="noopener noreferrer"
72 class="text-black/75 no-underline hover:underline"
73 onclick={(e) => e.stopPropagation()}>OpenStreetMap</a
74 >
75 {/snippet}
76
77 {#if showAttribution}
78 <div
79 class="absolute right-2.5 bottom-2.5 z-10 rounded-xl bg-white text-black"
80 style="width: calc(100% - 20px); max-width: 12rem;"
81 >
82 <button
83 class="float-right flex size-6 cursor-pointer items-center justify-center rounded-full shadow-[0_0_6px_rgba(59,130,246,0.6)]"
84 onclick={() => (showAttribution = false)}
85 aria-label="Toggle attribution"
86 >
87 {@render infoIcon()}
88 </button>
89 <div class="p-2 text-left text-xs leading-snug text-black/75">
90 {@render attributionText()}
91 </div>
92 </div>
93 {:else}
94 <button
95 class="absolute right-2.5 bottom-2.5 z-10 flex size-6 items-center justify-center rounded-full bg-white text-black"
96 onclick={() => (showAttribution = true)}
97 aria-label="Toggle attribution"
98 >
99 {@render infoIcon()}
100 </button>
101 {/if}
102</div>