diff --git a/web/themes/custom/caravane/assets/js/libs/leaflet.edgebuffer.js b/web/themes/custom/caravane/assets/js/libs/leaflet.edgebuffer.js new file mode 100644 index 0000000..e020a45 --- /dev/null +++ b/web/themes/custom/caravane/assets/js/libs/leaflet.edgebuffer.js @@ -0,0 +1,23 @@ +export default function (L) { + L.EdgeBuffer = { + previousMethods: { + getTiledPixelBounds: L.GridLayer.prototype._getTiledPixelBounds, + } + }; + + L.GridLayer.include({ + _getTiledPixelBounds: function (center, zoom, tileZoom) { + var pixelBounds = L.EdgeBuffer.previousMethods.getTiledPixelBounds.call(this, center, zoom, tileZoom); + + var edgeBufferTiles = this.options.edgeBufferTiles ?? 1; + if (edgeBufferTiles > 0) { + var pixelEdgeBuffer = L.GridLayer.prototype.getTileSize.call(this).multiplyBy(edgeBufferTiles); + pixelBounds = new L.Bounds(pixelBounds.min.subtract(pixelEdgeBuffer), pixelBounds.max.add(pixelEdgeBuffer)); + } + return pixelBounds; + } + }); + + return L; + } + \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/main.js b/web/themes/custom/caravane/assets/js/main.js index 9823fec..e2e336e 100644 --- a/web/themes/custom/caravane/assets/js/main.js +++ b/web/themes/custom/caravane/assets/js/main.js @@ -2,7 +2,9 @@ import { initVueContentModale } from './utils/vue-setup'; import { processClickableElements } from './utils/process-clickable-elements'; import { handleReactiveness, setMenuToggle, setHamburgerWhenLogged } from './utils/layout-setup'; import { initFirstLoadRouting, handleClickableElements, handleBrowserNavigation } from './utils/handle-navigation'; -import { setupMapStore } from './utils/map-setup'; +import { setupMapStore, preloadEtapesTiles } from './utils/map-setup'; + +import initEdgeBuffer from './libs/leaflet.edgebuffer'; import '../scss/main.scss' @@ -11,8 +13,8 @@ import '../scss/main.scss' (function ($, Drupal, drupalSettings) { const CaravaneTheme = function () { function init () { - console.log('DrupalSettings', drupalSettings); - + // console.log('DrupalSettings', drupalSettings); + const baseUrl = window.location.protocol + "//" + window.location.host; const siteName = document.querySelector('#site_name').innerText; const { store, mapStore, router, route } = initVueContentModale(); @@ -25,7 +27,12 @@ import '../scss/main.scss' Drupal.behaviors.customLeafletInteraction = { attach: function(context, settings) { - $(context).on('leafletMapInit', function (e, settings, map, mapid, markers) { + + initEdgeBuffer(L); + let mapSettings = settings.leaflet[Object.keys(settings.leaflet)[0]].map; + mapSettings.layers.layer.edgeBufferTiles = 8; + + $(context).on('leafletMapInit', function (e, settings, map, mapid, markers) { const { etapeListLinks, generalListLinks, @@ -36,6 +43,8 @@ import '../scss/main.scss' setupMapStore(mapStore, map, settings); + // preloadEtapesTiles(mapStore, map); + initFirstLoadRouting(store, router, baseUrl, siteName); handleClickableElements(clickableElements, store, router, baseUrl, siteName, mapStore); diff --git a/web/themes/custom/caravane/assets/js/stores/content.js b/web/themes/custom/caravane/assets/js/stores/content.js index 363c50d..0b03838 100644 --- a/web/themes/custom/caravane/assets/js/stores/content.js +++ b/web/themes/custom/caravane/assets/js/stores/content.js @@ -254,7 +254,7 @@ export const useContentStore = defineStore('content', { this.content[`${this.contentType}s`] = multiItemPageArray; - console.log(this.content); + // console.log(this.content); } } catch (error) { this.error = 'Failed to fetch data'; diff --git a/web/themes/custom/caravane/assets/js/stores/map.js b/web/themes/custom/caravane/assets/js/stores/map.js index 1671814..e78b4e4 100644 --- a/web/themes/custom/caravane/assets/js/stores/map.js +++ b/web/themes/custom/caravane/assets/js/stores/map.js @@ -17,18 +17,18 @@ export const useMapStore = defineStore('mapState', { }), actions: { zoomToPlace(lat, long) { - if (useLayoutStore().isDesktop) long = long - 0.03; + if (useLayoutStore().isDesktop) long = long - 0.03; this.map.flyTo( [lat, long], this.maxZoom, - { animate: this.animationsAreEnabled, animationDuration: this.animationDuration }); + { animate: this.animationsAreEnabled, duration: this.animationDuration }); this.currentZoom = this.maxZoom; }, - resetMap() { + resetMap(animate = this.animationsAreEnabled, duration = this.animationDuration) { this.map.flyTo( this.defaultMapCenter, useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile, - { animate: this.animationsAreEnabled, animationDuration: this.animationDuration }); + { animate, duration }); this.currentZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile; }, lockMap() { diff --git a/web/themes/custom/caravane/assets/js/utils/map-setup.js b/web/themes/custom/caravane/assets/js/utils/map-setup.js index f991c30..f7a54db 100644 --- a/web/themes/custom/caravane/assets/js/utils/map-setup.js +++ b/web/themes/custom/caravane/assets/js/utils/map-setup.js @@ -1,4 +1,5 @@ import { useLayoutStore } from '../stores/layout'; +import REST from '../api/rest-axios'; export function setupMapStore(mapStore, map, settings) { mapStore.map = map; @@ -8,4 +9,58 @@ export function setupMapStore(mapStore, map, settings) { mapStore.defaultZoomMobile = settings.settings.minZoom - 1; mapStore.map.flyTo([mapStore.defaultMapCenter.lat, mapStore.defaultMapCenter.lng], useLayoutStore().isDesktop ? mapStore.defaultZoomDesktop : mapStore.defaultZoomMobile); mapStore.checkReducedMotion(); -} \ No newline at end of file +} + +// not working +// kept to maybe rework on it later +export async function preloadEtapesTiles(mapStore, map) { + function waitForEvent(el, eventName) { + return new Promise((resolve) => { + el.once(eventName, resolve); + }); + } + + const tilesSource = map._layers.layer._url; + + const response = await REST.get(`/jsonapi/node/etape/`); + + const defaultZoom = useLayoutStore().isDesktop ? mapStore.defaultZoomDesktop : mapStore.defaultZoomMobile; + + let tilesCached = new Set(); + + for (const etape of response.data.data) { + const etapeCoords = { + title: etape.attributes.title, + lat: etape.attributes.field_geofield.lat, + lng: etape.attributes.field_geofield.lon, + }; + + for (let zoom = defaultZoom; zoom <= mapStore.maxZoom; zoom++) { + map.flyTo([etapeCoords.lat, etapeCoords.lng], zoom, { animate: true, duration: 0.001 }); + await waitForEvent(map, 'moveend zoomend'); + + let allTilesCached = Object.keys(map._layers.layer._tiles).every(tile => tilesCached.has(tile)); + + const tileLayer = Object.values(map._layers).find(layer => layer instanceof L.TileLayer); + + if (!allTilesCached && tileLayer._loading) { + await waitForEvent(tileLayer, 'load'); + Object.keys(map._layers.layer._tiles).forEach(tile => { + if (!tilesCached.has(tile)) { +/* const tileObject = map._layers.layer._tiles[tile]; + let img = new Image(); + const url = tilesSource + .replace('{z}', tileObject.coords.z) + .replace('{x}', tileObject.coords.x) + .replace('{y}', tileObject.coords.y); + img.src = url; */ + tilesCached.add(tile) + } + }); + } + + } + } + // console.log(tilesCached); + mapStore.resetMap(false, 0); +} diff --git a/web/themes/custom/caravane/assets/scss/main.scss b/web/themes/custom/caravane/assets/scss/main.scss index 190abe0..97e8e04 100644 --- a/web/themes/custom/caravane/assets/scss/main.scss +++ b/web/themes/custom/caravane/assets/scss/main.scss @@ -301,6 +301,7 @@ body{ top: 0; width: 100vw; .leaflet-container { + background-color: $main-color-light; .leaflet-popup { display: none; }