<section id="gallery" class="w-full justify-center"> <div class="carousel-wrapper mx-auto max-w-[900px] md:max-w-[1500px] flex relative justify-center items-center" > <button id="prev" class="absolute left-0 top-1/2 transform -translate-y-1/2 w-1/2 h-full text-white flex items-center justify-start pl-8" > <svg xmlns="http://www.w3.org/2000/svg" class="fill-current w-6 sm:w-4" viewBox="0 0 320 512" > <path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z" /> </svg> </button> <div class="carousel" data-current="0"> {{ $gallery := .Site.Params.gallery.home }} {{ range $index, $image := $gallery }} <img src="{{ $image.url | safeURL }}" alt="{{ $image.alt }}" class="carousel-image h-[20rem] sm:h-[30rem] xl:h-[40rem] w-auto rounded-md" data-index="{{ $index }}" /> {{ end }} </div> <button id="next" class="absolute right-0 top-1/2 transform -translate-y-1/2 w-1/2 h-full text-white flex items-center justify-end pr-8" > <svg xmlns="http://www.w3.org/2000/svg" class="fill-current w-6 sm:w-4" viewBox="0 0 320 512" > <path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z" /> </svg> </button> </div> <div class="thumbnails flex justify-left 2xl:justify-center mt-2 overflow-x-scroll pb-2" > {{ $gallery := .Site.Params.gallery.home }} {{ range $index, $image := $gallery }} <img loading="lazy" src="{{ $image.url | safeURL }}" alt="{{ $image.alt }}" class="thumbnail transition-opacity duration-400 cursor-pointer m-1 h-[5rem] sm:h-[10rem] w-auto rounded-md opacity-20" data-index="{{ $index }}" /> {{ end }} </div> </section> <script> document.addEventListener("DOMContentLoaded", () => { const carousel = document.querySelector(".carousel"); const images = Array.from(document.querySelectorAll(".carousel-image")); const thumbnails = Array.from(document.querySelectorAll(".thumbnail")); const thumbnailContainer = document.querySelector(".thumbnails"); let currentIndex = 0; const showImage = (index) => { carousel.dataset.current = index; images.forEach((img, i) => { img.style.display = i === index ? "block" : "none"; }); const thumbnail = thumbnails[index]; smoothScrollTo(thumbnailContainer, thumbnail); }; const handleButtonClick = (direction) => () => { currentIndex = (currentIndex + direction + images.length) % images.length; showImage(currentIndex); addBorderToThumbnail(currentIndex); }; const addBorderToThumbnail = (index) => { thumbnails.forEach((thumbnail, i) => { if (i === index) { thumbnail.classList.add("!opacity-90"); } else { thumbnail.classList.remove("!opacity-90"); } }); }; const smoothScrollTo = (element, targetElement) => { let startTime = null; const duration = 500; const scrollStep = (timestamp) => { if (!startTime) startTime = timestamp; const progress = Math.min((timestamp - startTime) / duration, 1); element.scrollLeft = element.scrollLeft + (targetElement.offsetLeft - element.offsetWidth / 2 + targetElement.offsetWidth / 2 - element.scrollLeft) * 0.1 * progress; if (progress < 1) { requestAnimationFrame(scrollStep); } }; requestAnimationFrame(scrollStep); }; document .getElementById("prev") .addEventListener("click", handleButtonClick(-1)); document .getElementById("next") .addEventListener("click", handleButtonClick(1)); thumbnails.forEach((thumbnail, index) => { thumbnail.addEventListener("click", () => { currentIndex = index; showImage(index); addBorderToThumbnail(currentIndex); }); }); showImage(0); addBorderToThumbnail(0); }); </script>