From ec5fc137d4095b772d55ea1624eb029f4c760eb1 Mon Sep 17 00:00:00 2001 From: ouidade Date: Thu, 17 Oct 2024 13:06:30 +0200 Subject: [PATCH] lightbox diaporama site --- .../quartiers_de_demain/dist/assets/bundle.js | 2 +- .../dist/assets/css/bundle.css | 90 ++++++++++++++++--- .../src/assets/js/quartiers_de_demain.js | 64 +++++++++++++ .../src/assets/scss/global/_layout.scss | 2 +- .../src/assets/scss/pages/node-type-site.scss | 13 ++- .../src/assets/scss/partials/header.scss | 12 ++- .../src/assets/scss/partials/lightbox.scss | 58 ++++++++++++ .../src/assets/scss/quartiers_de_demain.scss | 1 + .../field--paragraph--site-diapo.html.twig | 6 ++ .../templates/image.html.twig | 15 ++++ 10 files changed, 239 insertions(+), 24 deletions(-) create mode 100644 web/themes/custom/quartiers_de_demain/src/assets/scss/partials/lightbox.scss create mode 100644 web/themes/custom/quartiers_de_demain/templates/image.html.twig 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 0d8ba85..4e8fce5 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\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///////////// 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?"); /***/ }) diff --git a/web/themes/custom/quartiers_de_demain/dist/assets/css/bundle.css b/web/themes/custom/quartiers_de_demain/dist/assets/css/bundle.css index 5251f67..6f41a7d 100644 --- a/web/themes/custom/quartiers_de_demain/dist/assets/css/bundle.css +++ b/web/themes/custom/quartiers_de_demain/dist/assets/css/bundle.css @@ -193,7 +193,7 @@ h2 { } .layout-container main { width: 100%; - padding-top: 320px; + padding-top: 280px; } @media (max-width: 810px) { .layout-container main { @@ -291,7 +291,7 @@ header .header_left_container #block-quartiers-de-demain-logorepu-2 { } header .header_left_container #block-quartiers-de-demain-logoepau-2 { display: none; - height: 320px; + height: 280px; } @media (max-width: 891px) { header .header_left_container #block-quartiers-de-demain-logoepau-2 { @@ -316,7 +316,7 @@ header .header_left_container #block-quartiers-de-demain-logoquartiersdedemain . header .header_left_container img { width: auto; margin: auto; - height: calc(320px - 5rem); + height: calc(280px - 1rem); padding: 2rem; transition: height 0.3s; /* Add transition for smooth resizing */ } @@ -379,6 +379,7 @@ header .header_right_container .language-switcher-language-url ul .is-active { header .header_nav_container { flex: 0 0 0%; width: 100%; + min-width: fit-content; background: rgb(7, 50, 194); text-align: center; transform: translateX(0); @@ -398,10 +399,9 @@ header .header_nav_container #block-quartiers-de-demain-entete ul { flex-direction: column; align-items: flex-start; position: relative; - top: 80px; padding-left: 1rem; padding-right: 1rem; - margin: 0; + margin-top: 2rem; } @media (max-width: 1025px) { header .header_nav_container #block-quartiers-de-demain-entete ul { @@ -409,11 +409,6 @@ header .header_nav_container #block-quartiers-de-demain-entete ul { align-items: center; } } -@media (max-width: 1090px) { - header .header_nav_container #block-quartiers-de-demain-entete ul { - top: 16px; - } -} @media (max-width: 1090px) { header .header_nav_container #block-quartiers-de-demain-entete ul li { padding-top: 0.3rem; @@ -464,7 +459,7 @@ header .header:hover + .header_nav_container { /* Taille définitive du header après l'animation */ .header--collapsed { - height: 320px; /* Ou la hauteur que vous souhaitez pour votre header */ + height: 280px; /* Ou la hauteur que vous souhaitez pour votre header */ width: 35%; transform-origin: bottom right; transition: all 1s ease-in-out; @@ -495,6 +490,7 @@ header .header:hover + .header_nav_container { .header--collapsed .header_nav_container { flex: 0 0 30%; transform-origin: bottom right; + min-width: fit-content; } @media (max-width: 810px) { .header--collapsed .header_nav_container { @@ -505,7 +501,7 @@ header .header:hover + .header_nav_container { } .header--collapsed-already { - height: 320px; /* Ou la hauteur que vous souhaitez pour votre header */ + height: 280px; /* Ou la hauteur que vous souhaitez pour votre header */ width: 35%; transform-origin: bottom right; transition: all 0s ease-in-out; @@ -530,6 +526,7 @@ header .header:hover + .header_nav_container { } .header--collapsed-already .header_nav_container { flex: 0 0 30%; + min-width: fit-content; transform-origin: bottom right; } @media (max-width: 810px) { @@ -1633,6 +1630,64 @@ header #block-quartiers-de-demain-logoquartiersdedemain .field_field_logo .qdd-h z-index: 0; } +body { + font-family: Arial, sans-serif; +} + +.diaporama { + display: flex; + gap: 10px; +} + +.diaporama img { + width: 150px; + cursor: pointer; +} + +.lightbox { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.8); + justify-content: center; + align-items: center; + z-index: 999; +} + +.lightbox img { + max-width: 90%; + max-height: 80%; +} + +.lightbox .close { + position: absolute; + top: 20px; + right: 40px; + font-size: 40px; + color: white; + cursor: pointer; +} + +.prev, .next { + position: absolute; + top: 50%; + color: white; + font-size: 30px; + cursor: pointer; + user-select: none; +} + +.prev { + left: 10px; +} + +.next { + right: 10px; +} + /*pages*/ #home .config_pages--type--diaporama-home { position: relative; @@ -2847,6 +2902,7 @@ header #block-quartiers-de-demain-logoquartiersdedemain .field_field_logo .qdd-h margin-bottom: 3rem; } .node-type-site .layout--threecol-25-50-25 .layout__region--first div { + width: fit-content; margin-bottom: 0.5rem; } .node-type-site .layout--threecol-25-50-25 .layout__region--first div #sites-map-container { @@ -2915,13 +2971,13 @@ header #block-quartiers-de-demain-logoquartiersdedemain .field_field_logo .qdd-h padding-left: 0.2rem; } .node-type-site .layout--threecol-25-50-25 .layout__region--second { - flex: 0 1 80%; + width: 60%; } .node-type-site .layout--threecol-25-50-25 .layout__region--second .block-region-second { display: flex; flex-direction: row; flex-wrap: wrap; - margin-left: 2.5rem; + margin-left: 3.5rem; } @media (max-width: 500px) { .node-type-site .layout--threecol-25-50-25 .layout__region--second .block-region-second { @@ -3000,6 +3056,12 @@ header #block-quartiers-de-demain-logoquartiersdedemain .field_field_logo .qdd-h font-size: 0.5rem; color: rgb(7, 50, 194); } +.node-type-site .layout--threecol-25-50-25 .layout__region--second .block-region-second .field_field_parties { + width: 70%; +} +.node-type-site .layout--threecol-25-50-25 .layout__region--second .block-region-second .field_field_parties div { + width: fit-content; +} .node-type-site .layout--threecol-25-50-25 .layout__region--second .block-region-second div:has(.field_field_parties) { margin-top: 2rem; } 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 0cc3037..1802eaa 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 @@ -463,6 +463,70 @@ // } // }); +//////////////// 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; + +// 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 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 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; + }); +}); + +// 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'; + } +}); + diff --git a/web/themes/custom/quartiers_de_demain/src/assets/scss/global/_layout.scss b/web/themes/custom/quartiers_de_demain/src/assets/scss/global/_layout.scss index eb8f780..190c643 100644 --- a/web/themes/custom/quartiers_de_demain/src/assets/scss/global/_layout.scss +++ b/web/themes/custom/quartiers_de_demain/src/assets/scss/global/_layout.scss @@ -1,5 +1,5 @@ -$header-height : 320px; +$header-height : 280px; $header-height-pad : 160px; $header-height-small : 70px; $header-height-ultrasmall : 50px; diff --git a/web/themes/custom/quartiers_de_demain/src/assets/scss/pages/node-type-site.scss b/web/themes/custom/quartiers_de_demain/src/assets/scss/pages/node-type-site.scss index 6030862..95b1e99 100644 --- a/web/themes/custom/quartiers_de_demain/src/assets/scss/pages/node-type-site.scss +++ b/web/themes/custom/quartiers_de_demain/src/assets/scss/pages/node-type-site.scss @@ -7,6 +7,7 @@ } } .layout--threecol-25-50-25{ + flex-wrap: nowrap; @media(max-width: 500px){ display: flex; @@ -26,7 +27,7 @@ } } div{ - // width: fit-content; + width: fit-content; margin-bottom: 0.5rem; // #sites-map-container.fixed{ // width: auto; @@ -102,12 +103,13 @@ } } .layout__region--second{ - flex: 0 1 80%; + // flex: 0 1 60%; + width: 60%; .block-region-second{ display: flex; flex-direction: row; flex-wrap: wrap; - margin-left: 2.5rem; + margin-left: 3.5rem; @media(max-width: 500px){ margin-left: 0.5rem; margin-top: 1rem; @@ -197,7 +199,10 @@ color: $blue_QDD; } } - + .field_field_parties{ + div{width: fit-content;} + width: 70%; + } div:has(.field_field_parties){ margin-top: 2rem; @media(max-width: 500px){ diff --git a/web/themes/custom/quartiers_de_demain/src/assets/scss/partials/header.scss b/web/themes/custom/quartiers_de_demain/src/assets/scss/partials/header.scss index 1dfc671..4805c28 100644 --- a/web/themes/custom/quartiers_de_demain/src/assets/scss/partials/header.scss +++ b/web/themes/custom/quartiers_de_demain/src/assets/scss/partials/header.scss @@ -60,7 +60,7 @@ header{ img{ width: auto; margin: auto; - height: calc($header-height - 5rem); + height: calc($header-height - 1rem); padding: 2rem; transition: height 0.3s; /* Add transition for smooth resizing */ @media(max-width: 891px){ @@ -114,6 +114,7 @@ header{ .header_nav_container{ flex: 0 0 0%; width: 100%; + min-width: fit-content; background: $blue_QDD; text-align: center; transform: translateX(0); @@ -135,10 +136,11 @@ header{ flex-direction: column; align-items: flex-start; position: relative; - top: calc($header-height / 4 ); + // top: calc($header-height / 4 ); padding-left: 1rem; padding-right: 1rem; - margin: 0; + margin-top: 2rem; + // @media(max-width: 1200px){ // top:0; // } @@ -148,7 +150,7 @@ header{ // margin: 1rem; } @media(max-width: 1090px){ - top: calc($header-height-pad / 10); + // top: calc($header-height-pad / 10); } li{ @media(max-width: 1090px){ @@ -234,6 +236,7 @@ header{ .header_nav_container{ flex: 0 0 30%; transform-origin: bottom right; + min-width: fit-content; @media(max-width: 810px){ flex: 1 0 100%; position: relative; @@ -263,6 +266,7 @@ header{ } .header_nav_container{ flex: 0 0 30%; + min-width: fit-content; transform-origin: bottom right; @media(max-width: 810px){ flex: 1 0 100%; diff --git a/web/themes/custom/quartiers_de_demain/src/assets/scss/partials/lightbox.scss b/web/themes/custom/quartiers_de_demain/src/assets/scss/partials/lightbox.scss new file mode 100644 index 0000000..2b005b8 --- /dev/null +++ b/web/themes/custom/quartiers_de_demain/src/assets/scss/partials/lightbox.scss @@ -0,0 +1,58 @@ +body { + font-family: Arial, sans-serif; + } + + .diaporama { + display: flex; + gap: 10px; + } + + .diaporama img { + width: 150px; + cursor: pointer; + } + + .lightbox { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.8); + justify-content: center; + align-items: center; + z-index: 999; + } + + .lightbox img { + max-width: 90%; + max-height: 80%; + } + + .lightbox .close { + position: absolute; + top: 20px; + right: 40px; + font-size: 40px; + color: white; + cursor: pointer; + } + + .prev, .next { + position: absolute; + top: 50%; + color: white; + font-size: 30px; + cursor: pointer; + user-select: none; + } + + .prev { + left: 10px; + } + + .next { + right: 10px; + } + \ No newline at end of file diff --git a/web/themes/custom/quartiers_de_demain/src/assets/scss/quartiers_de_demain.scss b/web/themes/custom/quartiers_de_demain/src/assets/scss/quartiers_de_demain.scss index d25e944..02ffbc7 100644 --- a/web/themes/custom/quartiers_de_demain/src/assets/scss/quartiers_de_demain.scss +++ b/web/themes/custom/quartiers_de_demain/src/assets/scss/quartiers_de_demain.scss @@ -33,6 +33,7 @@ @import "partials/formes-animees"; @import "partials/animation-pilliers"; @import "partials/map"; +@import "partials/lightbox"; // @import "partials/slick_custom"; diff --git a/web/themes/custom/quartiers_de_demain/templates/field--paragraph--site-diapo.html.twig b/web/themes/custom/quartiers_de_demain/templates/field--paragraph--site-diapo.html.twig index cf26367..e1eefec 100644 --- a/web/themes/custom/quartiers_de_demain/templates/field--paragraph--site-diapo.html.twig +++ b/web/themes/custom/quartiers_de_demain/templates/field--paragraph--site-diapo.html.twig @@ -74,5 +74,11 @@ {% if multiple %} {% endif %} + {% endif %} diff --git a/web/themes/custom/quartiers_de_demain/templates/image.html.twig b/web/themes/custom/quartiers_de_demain/templates/image.html.twig new file mode 100644 index 0000000..1215d75 --- /dev/null +++ b/web/themes/custom/quartiers_de_demain/templates/image.html.twig @@ -0,0 +1,15 @@ +{# +/** + * @file + * Default theme implementation of an image. + * + * Available variables: + * - attributes: HTML attributes for the img tag. + * - style_name: (optional) The name of the image style applied. + * + * @see template_preprocess_image() + * + * @ingroup themeable + */ +#} +