your personal website on atproto - mirror blento.app
at improve-oauth-permissions 127 lines 3.4 kB view raw
1<script lang="ts"> 2 import type { Item } from '$lib/types'; 3 import { MapLibre, Projection, Marker } from 'svelte-maplibre-gl'; 4 import type maplibregl from 'maplibre-gl'; 5 6 let { item = $bindable(), isEditing = false }: { item: Item; isEditing?: boolean } = $props(); 7 8 let center = $state({ lng: parseFloat(item.cardData.lon), lat: parseFloat(item.cardData.lat) }); 9 let showAttribution = $state(false); 10 let map: maplibregl.Map | undefined = $state(); 11 12 const fixedCenter = { lng: parseFloat(item.cardData.lon), lat: parseFloat(item.cardData.lat) }; 13 14 function handleZoom() { 15 if (!isEditing && map) { 16 map.setCenter(fixedCenter); 17 } 18 } 19 20 $effect(() => { 21 if (!isEditing && map) { 22 map.getCanvas().style.touchAction = 'pan-x pan-y'; 23 } 24 }); 25</script> 26 27<div 28 class="absolute inset-0 isolate h-full w-full" 29 onfocusin={(e) => { 30 if (!isEditing && e.target instanceof HTMLElement) e.target.blur(); 31 }} 32> 33 <div class="h-full w-full"> 34 <MapLibre 35 bind:map 36 class="h-full w-full" 37 style="https://tiles.openfreemap.org/styles/liberty" 38 zoom={item.cardData.zoom} 39 {center} 40 attributionControl={false} 41 dragPan={isEditing} 42 dragRotate={false} 43 keyboard={false} 44 touchZoomRotate={true} 45 scrollZoom={true} 46 boxZoom={false} 47 pitchWithRotate={false} 48 touchPitch={false} 49 onzoom={handleZoom} 50 > 51 <Projection type="globe" /> 52 53 <Marker bind:lnglat={center}> 54 {#snippet content()} 55 <div class="from-accent-400 size-10 rounded-full bg-radial via-transparent p-3"> 56 <div class="bg-accent-500 size-4 rounded-full ring-2 ring-white"></div> 57 </div> 58 {/snippet} 59 </Marker> 60 </MapLibre> 61 </div> 62 63 {#snippet infoIcon()} 64 <svg 65 xmlns="http://www.w3.org/2000/svg" 66 width="24" 67 height="24" 68 fill-rule="evenodd" 69 viewBox="0 0 20 20" 70 > 71 <path 72 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" 73 /> 74 </svg> 75 {/snippet} 76 77 {#snippet attributionText()} 78 <a 79 href="https://openfreemap.org" 80 target="_blank" 81 rel="noopener noreferrer" 82 class="text-black/75 no-underline hover:underline" 83 onclick={(e) => e.stopPropagation()}>OpenFreeMap</a 84 > 85 <a 86 href="https://openmaptiles.org" 87 target="_blank" 88 rel="noopener noreferrer" 89 class="text-black/75 no-underline hover:underline" 90 onclick={(e) => e.stopPropagation()}>© OpenMapTiles</a 91 > 92 Data from 93 <a 94 href="https://www.openstreetmap.org/copyright" 95 target="_blank" 96 rel="noopener noreferrer" 97 class="text-black/75 no-underline hover:underline" 98 onclick={(e) => e.stopPropagation()}>OpenStreetMap</a 99 > 100 {/snippet} 101 102 {#if showAttribution} 103 <div 104 class="absolute right-2.5 bottom-2.5 z-10 rounded-xl bg-white text-black" 105 style="width: calc(100% - 20px); max-width: 12rem;" 106 > 107 <button 108 class="float-right flex size-6 cursor-pointer items-center justify-center rounded-full shadow-[0_0_6px_rgba(59,130,246,0.6)]" 109 onclick={() => (showAttribution = false)} 110 aria-label="Toggle attribution" 111 > 112 {@render infoIcon()} 113 </button> 114 <div class="p-2 text-left text-xs leading-snug text-black/75"> 115 {@render attributionText()} 116 </div> 117 </div> 118 {:else} 119 <button 120 class="absolute right-2.5 bottom-2.5 z-10 flex size-6 items-center justify-center rounded-full bg-white text-black" 121 onclick={() => (showAttribution = true)} 122 aria-label="Toggle attribution" 123 > 124 {@render infoIcon()} 125 </button> 126 {/if} 127</div>