<script lang="ts">
import type maplibregl from 'maplibre-gl';
import MapLibre from 'svelte-maplibre/MapLibre.svelte';
import GeoJSON from 'svelte-maplibre/GeoJSON.svelte';
import FillLayer from 'svelte-maplibre/FillLayer.svelte';
import LineLayer from 'svelte-maplibre/LineLayer.svelte';
import { mapClasses } from '../styles.js';
import code from './+page.svelte?raw';
import CodeSample from '$site/CodeSample.svelte';
import states from '$site/states.json?url';
import { contrastingColor } from '$site/colors.js';
import { hoverStateFilter } from 'svelte-maplibre/filters.js';
import type { ExpressionSpecification } from 'maplibre-gl';
let showBorder = $state(true);
let showFill = $state(true);
let fillColor = $state('#006600');
let borderColor = $state('#003300');
let map: maplibregl.Map | undefined = $state();
let loaded = $state(false);
let textLayers: maplibregl.LayerSpecification[] = $derived(
map && loaded
? map.getStyle().layers.filter((layer) => {
return layer.type === 'symbol' && layer['source-layer'] === 'place';
})
: []
);
let colors = $derived(contrastingColor(fillColor));
$effect(() => {
for (let layer of textLayers) {
map?.setPaintProperty(layer.id, 'text-color', colors.textColor);
map?.setPaintProperty(layer.id, 'text-halo-color', colors.textOutlineColor);
}
});
let filterStates = $state(false);
let filter: ExpressionSpecification | undefined = $derived(
filterStates ? ['==', 'T', ['slice', ['get', 'NAME'], 0, 1]] : undefined
);
</script>
<div class="grid w-full max-w-md items-center gap-y-2 self-start">
<label><input type="checkbox" bind:checked={showFill} /> Show fill</label>
<label><input type="color" bind:value={fillColor} /> Fill Color </label>
<label><input type="checkbox" bind:checked={showBorder} /> Show border</label>
<label><input type="color" bind:value={borderColor} /> Border Color </label>
</div>
<label
><input type="checkbox" bind:checked={filterStates} /> Only show states starting with 'T'</label
>
<MapLibre
bind:map
bind:loaded
style="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
class={mapClasses}
standardControls
center={[-98.137, 40.137]}
zoom={4}
>
<GeoJSON id="states" data={states} promoteId="STATEFP">
{#if showFill}
<FillLayer
paint={{
'fill-color': hoverStateFilter(fillColor, colors.hoverBgColor),
'fill-opacity': 0.5,
}}
{filter}
beforeLayerType="symbol"
manageHoverState
/>
{/if}
{#if showBorder}
<LineLayer
layout={{ 'line-cap': 'round', 'line-join': 'round' }}
paint={{ 'line-color': borderColor, 'line-width': 3 }}
beforeLayerType="symbol"
/>
{/if}
</GeoJSON>
</MapLibre>