Files
gpx.studio/website/src/lib/components/map/layer-control/LayerControl.svelte

120 lines
4.1 KiB
Svelte
Raw Normal View History

2025-06-21 21:07:36 +02:00
<script lang="ts">
import CustomControl from '$lib/components/map/custom-control/CustomControl.svelte';
import LayerTree from './LayerTree.svelte';
2025-10-23 18:58:33 +02:00
import { OverpassLayer } from './overpass-layer';
2025-06-21 21:07:36 +02:00
import { Separator } from '$lib/components/ui/separator';
import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
import { Layers } from '@lucide/svelte';
2025-10-17 23:54:45 +02:00
import { settings } from '$lib/logic/settings';
import { map } from '$lib/components/map/map';
2025-06-21 21:07:36 +02:00
let container: HTMLDivElement;
2025-10-17 23:54:45 +02:00
let overpassLayer: OverpassLayer;
2025-06-21 21:07:36 +02:00
const {
currentBasemap,
previousBasemap,
currentOverlays,
currentOverpassQueries,
selectedBasemapTree,
selectedOverlayTree,
selectedOverpassTree,
} = settings;
2026-01-30 21:01:24 +01:00
map.onLoad((_map: maplibregl.Map) => {
2025-10-17 23:54:45 +02:00
if (overpassLayer) {
overpassLayer.remove();
}
overpassLayer = new OverpassLayer(_map, map.layerEventManager!);
2025-10-17 23:54:45 +02:00
overpassLayer.add();
});
2025-06-21 21:07:36 +02:00
let open = $state(false);
function openLayerControl() {
open = true;
}
function closeLayerControl() {
open = false;
}
let cancelEvents = $state(false);
</script>
<CustomControl class="group min-w-[29px] min-h-[29px] overflow-hidden">
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
bind:this={container}
class="size-full"
onmouseenter={openLayerControl}
onmouseleave={closeLayerControl}
onpointerenter={() => {
if (!open) {
cancelEvents = true;
openLayerControl();
setTimeout(() => {
cancelEvents = false;
}, 500);
}
}}
>
<div
class="flex flex-row justify-center items-center delay-100 transition-[opacity] duration-0 {open
? 'opacity-0 size-0 delay-0'
: 'w-[29px] h-[29px]'}"
>
<Layers size="20" />
</div>
<div
class="transition-[grid-template-rows grid-template-cols] grid grid-rows-[0fr] grid-cols-[0fr] duration-150 h-full {open
? 'grid-rows-[1fr] grid-cols-[1fr]'
: ''} {cancelEvents ? 'pointer-events-none' : ''}"
>
2025-10-18 18:51:11 +02:00
<ScrollArea class="overflow-hidden">
2025-06-21 21:07:36 +02:00
<div class="h-fit">
2025-10-18 18:51:11 +02:00
<div class="p-2 ml-1">
2025-06-21 21:07:36 +02:00
<LayerTree
2025-10-17 23:54:45 +02:00
layerTree={$selectedBasemapTree}
2025-06-21 21:07:36 +02:00
name="basemaps"
2025-10-17 23:54:45 +02:00
selected={$currentBasemap}
2025-06-21 21:07:36 +02:00
onselect={(value) => {
2025-10-17 23:54:45 +02:00
$previousBasemap = $currentBasemap;
$currentBasemap = value;
2025-06-21 21:07:36 +02:00
}}
/>
</div>
<Separator class="w-full" />
2025-10-18 18:51:11 +02:00
<div class="p-2 ml-1">
2025-10-17 23:54:45 +02:00
{#if $currentOverlays}
2025-06-21 21:07:36 +02:00
<LayerTree
2025-10-17 23:54:45 +02:00
layerTree={$selectedOverlayTree}
2025-06-21 21:07:36 +02:00
name="overlays"
multiple={true}
2025-10-17 23:54:45 +02:00
bind:checked={$currentOverlays}
2025-06-21 21:07:36 +02:00
/>
{/if}
</div>
<Separator class="w-full" />
2025-10-18 18:51:11 +02:00
<div class="p-2 ml-1">
2025-10-17 23:54:45 +02:00
{#if $currentOverpassQueries}
2025-06-21 21:07:36 +02:00
<LayerTree
2025-10-17 23:54:45 +02:00
layerTree={$selectedOverpassTree}
2025-06-21 21:07:36 +02:00
name="overpass"
multiple={true}
2025-10-17 23:54:45 +02:00
bind:checked={$currentOverpassQueries}
2025-06-21 21:07:36 +02:00
/>
{/if}
</div>
</div>
</ScrollArea>
</div>
</div>
</CustomControl>
<svelte:window
2025-11-10 13:11:44 +01:00
on:click={(e: MouseEvent) => {
const target = e.target as Node | null;
if (open && !cancelEvents && target && container && !container.contains(target)) {
2025-06-21 21:07:36 +02:00
closeLayerControl();
}
}}
/>