Compare commits
4 Commits
c82fc633aa
...
9370996c03
Author | SHA1 | Date |
---|---|---|
Valentin | 9370996c03 | |
Valentin | 31b577cc8b | |
Valentin | 9bf84290ac | |
Valentin | f2680fc65a |
|
@ -269,7 +269,7 @@ display:
|
|||
popupAnchor:
|
||||
x: ''
|
||||
'y': ''
|
||||
html: "<div></div>\r\n<div></div>\r\n<div></div>\r\n<div class=\"nid\">{{ nid }}</div>\r\n<div class=\"couleur\">{{ field_couleur }}</div>"
|
||||
html: "<div></div>\r\n<div></div>\r\n<div></div>\r\n<div class=\"url\">[node:url]</div>\r\n<div class=\"couleur\">[node:field_couleur]</div>"
|
||||
html_class: 'leaflet-map-divicon '
|
||||
circle_marker_options: '{"radius":100,"color":"red","fillColor":"#f03","fillOpacity":0.5}'
|
||||
leaflet_markercluster:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { initVueContentModale } from './utils/vue-setup';
|
||||
import { processClickableElements } from './utils/process-clickable-elements';
|
||||
import { handleReactiveness, setMenuToggle, setHamburgerWhenLogged } from './utils/layout-setup';
|
||||
import { initFirstLoadRouting, handleClickableElements } from './utils/handle-navigation';
|
||||
import { initFirstLoadRouting, handleClickableElements, handleBrowserNavigation } from './utils/handle-navigation';
|
||||
import { setupMapStore } from './utils/map-setup';
|
||||
|
||||
import '../scss/main.scss'
|
||||
|
@ -11,11 +11,11 @@ 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();
|
||||
const { store, mapStore, router, route } = initVueContentModale();
|
||||
|
||||
handleReactiveness();
|
||||
setMenuToggle();
|
||||
|
@ -25,8 +25,8 @@ import '../scss/main.scss'
|
|||
|
||||
Drupal.behaviors.customLeafletInteraction = {
|
||||
attach: function(context, settings) {
|
||||
$(context).on('leafletMapInit', function (e, settings, map, mapid, markers) {
|
||||
const {
|
||||
$(context).on('leafletMapInit', function (e, settings, map, mapid, markers) {
|
||||
const {
|
||||
etapeListLinks,
|
||||
generalListLinks,
|
||||
logoLink,
|
||||
|
@ -39,6 +39,10 @@ import '../scss/main.scss'
|
|||
initFirstLoadRouting(store, router, baseUrl, siteName);
|
||||
|
||||
handleClickableElements(clickableElements, store, router, baseUrl, siteName, mapStore);
|
||||
|
||||
window.addEventListener("popstate", () => {
|
||||
handleBrowserNavigation(store, baseUrl, siteName, mapStore);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -47,4 +51,4 @@ import '../scss/main.scss'
|
|||
init()
|
||||
}
|
||||
CaravaneTheme()
|
||||
})(jQuery, Drupal, drupalSettings)
|
||||
})(jQuery, Drupal, drupalSettings)
|
||||
|
|
|
@ -2,13 +2,13 @@ import { createRouter, createWebHistory } from 'vue-router';
|
|||
import ModaleView from '../vuejs/Modale.vue';
|
||||
|
||||
const routes = [
|
||||
/* {
|
||||
/* {
|
||||
name: 'etape',
|
||||
path: '/etapes/:title?',
|
||||
component: ModaleView,
|
||||
props: {id: null},
|
||||
},
|
||||
{
|
||||
{
|
||||
name: 'home',
|
||||
path: '/',
|
||||
component: ModaleView,
|
||||
|
@ -20,10 +20,10 @@ const routes = [
|
|||
component: ModaleView,
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
export default router;
|
||||
|
|
|
@ -27,7 +27,7 @@ export const useContentStore = defineStore('content', {
|
|||
this.resetStore(false);
|
||||
const contentTypes = [ 'etape', 'static' ];
|
||||
try {
|
||||
let rawContent,
|
||||
let rawContent,
|
||||
contentType,
|
||||
response;
|
||||
|
||||
|
@ -58,11 +58,11 @@ export const useContentStore = defineStore('content', {
|
|||
// vignette
|
||||
const vignetteFetch = await this.fetchDeeperContent('field_vignette', rawContent.relationships);
|
||||
if (vignetteFetch) {
|
||||
this.content.vignette = {
|
||||
this.content.vignette = {
|
||||
url: vignetteFetch.attributes.uri.url,
|
||||
alt: rawContent.relationships.field_vignette.data.meta.alt
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType === 'etape') {
|
||||
// coordinates
|
||||
|
@ -84,12 +84,12 @@ export const useContentStore = defineStore('content', {
|
|||
// previous / next
|
||||
await this.getRelatedEtape('previous', response.data.data, path);
|
||||
await this.getRelatedEtape('next', response.data.data, path);
|
||||
}
|
||||
}
|
||||
|
||||
// parties
|
||||
const fieldParties = contentType === 'etape' ? 'field_parties' : 'field_parties_static';
|
||||
const partiesFetch = await this.fetchDeeperContent(fieldParties, rawContent.relationships);
|
||||
|
||||
|
||||
if (partiesFetch) {
|
||||
this.content.parties = [];
|
||||
for (let partie of partiesFetch) {
|
||||
|
@ -100,7 +100,7 @@ export const useContentStore = defineStore('content', {
|
|||
|
||||
switch (partieType) {
|
||||
case 'carte_sensible':
|
||||
const carteSensibleFetch = await this.fetchDeeperContent('field_image_carte', partie.relationships);
|
||||
const carteSensibleFetch = await this.fetchDeeperContent('field_image_carte', partie.relationships);
|
||||
if (carteSensibleFetch) {
|
||||
partieContent.carteSensible = {
|
||||
url: carteSensibleFetch.attributes.uri.url,
|
||||
|
@ -110,7 +110,7 @@ export const useContentStore = defineStore('content', {
|
|||
break;
|
||||
case 'titre_texte':
|
||||
partieContent.titre = partie.attributes.field_titre;
|
||||
partieContent.texte = partie.attributes.field_texte.value;
|
||||
partieContent.texte = partie.attributes.field_texte.value;
|
||||
break;
|
||||
case 'chiffres_cles':
|
||||
const chiffresClesFetch = await this.fetchDeeperContent('field_chiffres_clefs', partie.relationships);
|
||||
|
@ -144,7 +144,7 @@ export const useContentStore = defineStore('content', {
|
|||
partieContent.entretien.personnes = [];
|
||||
for (let personne of personnesFetch) {
|
||||
const portraitFetch = await this.fetchDeeperContent('field_portrait', personne.relationships);
|
||||
if (portraitFetch) {
|
||||
if (portraitFetch) {
|
||||
partieContent.entretien.personnes.push({
|
||||
portrait: portraitFetch.attributes.uri.url,
|
||||
alt: personne.relationships.field_portrait.data.meta.alt,
|
||||
|
@ -158,7 +158,7 @@ export const useContentStore = defineStore('content', {
|
|||
question: qr.attributes.field_question,
|
||||
reponse: qr.attributes.field_reponse.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'exergue':
|
||||
|
@ -169,7 +169,7 @@ export const useContentStore = defineStore('content', {
|
|||
for (let video of partie.attributes.field_videos) {
|
||||
const videoId = video.split('?v=')[1];
|
||||
const videoUrl = `https://www.youtube.com/embed/${videoId}`;
|
||||
partieContent.videos.push(videoUrl);
|
||||
partieContent.videos.push(videoUrl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -179,8 +179,8 @@ export const useContentStore = defineStore('content', {
|
|||
} catch (error) {
|
||||
this.error = 'Failed to fetch data';
|
||||
console.error('Issue with getNodeData', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
getCleanDate(date) {
|
||||
|
@ -195,7 +195,7 @@ export const useContentStore = defineStore('content', {
|
|||
const baseUrl = window.location.protocol + "//" + window.location.host;
|
||||
for (let etape of allEtapesData) {
|
||||
for (let tag of etape.attributes.metatag) {
|
||||
if (tag.tag === "link" && tag.attributes.href === baseUrl + relatedPath) {
|
||||
if (tag.tag === "link" && tag.attributes.href === baseUrl + relatedPath) {
|
||||
const vignetteFetch = await REST.get(etape.relationships.field_vignette.links.related.href);
|
||||
this.content[direction] = {
|
||||
url: tag.attributes.href,
|
||||
|
@ -223,7 +223,7 @@ export const useContentStore = defineStore('content', {
|
|||
if (path.endsWith(liHref)) {
|
||||
const previousEtapeItemPath = li.previousElementSibling?.querySelector('a').getAttribute('href');
|
||||
const nextEtapeItemPath = li.nextElementSibling?.querySelector('a').getAttribute('href');
|
||||
|
||||
|
||||
if (previousEtapeItemPath && direction === 'previous') {
|
||||
let prevContent = await getRelatedEtapeContent(previousEtapeItemPath, allEtapesData);
|
||||
return prevContent;
|
||||
|
@ -256,4 +256,4 @@ export const useContentStore = defineStore('content', {
|
|||
this.error = null;
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,38 +34,48 @@ export const useLayoutStore = defineStore('layout', {
|
|||
this.isEtapeListRetracted = false;
|
||||
},
|
||||
setUpHamburgerToggle(menuBurger, menuContainer) {
|
||||
const menuTitle = document.querySelector('#menu-title');
|
||||
const menuH2 = document.querySelector('#menu > h2');
|
||||
const menuTitle = document.querySelector('#menu-title');
|
||||
const menuH2 = document.querySelector('#menu > h2');
|
||||
|
||||
menuBurger.addEventListener('click', (e) => {
|
||||
menuBurger.addEventListener('click', (e) => {
|
||||
this.toggleHamburgerMenu(menuBurger, menuContainer, menuTitle, menuH2);
|
||||
});
|
||||
document.addEventListener('click', (e) => {
|
||||
if (
|
||||
(!menuContainer.contains(e.target) && !menuBurger.contains(e.target))
|
||||
|| e.target.tagName === 'A'
|
||||
) {
|
||||
menuContainer.classList.remove('open');
|
||||
menuTitle.classList.remove('open');
|
||||
menuBurger.classList.remove('open');
|
||||
menuH2.classList.remove('open');
|
||||
setTimeout(() => {
|
||||
if (!this.isHamburgerMenuOpen) menuContainer.style.display = 'block';
|
||||
menuContainer.classList.toggle('open');
|
||||
menuTitle.classList.toggle('open');
|
||||
menuBurger.classList.toggle('open');
|
||||
menuH2.classList.toggle('open');
|
||||
if (this.isHamburgerMenuOpen) {
|
||||
setTimeout(() => {
|
||||
menuContainer.style.display = 'none';
|
||||
this.isHamburgerMenuOpen = !this.isHamburgerMenuOpen;
|
||||
}, 300);
|
||||
}
|
||||
}, 50);
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!menuContainer.contains(e.target) && !menuBurger.contains(e.target)) {
|
||||
menuContainer.classList.remove('open');
|
||||
menuTitle.classList.remove('open');
|
||||
menuBurger.classList.remove('open');
|
||||
menuH2.classList.remove('open');
|
||||
setTimeout(() => {
|
||||
if (this.isHamburgerMenuOpen) {
|
||||
menuContainer.style.display = 'none';
|
||||
}
|
||||
this.isHamburgerMenuOpen = false;
|
||||
}, 300);
|
||||
if (this.isHamburgerMenuOpen) {
|
||||
menuContainer.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
}, 300);
|
||||
this.isHamburgerMenuOpen = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
toggleHamburgerMenu(menuBurger, menuContainer, menuTitle, menuH2) {
|
||||
setTimeout(() => {
|
||||
if (!this.isHamburgerMenuOpen) menuContainer.style.display = 'block';
|
||||
menuContainer.classList.toggle('open');
|
||||
menuTitle.classList.toggle('open');
|
||||
menuBurger.classList.toggle('open');
|
||||
menuH2.classList.toggle('open');
|
||||
// console.log('isHamburgerMenuOpen', this.isHamburgerMenuOpen);
|
||||
console.log(this.isHamburgerMenuOpen);
|
||||
if (this.isHamburgerMenuOpen) {
|
||||
setTimeout(() => {
|
||||
menuContainer.style.display = 'none';
|
||||
}, 300);
|
||||
}
|
||||
console.log('TOGGLE', this.isHamburgerMenuOpen);
|
||||
console.log('isHamburgerMenuOpen', this.isHamburgerMenuOpen);
|
||||
this.isHamburgerMenuOpen = !this.isHamburgerMenuOpen;
|
||||
}, 50);
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,23 +10,30 @@ export const useMapStore = defineStore('mapState', {
|
|||
currentPlace: Object,
|
||||
maxZoom: Number,
|
||||
currentZoom: Number,
|
||||
duration: 3,
|
||||
animationsAreEnabled: true,
|
||||
animationDuration: 3,
|
||||
}),
|
||||
actions: {
|
||||
zoomToPlace(lat, long) {
|
||||
if (useLayoutStore().isDesktop) long = long - 0.03;
|
||||
this.map.flyTo([lat, long], this.maxZoom, { duration: this.duration });
|
||||
this.currentZoom = this.maxZoom;
|
||||
this.map.flyTo(
|
||||
[lat, long],
|
||||
this.maxZoom,
|
||||
{ animate: this.animationsAreEnabled, animationDuration: this.animationDuration });
|
||||
this.currentZoom = this.maxZoom;
|
||||
},
|
||||
resetMap() {
|
||||
this.map.flyTo(this.defaultMapCenter, useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile, { duration: this.duration });
|
||||
this.map.flyTo(
|
||||
this.defaultMapCenter,
|
||||
useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile,
|
||||
{ animate: this.animationsAreEnabled, animationDuration: this.animationDuration });
|
||||
this.currentZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile;
|
||||
},
|
||||
lockMap() {
|
||||
setTimeout(() => {
|
||||
this.map.options.minZoom = this.currentZoom;
|
||||
this.map.options.maxZoom = this.currentZoom;
|
||||
}, this.duration * 1000 + 100);
|
||||
}, this.animationDuration * 1000 + 100);
|
||||
this.map.dragging.disable();
|
||||
this.map.touchZoom.disable();
|
||||
this.map.doubleClickZoom.disable();
|
||||
|
@ -34,17 +41,28 @@ export const useMapStore = defineStore('mapState', {
|
|||
this.map.boxZoom.disable();
|
||||
this.map.keyboard.disable();
|
||||
// map.tap.disable();
|
||||
},
|
||||
unlockMap() {
|
||||
this.map.options.minZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile;
|
||||
this.map.options.maxZoom = this.maxZoom;
|
||||
this.map.dragging.enable();
|
||||
this.map.touchZoom.enable();
|
||||
this.map.doubleClickZoom.enable();
|
||||
this.map.scrollWheelZoom.enable();
|
||||
this.map.boxZoom.enable();
|
||||
this.map.keyboard.enable();
|
||||
// map.tap.enable();
|
||||
},
|
||||
},
|
||||
unlockMap() {
|
||||
this.map.options.minZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile;
|
||||
this.map.options.maxZoom = this.maxZoom;
|
||||
this.map.dragging.enable();
|
||||
this.map.touchZoom.enable();
|
||||
this.map.doubleClickZoom.enable();
|
||||
this.map.scrollWheelZoom.enable();
|
||||
this.map.boxZoom.enable();
|
||||
this.map.keyboard.enable();
|
||||
// map.tap.enable();
|
||||
},
|
||||
toggleAnimation() {
|
||||
this.animationsAreEnabled = !this.animationsAreEnabled;
|
||||
},
|
||||
checkReducedMotion() {
|
||||
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
this.animationsAreEnabled = !mediaQuery.matches;
|
||||
|
||||
mediaQuery.addEventListener('change', (event) => {
|
||||
this.animationsAreEnabled = !event.matches;
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,11 +4,11 @@ import { useLayoutStore } from '../stores/layout';
|
|||
export async function initFirstLoadRouting(store, router, baseUrl, siteName) {
|
||||
const decoupled_origin = JSON.parse(window.localStorage.getItem('decoupled_origin'));
|
||||
|
||||
if(decoupled_origin) {
|
||||
if(decoupled_origin) {
|
||||
await store.fetchContentData(baseUrl + decoupled_origin.url);
|
||||
router.push(decoupled_origin.url);
|
||||
window.localStorage.removeItem("decoupled_origin");
|
||||
document.title = store.pageTitle;
|
||||
document.title = store.pageTitle;
|
||||
setActiveNavItem(store.contentType, decoupled_origin.url);
|
||||
} else {
|
||||
document.title = siteName;
|
||||
|
@ -23,19 +23,29 @@ export function handleClickableElements(clickableElements, store, router, baseUr
|
|||
link.onclick = async function (e) {
|
||||
router.push(href);
|
||||
if (href !== window.location.pathname) {
|
||||
if (href === '/') {
|
||||
store.resetStore(true);
|
||||
document.title = siteName;
|
||||
mapStore.resetMap();
|
||||
} else {
|
||||
await store.fetchContentData(baseUrl + href);
|
||||
document.title = store.pageTitle;
|
||||
}
|
||||
setActiveNavItem(store.contentType, href);
|
||||
|
||||
const listeEtape = document.querySelector('#etapes-liste');
|
||||
if (!useLayoutStore().isDesktop) useLayoutStore().collapseEtapeListe(listeEtape);
|
||||
pageChange(href, store, siteName, mapStore, baseUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleBrowserNavigation(store, baseUrl, siteName, mapStore) {
|
||||
let href = window.location.pathname;
|
||||
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
|
||||
pageChange(href, store, siteName, mapStore, baseUrl)
|
||||
}
|
||||
|
||||
async function pageChange(href, store, siteName, mapStore, baseUrl) {
|
||||
if (href === '/') {
|
||||
store.resetStore(true);
|
||||
document.title = siteName;
|
||||
mapStore.resetMap();
|
||||
} else {
|
||||
await store.fetchContentData(baseUrl + href);
|
||||
document.title = store.pageTitle;
|
||||
}
|
||||
setActiveNavItem(store.contentType, href);
|
||||
|
||||
const listeEtape = document.querySelector('#etapes-liste');
|
||||
if (!useLayoutStore().isDesktop) useLayoutStore().collapseEtapeListe(listeEtape);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export function processClickableElements() {
|
||||
return {
|
||||
return {
|
||||
etapeListLinks: processEtapeLinks(),
|
||||
generalListLinks: processStaticLinks(),
|
||||
logoLink: processLogoLink(),
|
||||
|
@ -26,15 +26,7 @@ function processEtapeLinks() {
|
|||
function processStaticLinks() {
|
||||
const general_link_fields = document.querySelectorAll('#menu > ul > li > a');
|
||||
for (let i = 0; i < general_link_fields.length; i ++) {
|
||||
let general_link_path = general_link_fields[i].getAttribute('data-drupal-link-system-path');
|
||||
if (general_link_path && general_link_path !== '<front>') {
|
||||
const match = [...general_link_path.match(/^node\/(\d+)$/)];
|
||||
if (match) {
|
||||
const nid = match[1];
|
||||
general_link_fields[i].setAttribute('data-nid', parseInt(nid));
|
||||
}
|
||||
}
|
||||
general_link_fields[i].addEventListener('click', (e) => e.preventDefault());
|
||||
general_link_fields[i].addEventListener('click', (e) => e.preventDefault());
|
||||
}
|
||||
|
||||
return general_link_fields;
|
||||
|
@ -70,11 +62,11 @@ function processMapIcons() {
|
|||
const popup = document.querySelector('.leaflet-tooltip-center > div');
|
||||
popup.style.opacity = "1";
|
||||
});
|
||||
|
||||
|
||||
icon.addEventListener('mouseleave', () => {
|
||||
icon.style.transform = icon.style.transform.split(' ')[0] + icon.style.transform.split(' ')[1] + icon.style.transform.split(' ')[2];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return icons;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export function setActiveNavItem(contentType, href) {
|
||||
const staticNavItems = document.querySelectorAll('#menu > ul > li > a');
|
||||
const etapeNavItems = document.querySelectorAll('#etapes-liste li a');
|
||||
|
||||
|
||||
for (let item of staticNavItems) {
|
||||
item.classList.remove('is-active');
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ export function setActiveNavItem(contentType, href) {
|
|||
for (let item of etapeNavItems) {
|
||||
item.closest('li').classList.remove('inactive');
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
if (contentType === 'static') {
|
||||
for (let item of staticNavItems) {
|
||||
|
@ -32,4 +32,4 @@ export function setActiveNavItem(contentType, href) {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { createApp } from 'vue';
|
|||
import { createPinia } from 'pinia';
|
||||
import router from '../router/router';
|
||||
import Modale from '../vuejs/Modale.vue';
|
||||
import AnimationToggle from '../vuejs/AnimationToggle.vue';
|
||||
import VueImageZoomer from 'vue-image-zoomer';
|
||||
import 'vue-image-zoomer/dist/style.css';
|
||||
|
||||
|
@ -9,14 +10,20 @@ import { useContentStore } from '../stores/content';
|
|||
import { useMapStore } from '../stores/map';
|
||||
|
||||
export function initVueContentModale() {
|
||||
const pinia = createPinia();
|
||||
|
||||
const app = createApp(Modale)
|
||||
.use(createPinia())
|
||||
.use(router)
|
||||
.use(VueImageZoomer);
|
||||
.use(pinia)
|
||||
.use(router)
|
||||
.use(VueImageZoomer);
|
||||
|
||||
const store = useContentStore();
|
||||
const mapStore = useMapStore();
|
||||
app.mount('#content-modale');
|
||||
app.mount('#content-modale');
|
||||
|
||||
const animationToggle = createApp(AnimationToggle)
|
||||
.use(pinia)
|
||||
.mount('#animation-toggle');
|
||||
|
||||
return { store, mapStore, router };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<div @click="handleClick" class="animation-toggle-container">
|
||||
<div><p>Activer les animations</p></div>
|
||||
<label class="switch">
|
||||
<input type="checkbox" v-model="animationsAreEnabled" @click.stop @change="toggleAnimation" />
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { useMapStore } from '../stores/map';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const mapStore = useMapStore();
|
||||
|
||||
const { animationsAreEnabled } = storeToRefs(mapStore);
|
||||
|
||||
const toggleAnimation = () => {
|
||||
mapStore.toggleAnimation();
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
toggleAnimation();
|
||||
};
|
||||
|
||||
return {
|
||||
handleClick,
|
||||
toggleAnimation,
|
||||
animationsAreEnabled,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<Transition>
|
||||
<Transition
|
||||
:enter-active-class="animationsAreEnabled ? 'v-enter-active' : 'no-transition'"
|
||||
:leave-active-class="animationsAreEnabled ? 'v-leave-active' : 'no-transition'"
|
||||
>
|
||||
<div v-if="!loading && (contentType === 'etape' || contentType === 'static')">
|
||||
<div class="content-wrapper">
|
||||
<ModaleHeader
|
||||
|
@ -8,8 +11,8 @@
|
|||
:couleur="content.couleur || brandColor" />
|
||||
<main>
|
||||
<div v-for="partie in content.parties" class="partie">
|
||||
<ModaleCarteSensible
|
||||
v-if="partie.type === 'carte_sensible'"
|
||||
<ModaleCarteSensible
|
||||
v-if="partie.type === 'carte_sensible'"
|
||||
:partie="partie" />
|
||||
<ModaleTitreTexte
|
||||
v-if="partie.type === 'titre_texte'"
|
||||
|
@ -78,10 +81,10 @@ const {
|
|||
contentType,
|
||||
content,
|
||||
loading,
|
||||
error,
|
||||
error,
|
||||
} = storeToRefs(store);
|
||||
|
||||
const { map, duration } = storeToRefs(mapState);
|
||||
const { defaultMapCenter, animationDuration, animationsAreEnabled } = storeToRefs(mapState);
|
||||
|
||||
let isModaleEtape, wasModaleEtape;
|
||||
|
||||
|
@ -90,10 +93,10 @@ const brandColor = "#80c8bf";
|
|||
const handleColorChange = () => {
|
||||
watch(
|
||||
() => content.value.couleur,
|
||||
() => {
|
||||
() => {
|
||||
if (contentType.value === 'etape' && content.value.couleur) {
|
||||
document.documentElement.style.setProperty('--etape-couleur', content.value.couleur || brandColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -103,33 +106,59 @@ const handleMapMovement = () => {
|
|||
() => loading.value,
|
||||
() => {
|
||||
if (!loading.value) {
|
||||
isModaleEtape = contentType.value === 'etape';
|
||||
|
||||
if (!wasModaleEtape && isModaleEtape) {
|
||||
// national -> détail
|
||||
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
|
||||
mapState.zoomToPlace(content.value.coordinates.lat, content.value.coordinates.lon);
|
||||
} else if (wasModaleEtape && isModaleEtape) {
|
||||
// détail -> détail
|
||||
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(content.value.coordinates.lat, content.value.coordinates.lon);
|
||||
}, duration.value * 1000);
|
||||
|
||||
} else if (wasModaleEtape && !isModaleEtape) {
|
||||
// détail -> national
|
||||
document.documentElement.style.setProperty('--modale-leave-delay', 0);
|
||||
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
|
||||
mapState.resetMap();
|
||||
} else if (!wasModaleEtape && !isModaleEtape) {
|
||||
// national -> national
|
||||
console.log('national -> national');
|
||||
document.documentElement.style.setProperty('--modale-leave-delay', 0);
|
||||
document.documentElement.style.setProperty('--modale-enter-delay', '0.5s');
|
||||
isModaleEtape = contentType.value === 'etape';
|
||||
|
||||
// Define helper functions in variables
|
||||
const disableModaleTransition = () => {
|
||||
document.documentElement.style.setProperty('margin-top', '0');
|
||||
document.documentElement.style.setProperty('transition', 'none');
|
||||
}
|
||||
|
||||
const setModaleTransition = (enterDelay) => {
|
||||
document.documentElement.style.setProperty('--modale-enter-delay', `${enterDelay}s`);
|
||||
};
|
||||
|
||||
const zoomToContentPlace = () => {
|
||||
mapState.zoomToPlace(
|
||||
content.value.coordinates.lat ? content.value.coordinates.lat : defaultMapCenter.value.lat,
|
||||
content.value.coordinates.lon ? content.value.coordinates.lon : defaultMapCenter.value.lng
|
||||
);
|
||||
};
|
||||
|
||||
if (animationsAreEnabled.value) {
|
||||
|
||||
if (isModaleEtape) {
|
||||
if (!wasModaleEtape) {
|
||||
console.log('national -> détail');
|
||||
setModaleTransition(animationDuration.value);
|
||||
zoomToContentPlace();
|
||||
} else {
|
||||
console.log('détail -> détail');
|
||||
setModaleTransition(animationDuration.value);
|
||||
//mapState.resetMap();
|
||||
zoomToContentPlace();
|
||||
//setTimeout(zoomToContentPlace, animationDuration.value * 1000);
|
||||
}
|
||||
} else {
|
||||
if (wasModaleEtape) {
|
||||
console.log('détail -> national');
|
||||
setModaleTransition(animationDuration.value);
|
||||
mapState.resetMap();
|
||||
} else {
|
||||
console.log('national -> national');
|
||||
setModaleTransition(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isModaleEtape) {
|
||||
zoomToContentPlace();
|
||||
} else {
|
||||
mapState.resetMap();
|
||||
}
|
||||
disableModaleTransition();
|
||||
}
|
||||
|
||||
scrollTo(0, 0);
|
||||
|
||||
wasModaleEtape = isModaleEtape;
|
||||
}
|
||||
},
|
||||
|
@ -138,7 +167,7 @@ const handleMapMovement = () => {
|
|||
|
||||
onMounted(() => {
|
||||
isModaleEtape = contentType.value === 'etape';
|
||||
wasModaleEtape = isModaleEtape;
|
||||
wasModaleEtape = isModaleEtape;
|
||||
handleColorChange();
|
||||
handleMapMovement();
|
||||
});
|
||||
|
@ -150,7 +179,7 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.v-leave-active {
|
||||
transition: margin-top 0.5s ease-in var(--modale-leave-delay);
|
||||
transition: margin-top 0.5s ease-in;
|
||||
}
|
||||
|
||||
.v-enter-from,
|
||||
|
@ -160,6 +189,12 @@ onMounted(() => {
|
|||
|
||||
.v-enter-to,
|
||||
.v-leave-from {
|
||||
margin-top: 0vh;
|
||||
margin-top: 0vh;
|
||||
}
|
||||
</style>
|
||||
|
||||
/* This class will disable transitions */
|
||||
.no-transition {
|
||||
margin-top: 0 !important;
|
||||
transition: none !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<div class="brand-pattern pattern-bottom" :style="{ backgroundColor: couleur }">
|
||||
<div class="pattern"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="contentType === 'etape' && (content.previous || content.next)" class="related-etape-links">
|
||||
<div v-if="content.previous" class="card previous" @click="displayRelatedElement(content.previous.url)">
|
||||
<div v-if="content.previous" class="card previous" @click="clickRelatedElement(content.previous.url)">
|
||||
<div class="icon">
|
||||
<div :style="{ backgroundColor: content.previous.couleur }"></div>
|
||||
<div :style="{ backgroundColor: content.previous.couleur }"></div>
|
||||
|
@ -21,7 +21,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="content.next" class="card next" @click="displayRelatedElement(content.next.url)">
|
||||
<div v-if="content.next" class="card next" @click="clickRelatedElement(content.next.url)">
|
||||
<div class="icon">
|
||||
<div :style="{ backgroundColor: content.next.couleur }"></div>
|
||||
<div :style="{ backgroundColor: content.next.couleur }"></div>
|
||||
|
@ -57,10 +57,19 @@ const props = defineProps({
|
|||
|
||||
async function displayRelatedElement(href) {
|
||||
const baseUrl = window.location.protocol + "//" + window.location.host;
|
||||
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
|
||||
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
|
||||
|
||||
router.push(href);
|
||||
await store.fetchContentData(baseUrl + href);
|
||||
document.title = store.pageTitle;
|
||||
}
|
||||
</script>
|
||||
|
||||
import { setActiveNavItem } from '../../utils/set-active-nav-item.js';
|
||||
|
||||
function clickRelatedElement(href) {
|
||||
const baseUrl = window.location.protocol + "//" + window.location.host;
|
||||
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
|
||||
setActiveNavItem('etape', href);
|
||||
displayRelatedElement(href);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -63,7 +63,7 @@ body{
|
|||
display: flex;
|
||||
align-items: center;
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
grid-column: 1 / span 1;
|
||||
grid-column: 1 / span 1;
|
||||
}
|
||||
> div > div > a > img {
|
||||
width: 100%;
|
||||
|
@ -76,7 +76,7 @@ body{
|
|||
align-items: center;
|
||||
padding-right: 2.5rem;
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
grid-column: 2 / span 2;
|
||||
grid-column: 2 / span 2;
|
||||
}
|
||||
> div > div > a > img {
|
||||
width: 100%;
|
||||
|
@ -90,7 +90,7 @@ body{
|
|||
display: flex;
|
||||
align-items: center;
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
grid-column: 8 / span 2;
|
||||
grid-column: 8 / span 2;
|
||||
}
|
||||
> div > div > a > img {
|
||||
width: 100%;
|
||||
|
@ -296,7 +296,7 @@ body{
|
|||
> div {
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .layout__region--second {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
|
@ -404,7 +404,7 @@ body{
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
*/
|
||||
*/
|
||||
padding-top: 10px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
|
@ -597,6 +597,7 @@ body{
|
|||
margin: 30px 0;
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
padding-right: 0.5rem;
|
||||
transition: transform 0.3s ease-out, opacity 0.3s ease-out;
|
||||
cursor: pointer;
|
||||
> .infos-arret {
|
||||
|
@ -625,7 +626,7 @@ body{
|
|||
text-align: right;
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
font-size: $m-font-size-desktop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .views-field-field-adresse-postal-code {
|
||||
|
@ -647,7 +648,7 @@ body{
|
|||
content: ')';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
> .views-field-field-dates {
|
||||
grid-column: 1 / span 2;
|
||||
|
@ -821,7 +822,7 @@ body{
|
|||
@media screen and (min-width: $tablet-min-width) {
|
||||
width: calc($modale-width-mobile - $modale-x-padding * 6);
|
||||
margin-left: $modale-x-padding * 3;
|
||||
|
||||
|
||||
}
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
width: calc($modale-width-desktop - $modale-x-padding * 4);
|
||||
|
@ -960,7 +961,7 @@ body{
|
|||
> .description {
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
width: calc(100% - 6rem);
|
||||
margin-top: 0;
|
||||
}
|
||||
|
@ -1178,6 +1179,75 @@ body{
|
|||
}
|
||||
}
|
||||
}
|
||||
> #animation-toggle > div {
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
bottom: $body-margin-bottom;
|
||||
right: $body-margin-x;
|
||||
z-index: 999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.4rem 1.2rem;
|
||||
border-radius: 10rem;
|
||||
background-color: white;
|
||||
transition: background-color 0.3s ease-out;
|
||||
|
||||
> div {
|
||||
margin-right: 1rem;
|
||||
> p {
|
||||
font-size: $sm-font-size-mobile;
|
||||
@media screen and (min-width: $desktop-min-width) {
|
||||
font-size: $sm-font-size-desktop;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 2.2rem;
|
||||
height: 1.2rem;
|
||||
> input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
&:checked + .slider {
|
||||
background-color: $brand-color;
|
||||
}
|
||||
&:focus + .slider {
|
||||
box-shadow: 0 0 1px $brand-color;
|
||||
}
|
||||
&:checked + .slider::before {
|
||||
-webkit-transform: translateX(1rem);
|
||||
-ms-transform: translateX(1rem);
|
||||
transform: translateX(1rem);
|
||||
}
|
||||
}
|
||||
> .slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 34px;
|
||||
background-color: $main-color-light;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
border-radius: 50%;
|
||||
left: 0.1rem;
|
||||
bottom: 0.1rem;
|
||||
background-color: $light-color;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .user-login-form {
|
||||
height: 90vh;
|
||||
|
@ -1192,5 +1262,5 @@ body{
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,5 +52,6 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
<div id="content-modale"></div>
|
||||
<div id="animation-toggle"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
Loading…
Reference in New Issue