From 8e278fadaf0d8a735e259d4d6c59ade581150692 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 11 Nov 2023 00:04:17 -0800 Subject: map animation and list --- src/components/AppHeader.svelte | 4 +- src/components/LocationsMap.svelte | 147 +++++++++++++++++++++++++++++++++---- 2 files changed, 134 insertions(+), 17 deletions(-) (limited to 'src/components') diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte index 4ccd2d03..3bf1e893 100644 --- a/src/components/AppHeader.svelte +++ b/src/components/AppHeader.svelte @@ -17,6 +17,8 @@ menuButtons = [ { key: 'nav.settings', icon: 'settings', href: `/${user.username}/settings` }, { key: 'nav.support', icon: 'support', href: `/support` }, + { key: 'nav.map', icon: 'map', href: `/${user.username}/map` }, + { key: 'nav.merch', icon: 'shop', href: `https://coinosmerch.com` }, { key: 'nav.signOut', icon: 'logout', href: `/logout` }, ]; @@ -53,7 +55,7 @@ .url.pathname === `/${user.username}/receive` ? 'opacity-100' : 'opacity-70 hover:opacity-80'}" - > + > diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte index 7876659a..edd20632 100644 --- a/src/components/LocationsMap.svelte +++ b/src/components/LocationsMap.svelte @@ -2,6 +2,7 @@ import { onMount, onDestroy } from 'svelte'; import { browser } from '$app/environment'; import html2canvas from 'html2canvas'; + import { Icon } from '$comp'; import 'maplibre-gl/dist/maplibre-gl.css'; @@ -10,6 +11,71 @@ let mapContainer; let markers = []; + let currentIndex = -1; + let timeout; + + function select(m) { + stopFlying(); + currentIndex = inview.indexOf(m); + flyToMarker(m); + } + + async function flyToMarker(marker) { + marker.getElement().click(); + + map.flyTo({ + zoom: 14, + center: marker.getLngLat(), + essential: true, + easing: function (t) { + return 1 - Math.pow(1 - t, 3); + }, + duration: 5000 + }); + + await new Promise((r) => setTimeout(r, 5000)); + + if (!timeout) return; + + map.flyTo({ + zoom: 10.5, + center: marker.getLngLat(), + essential: true, + easing: function (t) { + return 1 - Math.pow(1 - t, 3); + }, + duration: 2000 + }); + } + + let toggle = () => { + if (timeout) stopFlying(); + else startFlying(); + }; + + let currentPopup; + function startFlying() { + currentIndex++; + + for (let p in popups) popups[p].remove(); + if (currentIndex >= inview.length) currentIndex = 0; + flyToMarker(inview[currentIndex]); + + timeout = setTimeout(startFlying, 7000); + } + + function stopFlying() { + if (!timeout) return; + timeout = clearTimeout(timeout); + + if (currentPopup) { + currentPopup.remove(); + } + + map.jumpTo({ center: map.getCenter(), zoom: map.getZoom() }); + map.off('moveend'); // Remove moveend listener if set + } + let checkAddress = (location) => { if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) { return `${ @@ -24,23 +90,24 @@ } }; + let inview = []; + function updateLabelVisibility() { + inview = []; if (!map) return; let zoom = map.getZoom(); let bounds = map.getBounds(); for (let marker of markers) { let isInView = bounds.contains(marker.getLngLat()); - let popup = marker.getPopup(); let { tags } = marker; - if (zoom > 13 && isInView) { - popup.setHTML(`${tags.name}`).addTo(map); - } else { - popup.remove(); - popup.setHTML(html(tags)); + if (isInView) { + inview.push(marker); } } + + inview = inview.sort((a, b) => a.tags.name.localeCompare(b.tags.name)); } let html = (tags) => `${ @@ -53,10 +120,13 @@ ${ tags && tags.website - ? `${tags.website}` + ? `${tags.website}` : '' }`; + let popups = {}; + let counter = 0; + onMount(() => { if (browser) { import('maplibre-gl').then(({ default: maplibre }) => { @@ -82,10 +152,16 @@ .setPopup(new maplibre.Popup().setHTML(html(tags))) .addTo(map); + marker.id = counter++; + marker.getElement().addEventListener('click', () => { let h = html(marker.tags); - let popup = marker.getPopup(); - popup.setHTML(h); + let p = marker.getPopup(); + popups[marker.id] = p; + p.setHTML(h); + p.on('close', () => { + delete popups[marker.id]; + }); }); marker.tags = tags; @@ -93,18 +169,31 @@ markers.push(marker); }); - // updateLabelVisibility(); - // map.on('moveend', updateLabelVisibility); - // map.on('zoomend', updateLabelVisibility); + updateLabelVisibility(); + + let observer = new IntersectionObserver( + (entries, observer) => { + entries.forEach((entry) => { + if (entry.isIntersecting) startFlying(); + else stopFlying(); + }); + }, + { threshold: 0.5 } + ); + + observer.observe(mapContainer); }); + + map.on('mousedown', stopFlying); + map.on('touchstart', stopFlying); + map.on('wheel', stopFlying); + map.on('dragstart', stopFlying); }); } }); onDestroy(() => { if (map) { - // map.off('moveend', updateLabelVisibility); - // map.off('zoomend', updateLabelVisibility); map.remove(); } }); @@ -113,12 +202,37 @@
+
+ + +
+ {#each inview as m} + + {/each} +
+
+ + {inview.length}
-- cgit v1.2.3