Allow cluster viewing

This commit is contained in:
Matthias Rupp 2023-05-01 21:03:52 -11:00
parent d48b0f7a1d
commit f49e122361
3 changed files with 71 additions and 24 deletions

View file

@ -1,6 +1,7 @@
<script lang="ts" context="module">
import { createContext } from '$lib/utils/context';
// @ts-ignore
const { get: getContext, set: setClusterContext } = createContext<() => L.MarkerClusterGroup>();
export const getClusterContext = () => {
@ -13,45 +14,66 @@
import 'leaflet.markercluster';
import { getMapContext } from './map.svelte';
import { MapMarkerResponseDto, getFileUrl } from '@api';
import { Marker, Icon } from 'leaflet';
import { assetInteractionStore } from '$lib/stores/asset-interaction.store';
import L from 'leaflet';
import { createEventDispatcher } from 'svelte';
class AssetMarker extends L.Marker {
marker: MapMarkerResponseDto;
constructor(marker: MapMarkerResponseDto) {
super([marker.lat, marker.lon], {
icon: new L.Icon({
iconUrl: getFileUrl(marker.id, true),
iconRetinaUrl: getFileUrl(marker.id, true),
iconSize: [60, 60],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
tooltipAnchor: [16, -28],
shadowSize: [41, 41]
}),
});
this.marker = marker;
}
getAssetId(): string {
return this.marker.id;
}
}
const dispatch = createEventDispatcher<{ view: { assets: string[] } }>();
export let markers: MapMarkerResponseDto[];
const map = getMapContext();
// @ts-ignore
let cluster: L.MarkerClusterGroup;
setClusterContext(() => cluster);
onMount(() => {
// @ts-ignore
cluster = new L.MarkerClusterGroup({
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
spiderfyOnMaxZoom: true,
zoomToBoundsOnClick: false,
spiderfyOnMaxZoom: false,
maxClusterRadius: 30,
spiderLegPolylineOptions: { opacity: 0 },
spiderfyDistanceMultiplier: 3
});
// @ts-ignore
cluster.on('clusterclick', (event) => {
// @ts-ignore
const ids = event.layer.getAllChildMarkers().map(marker => marker.getAssetId());
dispatch('view', { assets: ids });
});
for (let marker of markers) {
const icon = new Icon({
iconUrl: getFileUrl(marker.id, true),
iconRetinaUrl: getFileUrl(marker.id, true),
iconSize: [60, 60],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
tooltipAnchor: [16, -28],
shadowSize: [41, 41]
});
const leafletMarker = new Marker([marker.lat, marker.lon], {
icon,
alt: ''
});
const leafletMarker = new AssetMarker(marker);
leafletMarker.on('click', () => {
assetInteractionStore.setViewingAssetId(marker.id);
dispatch('view', { assets: [marker.id] });
});
cluster.addLayer(leafletMarker);

View file

@ -11,6 +11,7 @@
const map = getMapContext();
onMount(() => {
// @ts-ignore
tileLayer = new L.tileLayer.colorFilter(urlTemplate, options).addTo(map);
});

View file

@ -7,18 +7,40 @@
import {
assetInteractionStore,
isViewingAssetStoreState,
viewingAssetStoreState
viewingAssetStoreState,
} from '$lib/stores/asset-interaction.store';
import { colorTheme } from '$lib/stores/preferences.store';
export let data: PageData;
let initialMapCenter = [48, 11];
let initialMapCenter: [number, number] = [48, 11];
if (data.mapMarkers.length) {
let firstMarker = data.mapMarkers[0];
initialMapCenter = [firstMarker.lat, firstMarker.lon];
}
let viewingAssets: string[] = [];
let viewingAssetCursor = 0;
function onViewAssets(assets: string[]) {
assetInteractionStore.setViewingAssetId(assets[0]);
viewingAssets = assets;
viewingAssetCursor = 0;
}
function navigateNext() {
if (viewingAssetCursor < viewingAssets.length - 1) {
assetInteractionStore.setViewingAssetId(viewingAssets[++viewingAssetCursor]);
}
}
function navigatePrevious() {
if (viewingAssetCursor > 0) {
assetInteractionStore.setViewingAssetId(viewingAssets[--viewingAssetCursor]);
}
}
</script>
<UserPageLayout user={data.user} title={data.meta.title}>
@ -48,7 +70,7 @@
/>
{/if}
<AssetMarkerCluster markers={data.mapMarkers} />
<AssetMarkerCluster markers={data.mapMarkers} on:view={event => onViewAssets(event.detail.assets)} />
</Map>
</div>
@ -58,7 +80,9 @@
{#if $isViewingAssetStoreState}
<AssetViewer
asset={$viewingAssetStoreState}
showNavigation={false}
showNavigation={viewingAssets.length > 1}
on:navigate-next={navigateNext}
on:navigate-previous={navigatePrevious}
on:close={() => {
assetInteractionStore.setIsViewingAsset(false);
}}