diff --git a/web/modules/custom/q2d_mod/assets/js/carte-interactive-qdd.js b/web/modules/custom/q2d_mod/assets/js/carte-interactive-qdd.js index b705533..01ca15b 100644 --- a/web/modules/custom/q2d_mod/assets/js/carte-interactive-qdd.js +++ b/web/modules/custom/q2d_mod/assets/js/carte-interactive-qdd.js @@ -4,95 +4,24 @@ const popup = document.querySelector('#sites-map-container #popup'); const popupContent = document.querySelector('#sites-map-container #popup-content'); const modalBackground = document.querySelector('#sites-map-container #modal-background'); +// Vérifiez si la page contient la classe '.node-type-site' +const isSitePage = document.body.classList.contains('node-type-site'); + + // Fonction pour afficher le popup function showPopup(content, x, y, isLeftHalf) { + // Si on est sur une page avec la classe 'node-type-site', ne pas afficher le popup + if (isSitePage) return; + popupContent.innerHTML = content; -// // Récupérer la position et les dimensions du conteneur SVG -// const rect = svgElement.getBoundingClientRect(); - -// // Récupérer la position de défilement (scroll) de la page -// const scrollX = window.scrollX; -// const scrollY = window.scrollY; - -// // Variables pour stocker les positions calculées du popup -// let popupX, popupY; - -// // Afficher temporairement le popup pour mesurer ses dimensions -// popup.style.display = 'block'; -// const popupWidth = popup.offsetWidth; -// const popupHeight = popup.offsetHeight; - - - -// // // Vérifier si le point est dans la moitié gauche ou droite du SVG -// // if (isLeftHalf) { -// // console.log('Le point est dans la moitié gauche'); -// // // Aligner le popup à gauche du cercle -// // popupX = rect.left + x -scrollX - popupWidth - 800; // Ajuster ici si nécessaire -// // popupContent.style.textAlign = 'right'; // Alignement du texte à droite -// // } else { -// // console.log('Le point est dans la moitié droite'); -// // // Aligner le popup à droite du cercle -// popupX = rect.left + x + scrollX - popupWidth ; -// popupContent.style.textAlign = 'left'; // Alignement du texte à gauche -// // } - -// // // Calculer la position Y avec un ajustement pour éviter qu'il soit trop bas -// const offsetY = - popupHeight - 10; // Ajuster la position vers le haut avec un décalage -// popupY = rect.top + offsetY; // Centrer verticalement, puis ajuster - -// // console.log('rect.top:', rect.top); -// // console.log('y:', y); -// // console.log('scrollY:', scrollY); -// // console.log('popupHeight:', popupHeight); -// // console.log('offsetY:', offsetY); - - -// // // Empêcher le popup de dépasser les bords de l'écran -// // const viewportWidth = window.innerWidth; -// // const viewportHeight = window.innerHeight; - -// // // Vérifier si le popup dépasse à droite de l'écran -// // if (popupX + popupWidth > viewportWidth) { -// // popupX = viewportWidth - popupWidth - 10; // Ajustement à droite -// // } - -// // // Vérifier si le popup dépasse à gauche -// // if (popupX < 10) { -// // popupX = 10; // Ajustement à gauche -// // } - -// // // Vérifier si le popup dépasse en bas -// // if (popupY + popupHeight > viewportHeight) { -// // popupY = viewportHeight - popupHeight - 10; // Ajustement en bas -// // } - -// // // Vérifier si le popup dépasse en haut -// // if (popupY < 10) { -// // popupY = 10; // Ajustement en haut -// // } - -// // Appliquer les positions calculées au popup -// popup.style.left = `${popupX}px`; -// popup.style.top = `${popupY}px`; // Afficher le popup et le fond de modal popup.style.display = 'block'; modalBackground.style.display = 'block'; -// console.log(`Popup affiché à x: ${popupX}, y: ${popupY}`); } -// // Recalculer la position du popup lors du redimensionnement de la fenêtre -// window.addEventListener('resize', function() { -// if (popup.style.display === 'block') { -// const currentPopupRect = popup.getBoundingClientRect(); -// const rect = svgElement.getBoundingClientRect(); -// showPopup(popupContent.innerHTML, currentPopupRect.left - rect.left, currentPopupRect.top - rect.top); -// } -// }); - // Fonction pour fermer le popup function closePopup() { popup.style.display = 'none'; @@ -104,19 +33,6 @@ svgElement.addEventListener('mouseover', function(event) { if (event.target.classList.contains('site-link')) { const content = event.target.getAttribute('data-content'); -// // Récupérer la position et les dimensions du SVG -// const rect = svgElement.getBoundingClientRect(); - -// // Calculer la position relative du cercle -// const circleX = event.clientX - rect.left; -// const circleY = event.clientY - rect.top; - -// // // Calculer la moitié du SVG -// // const svgHalfWidth = rect.width / 2; - -// // // Déterminer si le cercle est sur la moitié gauche ou droite du SVG -// // const isLeftHalf = circleX < svgHalfWidth; - // Afficher le popup avec la position et l'alignement adaptés showPopup(content); } @@ -179,5 +95,22 @@ svgElement.addEventListener('click', function(event) { }); +///////////////////// page site point rouge /////////////////////// + +// Récupérer l'ID de la page depuis la classe du body +const body = document.querySelector('body'); +const pageId = body.className.match(/node-id-(\d+)/)[1]; // Extraire l'ID de la page + +// Sélectionner le groupe SVG qui a l'ID correspondant +const matchingGroup = document.querySelector(`#site-${pageId}`); + +// Si un groupe correspondant est trouvé, changer la couleur du cercle à l'intérieur +if (matchingGroup) { + const circle = matchingGroup.querySelector('circle'); // Sélectionner le cercle à l'intérieur du groupe + if (circle) { + circle.setAttribute('fill', 'red'); // Changer la couleur du cercle + } +} + diff --git a/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js b/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js index 4e8fce5..d42c2bf 100644 --- a/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js +++ b/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js @@ -36,7 +36,7 @@ eval("document.addEventListener('scroll', function() {\n const scrolled = win \**********************************************/ /***/ (function() { -eval("/**\n * @file\n * quartiers_de_demain behaviors.\n */\n (function (Drupal) {\n\n 'use strict';\n \n Drupal.behaviors.quartiers_de_demain = {\n attach: function (context, settings) {\n console.log('It works!');\n }\n };\n } (Drupal));\n\n\n //////// start header ////////////\n document.addEventListener('DOMContentLoaded', function() {\n\n const header = document.querySelector('header');\n const logo = document.querySelector('#block-quartiers-de-demain-logoquartiersdedemain > div:nth-child(1) > div:nth-child(1) > a:nth-child(1) > svg:nth-child(1)');\n const headerNavContainer = document.querySelector('.header_nav_container');\n const isFirstLoad = !performance.getEntriesByType(\"navigation\")[0].type.includes('back_forward');\n const isTargetPath = window.location.pathname === '/';\n\n // Fonction pour démarrer l'animation du logo SVG\n function startLogoAnimation() {\n logo.classList.add('animated');\n }\n \n // Fonction pour arrêter l'animation du logo SVG\n function stopLogoAnimation() {\n logo.classList.remove('animated');\n }\n \n // Vérifier si le header a la classe header--collapse\n function checkHeaderCollapse() {\n if (header.classList.contains('header--collapsed')) {\n stopLogoAnimation();\n } else if (header.classList.contains('header--collapsed-already')) {\n stopLogoAnimation();\n } else {\n startLogoAnimation();\n }\n\n }\n \n // Appeler la fonction au chargement initial\n checkHeaderCollapse();\n \n // Observer les changements de classe sur le header\n const observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(mutation) {\n if (mutation.attributeName === 'class') {\n checkHeaderCollapse();\n }\n });\n });\n observer.observe(header, { attributes: true });\n \n\n // Si ce n'est pas la première charge ou si le chemin n'est pas le chemin cible, ajouter la classe immédiatement\n if (!isFirstLoad || !isTargetPath) {\n header.classList.add('header--collapsed-already');\n // logo.classList.remove('animated');\n stopLogoAnimation();\n } else {\n // Sinon, appliquer la transition après un délai\n setTimeout(() => {\n header.classList.add('header--collapsed');\n }, 5000);\n }\n\n //////////////////////////////////////\n\n let lastScrollTop = 0;\n let threshold = 100; // Change this value as needed\n let isHidden = false;\n \n function slideOut() {\n headerNavContainer.animate([\n { transform: 'translateX(0)' },\n { transform: 'translateX(-100%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = true;\n }\n \n function slideIn() {\n headerNavContainer.animate([\n { transform: 'translateX(-100%)' },\n { transform: 'translateX(0)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = false;\n }\n \n function slideDown() {\n // headerNavContainer.style.display = 'block';\n headerNavContainer.animate([\n { transform: 'translateY(0%)' },\n { transform: 'translateY(+100%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = false;\n }\n \n function slideUp() {\n headerNavContainer.animate([\n { transform: 'translateY(100%)' },\n { transform: 'translateY(0%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n }).onfinish = function() {\n // headerNavContainer.style.display = 'none';\n };\n isHidden = true;\n }\n // Fonction pour ajuster la hauteur du header lors du défilement\n function adjustHeaderHeight() {\n if (window.scrollY > 0) {\n header.classList.add('shrink');\n } else {\n header.classList.remove('shrink');\n }\n }\n\n function handleScroll() {\n let scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const isMobile = window.innerWidth < 811;\n\n if (scrollTop > threshold && !isHidden) {\n if (isMobile) {\n slideUp();\n } else {\n slideOut();\n }\n } else if (scrollTop <= threshold && isHidden) {\n if (isMobile) {\n slideDown();\n } else {\n slideIn();\n }\n }\n \n \n lastScrollTop = scrollTop <= 0 ? 0 : scrollTop; // For Mobile or negative scrolling\n }\n \n function handleTouchAndMouseEnter() {\n if (isHidden) {\n if (window.innerWidth < 811) {\n slideDown();\n } else {\n slideIn();\n }\n }\n }\n \n function handleTouchAndMouseLeave() {\n if (lastScrollTop > threshold && !isHidden) {\n if (window.innerWidth < 811) {\n slideUp();\n } else {\n slideOut();\n }\n }\n }\n \n window.addEventListener('scroll', handleScroll);\n window.addEventListener('scroll', adjustHeaderHeight);\n \n // Mouse events for desktop\n header.addEventListener('mouseenter', handleTouchAndMouseEnter);\n header.addEventListener('mouseleave', handleTouchAndMouseLeave);\n \n // Touch events for tablets and mobile devices\n header.addEventListener('touchstart', handleTouchAndMouseEnter);\n header.addEventListener('touchend', handleTouchAndMouseLeave);\n \n // Initial check to see if we're at the top of the page\n if (window.pageYOffset <= threshold) {\n if (window.innerWidth < 811) {\n slideDown();\n } else { \n slideIn();\n } \n } else {\n if (window.innerWidth < 811) {\n slideUp();\n } else {\n slideIn();\n }\n }\n \n });\n\n //////// end header ////////////\n \n\n\n//// ancre dans texte au click parragraphe correspondant arrive en dessous du header \n\n\n(function($, window) {\n var adjustAnchor = function() {\n var $anchor = $('.sidebar_first_container'),\n fixedElementHeight = 500;\n if ($anchor.length > 0) {\n $('html, body').stop().animate({scrollTop: $anchor.offset().top - fixedElementHeight }, 0);\n }\n };\n\n $(window).on('hashchange', function() {\n adjustAnchor();\n });\n\n\n //////////////////////// start script smooth apparition des textes /////////////////\n\n function scrollReaveal(){\n\n const nodes = {\n logo : document.querySelectorAll('#logo-animated-container'),\n chapeau : document.querySelectorAll('.field_body'),\n paragraph: document.querySelectorAll('.field_field_textes .paragraph--type--static-parts'),\n enjeux : document.querySelectorAll('.field_field_textes .paragraph--type--static-parts .enjeux'),\n }\n\n const showUp = {\n origin: 'bottom',\n delay: 100,\n duration: 1000,\n distance: '50px',\n easing: 'cubic-bezier(0.5, 0, 0, 1)'\n }\n\n const Show = {\n delay: 100,\n duration: 600,\n easing: 'cubic-bezier(0.5, 0, 0, 1)'\n }\n\n console.log(nodes);\n\n ScrollReveal().reveal(nodes.logo, Show);\n ScrollReveal().reveal(nodes.chapeau, showUp);\n ScrollReveal().reveal(nodes.paragraph, showUp);\n ScrollReveal().reveal(nodes.enjeux, showUp);\n }\n\n\n $( document ).ready(function() {\n scrollReaveal();\n });\n\n //////////////////////// end script smooth apparition des textes /////////////////\n\n // //////////////////// start Timeline script ///////////////////////\n\n // Update month field to only show the first 3 letters\n document.querySelectorAll('.paragraph--type--phase-deroulement').forEach(function(paragraph) {\n const monthField = paragraph.querySelector('.field_field_date_de_moi div:nth-of-type(2)');\n if (monthField) {\n const monthText = monthField.textContent.trim();\n if (monthText === \"juillet\") {\n monthField.textContent = monthText.slice(0, 4);\n monthField.classList.add('after');\n } else if (monthText === \"juin\") {\n monthField.textContent = monthText.slice(0, 4);\n } else if (monthText.length > 3) {\n monthField.textContent = monthText.slice(0, 3);\n monthField.classList.add('after');\n }\n }\n });\n \n // Fonction pour ajouter ou retirer la classe .only\n function updateDateClasses() {\n document.querySelectorAll('.paragraph--type--phase-deroulement .date').forEach(function(dateElement) {\n const date2Element = dateElement.querySelector('.date2');\n const yearElement = dateElement.querySelector('.field_field_date_de_annee');\n \n if (date2Element && !date2Element.textContent.trim()) {\n if (yearElement) {\n yearElement.classList.add('only');\n }\n } else {\n if (yearElement) {\n yearElement.classList.remove('only');\n }\n }\n });\n }\n \n // Exécuter la fonction une première fois pour le contenu déjà présent\n updateDateClasses();\n \n // MutationObserver pour surveiller les changements dans le DOM\n const observer = new MutationObserver(function(mutationsList, observer) {\n for(let mutation of mutationsList) {\n if (mutation.type === 'childList') {\n updateDateClasses();\n }\n }\n });\n\n\n // ////////////////////// start calendrier home /////////////////////////////////\n $(document).ready(function(){\n $('.__timeline-content').slick({\n slidesToShow: 3,\n // slidesToScroll: 1,\n dots: false,\n arrows: true,\n centerMode: true,\n adaptiveHeight: true,\n autoplay: false,\n draggable: true,\n // autoplaySpeed: 1500,\n infinite: true,\n // centerPadding: '100px',\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: true,\n draggable: true,\n centerMode: true,\n autoplay: false,\n // autoplaySpeed: 2000,\n }\n }]\n });\n console.log('salut slick calendrier');\n \n });\n \n // ////////////////////// end calendrier home /////////////////////////////////\n \n \n\n //////////////////////// end Timeline script /////////////////////////////////////////////\n\n /////////////////// caracteres body actus/////////////////////////\n\n document.addEventListener('DOMContentLoaded', function() {\n // Maximum number of characters to display\n const maxChars = 140; // Adjust this value as needed\n \n document.querySelectorAll('#actus-caroussel .node-type-actualite .field_body p').forEach(function(paragraph) {\n let text = paragraph.textContent.trim();\n if (text.length > maxChars) {\n let truncatedText = text.slice(0, maxChars) + '...';\n paragraph.textContent = truncatedText;\n }\n });\n });\n \n\n //////////// slideshow home ////////////////////////// \n\n\n\n $(document).ready(function(){\n let actuview = $('.content-actus .view')\n if (actuview) {\n actuview.slick({\n slidesToShow: 3,\n // slidesToScroll: 1,\n dots: false,\n arrows: true,\n centerMode: true,\n adaptiveHeight: true,\n autoplay: false,\n // autoplaySpeed: 1500,\n // infinite: true,\n // centerPadding: '100px',\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: true,\n draggable: true,\n centerMode: true,\n autoplay: false,\n // autoplaySpeed: 2000,\n }\n }]\n });\n console.log('salut slick home');\n \n }\n $('.slick-carousel').slick({\n lazyLoad: 'progressive', // Option 'ondemand' ou 'progressive'\n });\n\n });\n\n\n\n\n $(document).ready(function () {\n let diapohome = $('.config_pages--type--diaporama-home .diaporama');\n\n if (diapohome.length) {\n // Initialisation de Slick\n diapohome.slick({\n slidesToShow: 1,\n dots: false,\n arrows: false,\n // centerMode: true,\n adaptiveHeight: true,\n autoplay: true, // Activer l'autoplay\n autoplaySpeed: 4000, // Changement de slide toutes les 4 secondes\n // infinite: true,\n pauseOnHover: false, // Ne pas arrêter l'autoplay lors du survol\n pauseOnFocus: false,\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: false,\n draggable: true,\n centerMode: false,\n }\n }]\n });\n\n }\n});\n\n\n///////////// carte sticky node site ///////////////////\n // window.addEventListener('scroll', function() {\n // const mapContainer = document.getElementById('sites-map-container');\n // const header = document.querySelector('header'); // Sélectionnez votre header\n\n // const headerHeight = header.offsetHeight; // Calculer la hauteur du header\n // const scrollPosition = window.scrollY; // Obtenir la position actuelle du scroll\n // console.log('Hauteur dynamique du header:', headerHeight);\n\n // if (scrollPosition >= headerHeight - 350 ) {\n // mapContainer.classList.add('fixed');\n // mapContainer.style.position = 'fixed';\n // mapContainer.style.top = headerHeight + 350 ; // Fixé en haut une fois passé le header\n // } else {\n // mapContainer.classList.remove('fixed');\n // mapContainer.style.position = 'static'; // Retour à la position initiale\n // }\n // });\n\n//////////////// lightbox galerie image page site////////////////////////\n\n// Sélectionne uniquement les images à l'intérieur de '.paragraph--type--site-diapo'\n// Sélectionne uniquement les images à l'intérieur de '.paragraph--type--site-diapo'\nlet images = document.querySelectorAll('.paragraph--type--site-diapo .lightbox-trigger');\nlet currentIndex;\n\n// Créer le lightbox et ses éléments\nconst lightbox = document.createElement('div');\nlightbox.id = 'lightbox';\nlightbox.classList.add('lightbox');\ndocument.body.appendChild(lightbox);\n\nconst img = document.createElement('img');\nlightbox.appendChild(img);\n\nconst closeBtn = document.createElement('span');\ncloseBtn.classList.add('close');\ncloseBtn.innerHTML = '×';\nlightbox.appendChild(closeBtn);\n\nconst prevBtn = document.createElement('a');\nprevBtn.classList.add('prev');\nprevBtn.innerHTML = '❮';\nlightbox.appendChild(prevBtn);\n\nconst nextBtn = document.createElement('a');\nnextBtn.classList.add('next');\nnextBtn.innerHTML = '❯';\nlightbox.appendChild(nextBtn);\n\n// Ajouter un écouteur d'événement sur chaque image pour ouvrir le lightbox\nimages.forEach((image, index) => {\n image.addEventListener('click', () => {\n lightbox.style.display = 'flex';\n img.src = image.src;\n currentIndex = index;\n });\n});\n\n// Fermer le lightbox\ncloseBtn.addEventListener('click', () => {\n lightbox.style.display = 'none';\n});\n\n// Naviguer vers l'image précédente\nprevBtn.addEventListener('click', () => {\n currentIndex = (currentIndex > 0) ? currentIndex - 1 : images.length - 1;\n img.src = images[currentIndex].src;\n});\n\n// Naviguer vers l'image suivante\nnextBtn.addEventListener('click', () => {\n currentIndex = (currentIndex < images.length - 1) ? currentIndex + 1 : 0;\n img.src = images[currentIndex].src;\n});\n\n// Fermer le lightbox quand on clique en dehors de l'image\nlightbox.addEventListener('click', (e) => {\n if (e.target === lightbox) {\n lightbox.style.display = 'none';\n }\n});\n\n\n \n\n})(jQuery, window);\n\n\n\n\n//# sourceURL=webpack://quartiers_de_demain/./src/assets/js/quartiers_de_demain.js?"); +eval("/**\n * @file\n * quartiers_de_demain behaviors.\n */\n (function (Drupal) {\n\n 'use strict';\n \n Drupal.behaviors.quartiers_de_demain = {\n attach: function (context, settings) {\n console.log('It works!');\n }\n };\n } (Drupal));\n\n\n //////// start header ////////////\n document.addEventListener('DOMContentLoaded', function() {\n\n const header = document.querySelector('header');\n const logo = document.querySelector('#block-quartiers-de-demain-logoquartiersdedemain > div:nth-child(1) > div:nth-child(1) > a:nth-child(1) > svg:nth-child(1)');\n const headerNavContainer = document.querySelector('.header_nav_container');\n const isFirstLoad = !performance.getEntriesByType(\"navigation\")[0].type.includes('back_forward');\n const isTargetPath = window.location.pathname === '/';\n\n // Fonction pour démarrer l'animation du logo SVG\n function startLogoAnimation() {\n logo.classList.add('animated');\n }\n \n // Fonction pour arrêter l'animation du logo SVG\n function stopLogoAnimation() {\n logo.classList.remove('animated');\n }\n \n // Vérifier si le header a la classe header--collapse\n function checkHeaderCollapse() {\n if (header.classList.contains('header--collapsed')) {\n stopLogoAnimation();\n } else if (header.classList.contains('header--collapsed-already')) {\n stopLogoAnimation();\n } else {\n startLogoAnimation();\n }\n\n }\n \n // Appeler la fonction au chargement initial\n checkHeaderCollapse();\n \n // Observer les changements de classe sur le header\n const observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(mutation) {\n if (mutation.attributeName === 'class') {\n checkHeaderCollapse();\n }\n });\n });\n observer.observe(header, { attributes: true });\n \n\n // Si ce n'est pas la première charge ou si le chemin n'est pas le chemin cible, ajouter la classe immédiatement\n if (!isFirstLoad || !isTargetPath) {\n header.classList.add('header--collapsed-already');\n // logo.classList.remove('animated');\n stopLogoAnimation();\n } else {\n // Sinon, appliquer la transition après un délai\n setTimeout(() => {\n header.classList.add('header--collapsed');\n }, 5000);\n }\n\n //////////////////////////////////////\n\n let lastScrollTop = 0;\n let threshold = 100; // Change this value as needed\n let isHidden = false;\n \n function slideOut() {\n headerNavContainer.animate([\n { transform: 'translateX(0)' },\n { transform: 'translateX(-100%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = true;\n }\n \n function slideIn() {\n headerNavContainer.animate([\n { transform: 'translateX(-100%)' },\n { transform: 'translateX(0)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = false;\n }\n \n function slideDown() {\n // headerNavContainer.style.display = 'block';\n headerNavContainer.animate([\n { transform: 'translateY(0%)' },\n { transform: 'translateY(+100%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = false;\n }\n \n function slideUp() {\n headerNavContainer.animate([\n { transform: 'translateY(100%)' },\n { transform: 'translateY(0%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n }).onfinish = function() {\n // headerNavContainer.style.display = 'none';\n };\n isHidden = true;\n }\n // Fonction pour ajuster la hauteur du header lors du défilement\n function adjustHeaderHeight() {\n if (window.scrollY > 0) {\n header.classList.add('shrink');\n } else {\n header.classList.remove('shrink');\n }\n }\n\n function handleScroll() {\n let scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const isMobile = window.innerWidth < 811;\n\n if (scrollTop > threshold && !isHidden) {\n if (isMobile) {\n slideUp();\n } else {\n slideOut();\n }\n } else if (scrollTop <= threshold && isHidden) {\n if (isMobile) {\n slideDown();\n } else {\n slideIn();\n }\n }\n \n \n lastScrollTop = scrollTop <= 0 ? 0 : scrollTop; // For Mobile or negative scrolling\n }\n \n function handleTouchAndMouseEnter() {\n if (isHidden) {\n if (window.innerWidth < 811) {\n slideDown();\n } else {\n slideIn();\n }\n }\n }\n \n function handleTouchAndMouseLeave() {\n if (lastScrollTop > threshold && !isHidden) {\n if (window.innerWidth < 811) {\n slideUp();\n } else {\n slideOut();\n }\n }\n }\n \n window.addEventListener('scroll', handleScroll);\n window.addEventListener('scroll', adjustHeaderHeight);\n \n // Mouse events for desktop\n header.addEventListener('mouseenter', handleTouchAndMouseEnter);\n header.addEventListener('mouseleave', handleTouchAndMouseLeave);\n \n // Touch events for tablets and mobile devices\n header.addEventListener('touchstart', handleTouchAndMouseEnter);\n header.addEventListener('touchend', handleTouchAndMouseLeave);\n \n // Initial check to see if we're at the top of the page\n if (window.pageYOffset <= threshold) {\n if (window.innerWidth < 811) {\n slideDown();\n } else { \n slideIn();\n } \n } else {\n if (window.innerWidth < 811) {\n slideUp();\n } else {\n slideIn();\n }\n }\n \n });\n\n//////// end header ////////////\n \n\n\n//// ancre dans texte au click parragraphe correspondant arrive en dessous du header \n\n\n(function($, window) {\n var adjustAnchor = function() {\n var $anchor = $('.sidebar_first_container'),\n fixedElementHeight = 500;\n if ($anchor.length > 0) {\n $('html, body').stop().animate({scrollTop: $anchor.offset().top - fixedElementHeight }, 0);\n }\n };\n\n $(window).on('hashchange', function() {\n adjustAnchor();\n });\n\n\n //////////////////////// start script smooth apparition des textes /////////////////\n\n function scrollReaveal(){\n\n const nodes = {\n logo : document.querySelectorAll('#logo-animated-container'),\n chapeau : document.querySelectorAll('.field_body'),\n paragraph: document.querySelectorAll('.field_field_textes .paragraph--type--static-parts'),\n enjeux : document.querySelectorAll('.field_field_textes .paragraph--type--static-parts .enjeux'),\n }\n\n const showUp = {\n origin: 'bottom',\n delay: 100,\n duration: 1000,\n distance: '50px',\n easing: 'cubic-bezier(0.5, 0, 0, 1)'\n }\n\n const Show = {\n delay: 100,\n duration: 600,\n easing: 'cubic-bezier(0.5, 0, 0, 1)'\n }\n\n console.log(nodes);\n\n ScrollReveal().reveal(nodes.logo, Show);\n ScrollReveal().reveal(nodes.chapeau, showUp);\n ScrollReveal().reveal(nodes.paragraph, showUp);\n ScrollReveal().reveal(nodes.enjeux, showUp);\n }\n\n\n $( document ).ready(function() {\n scrollReaveal();\n });\n\n //////////////////////// end script smooth apparition des textes /////////////////\n\n // //////////////////// start Timeline script ///////////////////////\n\n // Update month field to only show the first 3 letters\n document.querySelectorAll('.paragraph--type--phase-deroulement').forEach(function(paragraph) {\n const monthField = paragraph.querySelector('.field_field_date_de_moi div:nth-of-type(2)');\n if (monthField) {\n const monthText = monthField.textContent.trim();\n if (monthText === \"juillet\") {\n monthField.textContent = monthText.slice(0, 4);\n monthField.classList.add('after');\n } else if (monthText === \"juin\") {\n monthField.textContent = monthText.slice(0, 4);\n } else if (monthText.length > 3) {\n monthField.textContent = monthText.slice(0, 3);\n monthField.classList.add('after');\n }\n }\n });\n \n // Fonction pour ajouter ou retirer la classe .only\n function updateDateClasses() {\n document.querySelectorAll('.paragraph--type--phase-deroulement .date').forEach(function(dateElement) {\n const date2Element = dateElement.querySelector('.date2');\n const yearElement = dateElement.querySelector('.field_field_date_de_annee');\n \n if (date2Element && !date2Element.textContent.trim()) {\n if (yearElement) {\n yearElement.classList.add('only');\n }\n } else {\n if (yearElement) {\n yearElement.classList.remove('only');\n }\n }\n });\n }\n \n // Exécuter la fonction une première fois pour le contenu déjà présent\n updateDateClasses();\n \n // MutationObserver pour surveiller les changements dans le DOM\n const observer = new MutationObserver(function(mutationsList, observer) {\n for(let mutation of mutationsList) {\n if (mutation.type === 'childList') {\n updateDateClasses();\n }\n }\n });\n\n\n // ////////////////////// start calendrier home /////////////////////////////////\n $(document).ready(function(){\n $('.__timeline-content').slick({\n slidesToShow: 3,\n // slidesToScroll: 1,\n dots: false,\n arrows: true,\n centerMode: true,\n adaptiveHeight: true,\n autoplay: false,\n draggable: true,\n // autoplaySpeed: 1500,\n infinite: true,\n // centerPadding: '100px',\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: true,\n draggable: true,\n centerMode: true,\n autoplay: false,\n // autoplaySpeed: 2000,\n }\n }]\n });\n console.log('salut slick calendrier');\n \n });\n \n // ////////////////////// end calendrier home /////////////////////////////////\n \n \n\n //////////////////////// end Timeline script /////////////////////////////////////////////\n\n /////////////////// caracteres body actus/////////////////////////\n\n document.addEventListener('DOMContentLoaded', function() {\n // Maximum number of characters to display\n const maxChars = 140; // Adjust this value as needed\n \n document.querySelectorAll('#actus-caroussel .node-type-actualite .field_body p').forEach(function(paragraph) {\n let text = paragraph.textContent.trim();\n if (text.length > maxChars) {\n let truncatedText = text.slice(0, maxChars) + '...';\n paragraph.textContent = truncatedText;\n }\n });\n });\n \n\n //////////// slideshow home ////////////////////////// \n\n\n\n $(document).ready(function(){\n let actuview = $('.content-actus .view')\n if (actuview) {\n actuview.slick({\n slidesToShow: 3,\n // slidesToScroll: 1,\n dots: false,\n arrows: true,\n centerMode: true,\n adaptiveHeight: true,\n autoplay: false,\n // autoplaySpeed: 1500,\n // infinite: true,\n // centerPadding: '100px',\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: true,\n draggable: true,\n centerMode: true,\n autoplay: false,\n // autoplaySpeed: 2000,\n }\n }]\n });\n console.log('salut slick home');\n \n }\n $('.slick-carousel').slick({\n lazyLoad: 'progressive', // Option 'ondemand' ou 'progressive'\n });\n\n });\n\n\n\n\n $(document).ready(function () {\n let diapohome = $('.config_pages--type--diaporama-home .diaporama');\n\n if (diapohome.length) {\n // Initialisation de Slick\n diapohome.slick({\n slidesToShow: 1,\n dots: false,\n arrows: false,\n // centerMode: true,\n adaptiveHeight: true,\n autoplay: true, // Activer l'autoplay\n autoplaySpeed: 4000, // Changement de slide toutes les 4 secondes\n // infinite: true,\n pauseOnHover: false, // Ne pas arrêter l'autoplay lors du survol\n pauseOnFocus: false,\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: false,\n draggable: true,\n centerMode: false,\n }\n }]\n });\n\n }\n});\n\n\n\n//////////////// lightbox galerie image page site////////////////////////\n\n // Sélectionne uniquement les images à l'intérieur de '.paragraph--type--site-diapo'\n let images = document.querySelectorAll('.paragraph--type--site-diapo .lightbox-trigger');\n let currentIndex;\n\n // Créer le lightbox et ses éléments\n const lightbox = document.createElement('div');\n lightbox.id = 'lightbox';\n lightbox.classList.add('lightbox');\n document.body.appendChild(lightbox);\n\n const img = document.createElement('img');\n lightbox.appendChild(img);\n\n const closeBtn = document.createElement('span');\n closeBtn.classList.add('close');\n closeBtn.innerHTML = '×';\n lightbox.appendChild(closeBtn);\n\n const prevBtn = document.createElement('a');\n prevBtn.classList.add('prev');\n prevBtn.innerHTML = '❮';\n lightbox.appendChild(prevBtn);\n\n const nextBtn = document.createElement('a');\n nextBtn.classList.add('next');\n nextBtn.innerHTML = '❯';\n lightbox.appendChild(nextBtn);\n\n // Ajouter un écouteur d'événement sur chaque image pour ouvrir le lightbox\n images.forEach((image, index) => {\n image.addEventListener('click', () => {\n lightbox.style.display = 'flex';\n img.src = image.src;\n currentIndex = index;\n });\n });\n\n // Fermer le lightbox\n closeBtn.addEventListener('click', () => {\n lightbox.style.display = 'none';\n });\n\n // Naviguer vers l'image précédente\n prevBtn.addEventListener('click', () => {\n currentIndex = (currentIndex > 0) ? currentIndex - 1 : images.length - 1;\n img.src = images[currentIndex].src;\n });\n\n // Naviguer vers l'image suivante\n nextBtn.addEventListener('click', () => {\n currentIndex = (currentIndex < images.length - 1) ? currentIndex + 1 : 0;\n img.src = images[currentIndex].src;\n });\n\n // Fermer le lightbox quand on clique en dehors de l'image\n lightbox.addEventListener('click', (e) => {\n if (e.target === lightbox) {\n lightbox.style.display = 'none';\n }\n });\n\n\n \n\n})(jQuery, window);\n\n\n\n\n//# sourceURL=webpack://quartiers_de_demain/./src/assets/js/quartiers_de_demain.js?"); /***/ }) diff --git a/web/themes/custom/quartiers_de_demain/src/assets/js/quartiers_de_demain.js b/web/themes/custom/quartiers_de_demain/src/assets/js/quartiers_de_demain.js index 1802eaa..e3e6650 100644 --- a/web/themes/custom/quartiers_de_demain/src/assets/js/quartiers_de_demain.js +++ b/web/themes/custom/quartiers_de_demain/src/assets/js/quartiers_de_demain.js @@ -202,7 +202,7 @@ }); - //////// end header //////////// +//////// end header //////////// @@ -444,88 +444,69 @@ }); -///////////// carte sticky node site /////////////////// - // window.addEventListener('scroll', function() { - // const mapContainer = document.getElementById('sites-map-container'); - // const header = document.querySelector('header'); // Sélectionnez votre header - - // const headerHeight = header.offsetHeight; // Calculer la hauteur du header - // const scrollPosition = window.scrollY; // Obtenir la position actuelle du scroll - // console.log('Hauteur dynamique du header:', headerHeight); - - // if (scrollPosition >= headerHeight - 350 ) { - // mapContainer.classList.add('fixed'); - // mapContainer.style.position = 'fixed'; - // mapContainer.style.top = headerHeight + 350 ; // Fixé en haut une fois passé le header - // } else { - // mapContainer.classList.remove('fixed'); - // mapContainer.style.position = 'static'; // Retour à la position initiale - // } - // }); //////////////// lightbox galerie image page site//////////////////////// -// Sélectionne uniquement les images à l'intérieur de '.paragraph--type--site-diapo' -// Sélectionne uniquement les images à l'intérieur de '.paragraph--type--site-diapo' -let images = document.querySelectorAll('.paragraph--type--site-diapo .lightbox-trigger'); -let currentIndex; + // Sélectionne uniquement les images à l'intérieur de '.paragraph--type--site-diapo' + let images = document.querySelectorAll('.paragraph--type--site-diapo .lightbox-trigger'); + let currentIndex; -// Créer le lightbox et ses éléments -const lightbox = document.createElement('div'); -lightbox.id = 'lightbox'; -lightbox.classList.add('lightbox'); -document.body.appendChild(lightbox); + // Créer le lightbox et ses éléments + const lightbox = document.createElement('div'); + lightbox.id = 'lightbox'; + lightbox.classList.add('lightbox'); + document.body.appendChild(lightbox); -const img = document.createElement('img'); -lightbox.appendChild(img); + const img = document.createElement('img'); + lightbox.appendChild(img); -const closeBtn = document.createElement('span'); -closeBtn.classList.add('close'); -closeBtn.innerHTML = '×'; -lightbox.appendChild(closeBtn); + const closeBtn = document.createElement('span'); + closeBtn.classList.add('close'); + closeBtn.innerHTML = '×'; + lightbox.appendChild(closeBtn); -const prevBtn = document.createElement('a'); -prevBtn.classList.add('prev'); -prevBtn.innerHTML = '❮'; -lightbox.appendChild(prevBtn); + const prevBtn = document.createElement('a'); + prevBtn.classList.add('prev'); + prevBtn.innerHTML = '❮'; + lightbox.appendChild(prevBtn); -const nextBtn = document.createElement('a'); -nextBtn.classList.add('next'); -nextBtn.innerHTML = '❯'; -lightbox.appendChild(nextBtn); + const nextBtn = document.createElement('a'); + nextBtn.classList.add('next'); + nextBtn.innerHTML = '❯'; + lightbox.appendChild(nextBtn); -// Ajouter un écouteur d'événement sur chaque image pour ouvrir le lightbox -images.forEach((image, index) => { - image.addEventListener('click', () => { - lightbox.style.display = 'flex'; - img.src = image.src; - currentIndex = index; + // Ajouter un écouteur d'événement sur chaque image pour ouvrir le lightbox + images.forEach((image, index) => { + image.addEventListener('click', () => { + lightbox.style.display = 'flex'; + img.src = image.src; + currentIndex = index; + }); }); -}); -// Fermer le lightbox -closeBtn.addEventListener('click', () => { - lightbox.style.display = 'none'; -}); - -// Naviguer vers l'image précédente -prevBtn.addEventListener('click', () => { - currentIndex = (currentIndex > 0) ? currentIndex - 1 : images.length - 1; - img.src = images[currentIndex].src; -}); - -// Naviguer vers l'image suivante -nextBtn.addEventListener('click', () => { - currentIndex = (currentIndex < images.length - 1) ? currentIndex + 1 : 0; - img.src = images[currentIndex].src; -}); - -// Fermer le lightbox quand on clique en dehors de l'image -lightbox.addEventListener('click', (e) => { - if (e.target === lightbox) { + // Fermer le lightbox + closeBtn.addEventListener('click', () => { lightbox.style.display = 'none'; - } -}); + }); + + // Naviguer vers l'image précédente + prevBtn.addEventListener('click', () => { + currentIndex = (currentIndex > 0) ? currentIndex - 1 : images.length - 1; + img.src = images[currentIndex].src; + }); + + // Naviguer vers l'image suivante + nextBtn.addEventListener('click', () => { + currentIndex = (currentIndex < images.length - 1) ? currentIndex + 1 : 0; + img.src = images[currentIndex].src; + }); + + // Fermer le lightbox quand on clique en dehors de l'image + lightbox.addEventListener('click', (e) => { + if (e.target === lightbox) { + lightbox.style.display = 'none'; + } + });