diff --git a/web/themes/custom/caravane/assets/js/main.js b/web/themes/custom/caravane/assets/js/main.js
index cd38854..3a8cc7e 100644
--- a/web/themes/custom/caravane/assets/js/main.js
+++ b/web/themes/custom/caravane/assets/js/main.js
@@ -7,6 +7,7 @@ import VueImageZoomer from 'vue-image-zoomer'
import 'vue-image-zoomer/dist/style.css';
import { useContentStore } from './stores/content';
+import { useMapStore } from './stores/mapState';
import router from './router/router';
// Working with the history API
@@ -31,19 +32,13 @@ import router from './router/router';
(function ($, Drupal, drupalSettings) {
const CaravaneTheme = function () {
- const _is_front = drupalSettings.path.isFront
- console.log('drupalSettings', drupalSettings)
+ const _is_front = drupalSettings.path.isFront;
+ console.log('drupalSettings', drupalSettings);
- // let _I18n
-
- // ___ _ _
- // |_ _|_ _ (_) |_
- // | || ' \| | _|
- // |___|_||_|_|\__|
function init () {
- console.log('CaravaneTheme init()')
- initVues()
- toggleMenu()
+ console.log('CaravaneTheme init()');
+ initVues();
+ toggleMenu();
}
function initVues(){
@@ -55,45 +50,67 @@ import router from './router/router';
.use(createPinia()).use(router)
.use(VueImageZoomer);
const store = useContentStore();
+ const mapStore = useMapStore();
app.mount('#content-modale');
- processEtapeLinks(store);
- processStaticLinks(store);
-
- setupEtapeMapPopup(store);
+ Drupal.behaviors.customLeafletInteraction = {
+ attach: function(context, settings) {
+ $(context).on('leafletMapInit', function (e, settings, map, mapid, markers) {
+ mapStore.defaultMapCenter = map.getCenter();
+ mapStore.maxZoom = settings.settings.maxZoom;
+ mapStore.defaultZoom = settings.settings.minZoom;
+
+ processEtapeLinks(store, map);
+ processStaticLinks(store, map);
+ processHeaderLogo(store, map);
+ setupEtapeMapPopup(store, map);
+ });
+ }
+ }
}
-
- function onClickContentLink(e, store, category){
+ function onClickContentLink(e, store, map, category){
e.preventDefault();
let a;
-
- const li = e.target.closest('li');
- a = li.querySelector('a');
+
+ if (e.target.tagName !== 'IMG') {
+ const li = e.target.closest('li');
+ a = li.querySelector('a');
+ } else {
+ a = e.target.closest('a');
+ }
let nid = a.dataset.nodeNid;
if (category === 'etape') {
- store.fetchEtapeData(nid);
+ store.fetchEtapeData(nid, map);
} else if (category === 'static') {
- store.fetchStaticData(nid);
+ if (nid) {
+ store.fetchStaticData(nid, map);
+ } else {
+ store.emptyAll(null, map);
+ }
}
return null;
}
- function processStaticLinks(store){
- let general_link_fields = document.querySelectorAll('#menu > ul > li:not(:first-of-type) > a');
+ function processStaticLinks(store, map) {
+ let general_link_fields = document.querySelectorAll('#menu > ul > li > a');
for (let field of general_link_fields) {
let general_link_href = field.getAttribute('href');
const nid = general_link_href.charAt(general_link_href.length-1);
- field.setAttribute('data-node-nid', nid);
- field.addEventListener('click', (e) => onClickContentLink(e, store, 'static'));
+ field.setAttribute('data-node-nid', parseInt(nid));
+ field.addEventListener('click', (e) => onClickContentLink(e, store, map, 'static'));
}
}
+ function processHeaderLogo(store, map) {
+ const logo = document.querySelector('#block-caravane-logocaravane a');
+ logo.addEventListener('click', (e) => onClickContentLink(e, store, map, 'static'));
+ }
- function processEtapeLinks(store){
+ function processEtapeLinks(store, map) {
let etape_li = document.querySelectorAll('#etapes-liste li');
etape_li.forEach((li) => {
let field = li.querySelector('div.views-field-title');
@@ -110,7 +127,7 @@ import router from './router/router';
if (nid) {
let a = field.querySelector('a');
a.setAttribute('data-node-nid', nid);
- li.addEventListener('click', (e) => onClickContentLink(e, store, 'etape'));
+ li.addEventListener('click', (e) => onClickContentLink(e, store, map, 'etape'));
}
let couleur = li.querySelector('.views-field-field-couleur .snippets-description').innerText;
let iconElements = li.querySelectorAll('.icone-arret > div');
@@ -145,52 +162,43 @@ import router from './router/router';
})
}
- function setupEtapeMapPopup(store) {
- Drupal.behaviors.customLeafletInteraction = {
- attach: function(context, settings) {
- $(context).on('leafletMapInit', function (e, settings, map, mapid, markers) {
- const icons = document.querySelectorAll('.leaflet-map-divicon');
- for (let icon of icons) {
- const colorContainer = icon.querySelector('.couleur');
- let colorDivs = colorContainer.querySelectorAll('.separated-content');
- let color;
- colorDivs.forEach((div) => {
- if (div.innerText.startsWith('
')) {
- color = div.innerText;
- }
- });
- color = color.substring(color.indexOf('>') + 1, color.indexOf('<', color.indexOf('>') + 1)).trim();
+ function setupEtapeMapPopup(store, map) {
+ const icons = document.querySelectorAll('.leaflet-map-divicon');
+ for (let icon of icons) {
+ const colorContainer = icon.querySelector('.couleur');
+ let colorDivs = colorContainer.querySelectorAll('.separated-content');
+ let color;
+ colorDivs.forEach((div) => {
+ if (div.innerText.startsWith('
')) {
+ color = div.innerText;
+ }
+ });
+ color = color.substring(color.indexOf('>') + 1, color.indexOf('<', color.indexOf('>') + 1)).trim();
- const nid = icon.querySelector('.nid');
- const nidValue = nid.querySelector('.separated-content').innerText;
+ const nid = icon.querySelector('.nid');
+ const nidValue = nid.querySelector('.separated-content').innerText;
- icon.addEventListener('click', function(event) {
- store.fetchEtapeData(nidValue);
- });
-
- //colorContainer.remove();
- //nid.remove();
- colorContainer.style.display = "none";
- nid.style.display = "none";
- const iconElements = icon.querySelectorAll('div');
- for (let iconElement of iconElements) {
- iconElement.style.backgroundColor = color;
- }
- icon.removeAttribute('title');
-
- icon.addEventListener('mouseenter', function (event) {
- icon.style.transform = `${icon.style.transform} scale(1.1)`;
- const popup = document.querySelector('.leaflet-tooltip-center > div');
- popup.style.opacity = "1";
- });
-
- icon.addEventListener('mouseleave', function (event) {
- icon.style.transform = icon.style.transform.split(' ')[0] + icon.style.transform.split(' ')[1] + icon.style.transform.split(' ')[2];
- })
- }
-
- });
+ icon.addEventListener('click', function(event) {
+ store.fetchEtapeData(nidValue, map);
+ });
+
+ colorContainer.style.display = "none";
+ nid.style.display = "none";
+ const iconElements = icon.querySelectorAll('div');
+ for (let iconElement of iconElements) {
+ iconElement.style.backgroundColor = color;
}
+ icon.removeAttribute('title');
+
+ icon.addEventListener('mouseenter', function (event) {
+ icon.style.transform = `${icon.style.transform} scale(1.1)`;
+ const popup = document.querySelector('.leaflet-tooltip-center > div');
+ popup.style.opacity = "1";
+ });
+
+ icon.addEventListener('mouseleave', function (event) {
+ icon.style.transform = icon.style.transform.split(' ')[0] + icon.style.transform.split(' ')[1] + icon.style.transform.split(' ')[2];
+ })
}
}
diff --git a/web/themes/custom/caravane/assets/js/stores/content.js b/web/themes/custom/caravane/assets/js/stores/content.js
index dcc38a5..302b8ad 100644
--- a/web/themes/custom/caravane/assets/js/stores/content.js
+++ b/web/themes/custom/caravane/assets/js/stores/content.js
@@ -6,9 +6,11 @@ import REST from '../api/rest-axios';
export const useContentStore = defineStore('content', {
state: () => ({
href: '',
+ map: {},
etape: {
title: '',
adresse: {},
+ coordinates: {},
etape_number: '',
vignette: {},
couleur: '',
@@ -37,8 +39,9 @@ export const useContentStore = defineStore('content', {
error: null,
}),
actions: {
- async fetchEtapeData(nid) {
+ async fetchEtapeData(nid, map) {
this.resetStore();
+ this.map = map;
try {
const response = await REST.get(`/jsonapi/node/etape/`);
for (let etape of response.data.data) {
@@ -48,6 +51,10 @@ export const useContentStore = defineStore('content', {
this.href = metatag.attributes.href;
}
}
+ this.etape.coordinates = {
+ lat: etape.attributes.field_geofield.lat,
+ lon: etape.attributes.field_geofield.lon,
+ };
this.etape.title = etape.attributes.title;
this.etape.adresse = etape.attributes.field_adresse;
this.etape.etape_number = etape.attributes.field_arret_numero;
@@ -205,8 +212,9 @@ export const useContentStore = defineStore('content', {
this.loading = false;
}
},
- async fetchStaticData(nid) {
+ async fetchStaticData(nid, map) {
this.resetStore();
+ this.map = map;
try {
const response = await REST.get(`/jsonapi/node/static/`);
for (let page of response.data.data) {
@@ -285,7 +293,9 @@ export const useContentStore = defineStore('content', {
}
}
},
- emptyAll(nid) {
+ emptyAll(nid, map) {
+ this.href = '';
+ this.map = map;
this.etape = {};
this.page = {};
this.setActiveItemInMenu(nid);
@@ -328,7 +338,6 @@ export const useContentStore = defineStore('content', {
resetStore() {
this.loading = true;
this.error = null;
- this.href = '';
this.etape = {};
this.page = {};
},
diff --git a/web/themes/custom/caravane/assets/js/stores/mapState.js b/web/themes/custom/caravane/assets/js/stores/mapState.js
new file mode 100644
index 0000000..e8e9a2b
--- /dev/null
+++ b/web/themes/custom/caravane/assets/js/stores/mapState.js
@@ -0,0 +1,46 @@
+import { defineStore } from 'pinia';
+
+export const useMapStore = defineStore('mapState', {
+ state: () => ({
+ defaultZoom: Number,
+ defaultMapCenter: Object,
+ currentPlace: Object,
+ maxZoom: Number,
+ currentZoom: Number,
+ duration: 3,
+ }),
+ actions: {
+ zoomToPlace(map, lat, long) {
+ map.flyTo([lat, long], this.maxZoom, { duration: this.duration });
+ this.currentZoom = this.maxZoom;
+ },
+ resetMap(map) {
+ map.flyTo(this.defaultMapCenter, this.defaultZoom, { duration: this.duration });
+ this.currentZoom = this.defaultZoom;
+ },
+ lockMap(map) {
+ setTimeout(() => {
+ map.options.minZoom = this.currentZoom;
+ map.options.maxZoom = this.currentZoom;
+ }, this.duration * 1000 + 100);
+ map.dragging.disable();
+ map.touchZoom.disable();
+ map.doubleClickZoom.disable();
+ map.scrollWheelZoom.disable();
+ map.boxZoom.disable();
+ map.keyboard.disable();
+ // map.tap.disable();
+ },
+ unlockMap(map) {
+ map.options.minZoom = this.defaultZoom;
+ map.options.maxZoom = this.maxZoom;
+ map.dragging.enable();
+ map.touchZoom.enable();
+ map.doubleClickZoom.enable();
+ map.scrollWheelZoom.enable();
+ map.boxZoom.enable();
+ map.keyboard.enable();
+ // map.tap.enable();
+ },
+ },
+});
\ No newline at end of file
diff --git a/web/themes/custom/caravane/assets/js/vuejs/Modale.vue b/web/themes/custom/caravane/assets/js/vuejs/Modale.vue
index 4d8305d..eac815d 100644
--- a/web/themes/custom/caravane/assets/js/vuejs/Modale.vue
+++ b/web/themes/custom/caravane/assets/js/vuejs/Modale.vue
@@ -20,7 +20,8 @@
:couleur="etape.couleur || brandColor" />
+ :partie="partie"
+ :couleur="etape.couleur || brandColor" />
+ :couleur="etape.couleur || brandColor"
+ :map="map" />
@@ -46,6 +48,7 @@
import { computed, watch, onMounted } from 'vue';
import { storeToRefs } from 'pinia';
import { useContentStore } from '../stores/content';
+import { useMapStore } from '../stores/mapState';
import { useRoute, useRouter } from 'vue-router';
import ModaleHeader from './components/ModaleHeader.vue';
@@ -64,13 +67,17 @@ const { isObjectEmpty, scrollTop } = useUtils();
const router = useRouter();
const store = useContentStore();
+const mapState = useMapStore();
const route = useRoute();
-const { loading, error, href, etape, page } = storeToRefs(store);
+const { loading, error, href, map, etape, page } = storeToRefs(store);
+const { duration } = storeToRefs(mapState);
const isEtapeValid = computed(() => !error.value && !loading.value && etape.value && !isObjectEmpty(etape.value));
const isPageValid = computed(() => !error.value && !loading.value && page.value && !isObjectEmpty(page.value));
+let isModaleEtape, wasModaleEtape;
+
const brandColor = "#80c8bf";
let isProgrammaticNavigation = false;
@@ -78,18 +85,18 @@ let isProgrammaticNavigation = false;
const handleRouteChange = () => {
watch(
() => route.params.id,
- (newId) => {
+ (newId) => {
if (isProgrammaticNavigation) {
isProgrammaticNavigation = false;
return;
}
if (!newId) {
- store.emptyAll();
+ store.emptyAll(map.value);
} else {
- store.fetchEtapeData(newId);
+ store.fetchEtapeData(newId, map.value);
if (!etape.value?.data) {
- store.fetchStaticData(newId);
+ store.fetchStaticData(newId, map.value);
}
scrollTop();
}
@@ -112,36 +119,82 @@ const handleHrefChange = () => {
() => href.value,
(newHref) => {
const relativePath = newHref.split('.fr')[1];
- if (relativePath && relativePath !== '' && relativePath !== '/') {
- isProgrammaticNavigation = true;
- router.push(relativePath);
- scrollTop();
+ isProgrammaticNavigation = true;
+ if (newHref == '') {
+ router.push('/');
+ mapState.unlockMap(map.value)
+ } else {
+ if (relativePath && relativePath !== '' && relativePath !== '/') {
+ mapState.lockMap(map.value);
+ router.push(relativePath);
+ scrollTop();
+ }
}
}
);
};
+const handleMapMovement = () => {
+ watch(
+ () => href.value,
+ () => {
+ console.log("NEW HREF");
+ console.log(href.value);
+
+ isModaleEtape = !isObjectEmpty(etape.value);
+
+ console.log("CAS 1", !wasModaleEtape && isModaleEtape);
+ console.log("CAS 2", wasModaleEtape && isModaleEtape);
+ console.log("CAS 3", wasModaleEtape && !isModaleEtape);
+
+ if (!wasModaleEtape && isModaleEtape) {
+ document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
+ mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
+
+ } else if (wasModaleEtape && isModaleEtape) {
+ document.documentElement.style.setProperty('--modale-leave-delay', 0);
+ document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value * 2}s`);
+ mapState.resetMap(map.value);
+ setTimeout(() => {
+ mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
+ }, duration.value * 1000);
+
+ } else if (wasModaleEtape && !isModaleEtape) {
+ document.documentElement.style.setProperty('--modale-leave-delay', 0);
+ mapState.resetMap(map.value);
+ }
+
+ wasModaleEtape = isModaleEtape;
+ },
+ );
+};
+
onMounted(() => {
+ isModaleEtape = !isObjectEmpty(etape.value);
+ wasModaleEtape = isModaleEtape;
handleRouteChange();
handleColorChange();
handleHrefChange();
+ handleMapMovement();
});
\ No newline at end of file
diff --git a/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue b/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue
index ec8e280..c7c3cf5 100644
--- a/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue
+++ b/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue
@@ -5,7 +5,7 @@