diff options
| author | Adam Soltys <[email protected]> | 2023-10-16 15:34:26 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-10-16 15:34:26 -0700 |
| commit | 829c2efb9c4415c64466988f1e189184ffb88478 (patch) | |
| tree | 23f9e5fd83be3d4ee3943d254e4d3d2ce194819a /src/components/LocationsMap.svelte | |
| parent | 16475fffdb0d20a2933cfaf6922afc7c137bb7fe (diff) | |
| parent | 0212fe0032eb0c5d6bfb74ebaab42543b73d6d6b (diff) | |
| download | coinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.tar.gz coinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.zip | |
Merge branch 'master' into swapee
Diffstat (limited to 'src/components/LocationsMap.svelte')
| -rw-r--r-- | src/components/LocationsMap.svelte | 268 |
1 files changed, 102 insertions, 166 deletions
diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte index 277d75a6..7876659a 100644 --- a/src/components/LocationsMap.svelte +++ b/src/components/LocationsMap.svelte @@ -1,205 +1,141 @@ <script> - export let locations; - import { onMount, onDestroy } from 'svelte'; import { browser } from '$app/environment'; - import html2canvas from 'html2canvas'; - function captureHighResMap(mapElement, scale = 2) { - // Backup original size - let originalWidth = mapElement.offsetWidth; - let originalHeight = mapElement.offsetHeight; - - // Scale the map element - mapElement.style.transform = `scale(${scale})`; - mapElement.style.transformOrigin = 'top left'; - mapElement.style.width = originalWidth * scale + 'px'; - mapElement.style.height = originalHeight * scale + 'px'; - - return html2canvas(mapElement, { - width: originalWidth * scale, - height: originalHeight * scale, - scale: scale - }).then((canvas) => { - // Restore the original size - mapElement.style.transform = ''; - mapElement.style.width = originalWidth + 'px'; - mapElement.style.height = originalHeight + 'px'; - - return canvas; - }); - } + import 'maplibre-gl/dist/maplibre-gl.css'; - let mapElement; + export let locations; let map; + let mapContainer; + let markers = []; - onMount(async () => { - if (browser) { - const L = await import('leaflet'); - - map = L.map(mapElement, { - zoomSnap: 0, - attributionControl: false, - }).setView([49.26, -123.05], 12); - - - const myCustomColour = '#F7931A'; + let checkAddress = (location) => { + if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) { + return `${ + location['addr:housenumber'] + ' ' + location['addr:street'] + ', ' + location['addr:city'] + }`; + } else if (location['addr:street'] && location['addr:city']) { + return `${location['addr:street'] + ', ' + location['addr:city']}`; + } else if (location['addr:city']) { + return `${location['addr:city']}`; + } else { + return ''; + } + }; - const markerHtmlStyles = ` - background-color: ${myCustomColour}; - width: 1.2rem; - height: 1.2rem; - display: block; - position: relative; - border-radius: 100% 100% 0; - transform: rotate(45deg); - opacity: 0.9; - border: 1px solid #666`; + function updateLabelVisibility() { + if (!map) return; + let zoom = map.getZoom(); + let bounds = map.getBounds(); - const icon = L.divIcon({ - className: 'my-custom-pin', - iconAnchor: [0, 24], - labelAnchor: [-6, 0], - popupAnchor: [0, -36], - html: `<span style="${markerHtmlStyles}" />` - }); + for (let marker of markers) { + let isInView = bounds.contains(marker.getLngLat()); + let popup = marker.getPopup(); + let { tags } = marker; - locations = locations.filter( - (location) => - location['osm_json'].tags && - location['osm_json'].tags['payment:swapee'] === 'yes' && - location['osm_json'].lat && - location['osm_json'].lon - ); + if (zoom > 13 && isInView) { + popup.setHTML(`<span class='block font-bold'>${tags.name}</span>`).addTo(map); + } else { + popup.remove(); + popup.setHTML(html(tags)); + } + } + } - L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png', { - maxZoom: 18, - subdomains: ['a', 'b', 'c', 'd'] - }).addTo(map); + let html = (tags) => `${ + tags && tags.name ? `<span class='block font-bold'>${tags.name}</span>` : '' + } - const checkAddress = (location) => { - if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) { - return `${ - location['addr:housenumber'] + - ' ' + - location['addr:street'] + - ', ' + - location['addr:city'] - }`; - } else if (location['addr:street'] && location['addr:city']) { - return `${location['addr:street'] + ', ' + location['addr:city']}`; - } else if (location['addr:city']) { - return `${location['addr:city']}`; - } else { - return ''; - } - }; + <span class='block'>${tags && checkAddress(tags)}</span> - locations.forEach((location) => { - if (location['deleted_at']) return; + ${tags && tags.phone ? `<a href='tel:${tags.phone}' class='block'>${tags.phone}</a>` : ''} - location = location['osm_json']; - let marker = L.marker([location.lat, location.lon], { icon }); + ${ + tags && tags.website + ? `<a href=${tags.website} target="_blank" rel="noreferrer" class='block text-blue-400'>${tags.website}</a>` + : '' + }`; - if (location.tags && location.tags.name) { - marker.bindTooltip(location.tags.name, { permanent: true }).openTooltip(); - } + onMount(() => { + if (browser) { + import('maplibre-gl').then(({ default: maplibre }) => { + map = new maplibre.Map({ + container: mapContainer, + style: 'https://tiles.stadiamaps.com/styles/stamen_toner.json', + center: [-123.05, 49.26], + zoom: 10.5 + }); - marker.bindPopup( - `${ - location.tags && location.tags.name - ? `<span class='block'>${location.tags.name}</span>` - : '' - } + map.on('load', () => { + locations.forEach((location) => { + if (location['deleted_at']) return; - <span class='block'>${location.tags && checkAddress(location.tags)}</span> + let { lat, lon, tags } = location['osm_json']; + if (!(lat && lon)) return; - ${ - location.tags && location.tags.phone - ? `<a href='tel:${location.tags.phone}' class='block'>${location.tags.phone}</a>` - : '' - } + let element = document.createElement('div'); + element.className = 'marker'; - ${ - location.tags && location.tags.website - ? `<a href=${location.tags.website} target="_blank" rel="noreferrer" class='block'>${location.tags.website}</a>` - : '' - } + let marker = new maplibre.Marker({ color: '#F7931A' }) + .setLngLat([lon, lat]) + .setPopup(new maplibre.Popup().setHTML(html(tags))) + .addTo(map); - ${ - location.tags && location.tags['contact:twitter'] - ? `<a href=${ - location.tags['contact:twitter'].startsWith('http') - ? location.tags['contact:twitter'] - : `https://twitter.com/${location.tags['contact:twitter']}` - } target="_blank" rel="noreferrer" class='block'>TWT: ${ - location.tags['contact:twitter'] - }</a>` - : '' - } + marker.getElement().addEventListener('click', () => { + let h = html(marker.tags); + let popup = marker.getPopup(); + popup.setHTML(h); + }); - ${ - location.tags && location.tags['contact:instagram'] - ? `<a href=${ - location.tags['contact:instagram'].startsWith('http') - ? location.tags['contact:instagram'] - : `https://instagram.com/${location.tags['contact:instagram']}` - } target="_blank" rel="noreferrer" class='block'>IG: ${ - location.tags['contact:instagram'] - }</a>` - : '' - } + marker.tags = tags; - ${ - location.tags && location.tags['contact:facebook'] - ? `<a href=${ - location.tags['contact:facebook'].startsWith('http') - ? location.tags['contact:facebook'] - : `https://facebook.com/${location.tags['contact:facebook']}` - } target="_blank" rel="noreferrer" class='block'>FB: ${ - location.tags['contact:facebook'] - }</a>` - : '' - } + markers.push(marker); + }); - ${ - location.tags && location.tags['contact:linkedin'] - ? `<a href=${ - location.tags['contact:linkedin'].startsWith('http') - ? location.tags['contact:linkedin'] - : `https://linkedin.com/${location.tags['contact:linkedin']}` - } target="_blank" rel="noreferrer" class='block'>LI: ${ - location.tags['contact:linkedin'] - }</a>` - : '' - }` - ); - marker.addTo(map); + // updateLabelVisibility(); + // map.on('moveend', updateLabelVisibility); + // map.on('zoomend', updateLabelVisibility); + }); }); - - // map.fitBounds(locations.map(({ osm_json: { lat, lon } }) => [lat, lon])); } }); - onDestroy(async () => map && map.remove()); + onDestroy(() => { + if (map) { + // map.off('moveend', updateLabelVisibility); + // map.off('zoomend', updateLabelVisibility); + map.remove(); + } + }); </script> <div class="container mx-auto max-w-4xl"> - <div class="flex w-full"> - <div class="mx-auto h-[550px] w-full z-0" bind:this={mapElement} /> - </div> + <div class="flex w-full"> + <div class="mx-auto h-[550px] w-full z-0" bind:this={mapContainer} /> + </div> </div> <style> - @import 'leaflet/dist/leaflet.css'; + :global(.maplibregl-popup-close-button) { + font-size: 18px; + padding: 8px; + } + + :global(.maplibregl-popup :focus) { + outline: none; + } + + :global(.maplibregl-ctrl-attrib) { + display: none; + } - :global(.leaflet-tooltip) { - border: none; + :global(.maplibregl-popup-content) { + padding: 0.5em 1em; border-radius: 4px; - font-size: 12px; - font-weight: bolder; + font-size: 14px; color: black; - background-color: rgba(255, 255, 255, 0.5); + background-color: white; + overflow: hidden; } </style> |
