56 lines
2.0 KiB
Svelte
56 lines
2.0 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from 'svelte';
|
|
|
|
import { storedLocation } from '$lib/stores/settings';
|
|
|
|
// a #zoom/lat/lng(/bearing/pitch) hash on OUR url is piped through to the
|
|
// map, so map positions can be bookmarked/shared via ombrella links
|
|
// (the reverse direction is not possible: the iframe is cross-origin, so
|
|
// its internal hash changes are unreadable from here)
|
|
let hashOverride = $state<string | null>(null);
|
|
|
|
onMount(() => {
|
|
const readHash = () => {
|
|
const hash = window.location.hash;
|
|
hashOverride = /^#\d+(\.\d+)?\/-?\d+(\.\d+)?\/-?\d+(\.\d+)?/.test(hash) ? hash : null;
|
|
};
|
|
readHash();
|
|
window.addEventListener('hashchange', readHash);
|
|
return () => window.removeEventListener('hashchange', readHash);
|
|
});
|
|
|
|
// the embedded map understands maplibre's #zoom/lat/lng hash, so the iframe
|
|
// opens focused on the selected location (zoomed out to regional scale);
|
|
// picking a new location while on this page recenters the map
|
|
const iframeSrc = $derived(
|
|
`https://maps.open-meteo.com/${
|
|
hashOverride ??
|
|
`#6/${$storedLocation.latitude.toFixed(3)}/${$storedLocation.longitude.toFixed(3)}`
|
|
}`
|
|
);
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>Weather Map | Open-Meteo.com</title>
|
|
<link rel="canonical" href="https://open-meteo.com/weather/maps" />
|
|
<meta name="description" content="Interactive weather map powered by Open-Meteo" />
|
|
</svelte:head>
|
|
|
|
<!-- Full-bleed map: the layout drops its padding for this route. The map
|
|
follows our theme through the color-scheme declared on :root/.dark -->
|
|
<div class="h-full w-full bg-background">
|
|
<!-- allow="cross-origin-isolated" delegates SharedArrayBuffer use to the
|
|
map; it only takes effect when this site itself is served with
|
|
COOP/COEP headers (see README, Deployment) -->
|
|
<iframe
|
|
src={iframeSrc}
|
|
title="Open-Meteo Interactive Map"
|
|
loading="lazy"
|
|
allowfullscreen
|
|
allow="cross-origin-isolated"
|
|
referrerpolicy="no-referrer"
|
|
class="block h-full w-full border-0"
|
|
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
|
|
></iframe>
|
|
</div>
|