Social_Cooking/js/index-carousel.js

144 lines
4.7 KiB
JavaScript

// =============================================
// Galerie-Karussell (Startseite)
// Diese Datei steuert die Foto-Galerie mit Pfeilen.
// =============================================
// Wichtige Elemente aus dem HTML holen.
const carouselTrack = document.querySelector('.gallery__track');
const prevArrow = document.querySelector('.gallery__arrow--prev');
const nextArrow = document.querySelector('.gallery__arrow--next');
const dotsContainer = document.querySelector('.gallery_dots');
// Nur ausführen, wenn die Galerie auf der Seite vorhanden ist.
if (carouselTrack) {
// Alle einzelnen Karten/Bilder im Track sammeln.
const items = Array.from(carouselTrack.querySelectorAll('.gallery__item'));
// Auf Mobile zeigen wir 1 Bild, auf Desktop 3 Bilder pro "Seite".
const getItemsPerPage = () => (window.matchMedia('(max-width: 900px)').matches ? 1 : 3);
let itemsPerPage = getItemsPerPage();
let pageCount = Math.ceil(items.length / itemsPerPage);
let activePage = 0;
var dots = [];
function buildDots() {
if (!dotsContainer) return;
dotsContainer.innerHTML = '';
dots = [];
for (var i = 0; i < pageCount; i++) {
var dot = document.createElement('button');
dot.type = 'button';
dot.className = 'gallery_dot' + (i === activePage ? ' gallery_dot--active' : '');
dot.setAttribute('role', 'tab');
dot.setAttribute('aria-selected', i === activePage ? 'true' : 'false');
dot.setAttribute('aria-label', 'Seite ' + (i + 1) + ' von ' + pageCount);
dot.dataset.page = i;
dot.addEventListener('click', function() {
goToPage(parseInt(this.dataset.page));
});
dotsContainer.appendChild(dot);
dots.push(dot);
}
}
function updateDots() {
dots.forEach(function(dot, i) {
dot.classList.toggle('gallery_dot--active', i === activePage);
dot.setAttribute('aria-selected', i === activePage ? 'true' : 'false');
});
}
function updateTrack() {
var gap = parseFloat(getComputedStyle(carouselTrack).gap) || 20;
var itemWidth = items[0].getBoundingClientRect().width;
var offset = activePage * (itemWidth + gap) * itemsPerPage;
carouselTrack.style.transform = 'translateX(-' + offset + 'px)';
carouselTrack.style.transition = 'transform 0.4s ease';
updateDots();
}
function goToPage(page) {
activePage = page;
updateTrack();
}
// Geht zur nächsten Seite (mit Wrap-around am Ende).
function showNext() {
activePage = (activePage + 1) % pageCount;
updateTrack();
}
// Geht zur vorherigen Seite (mit Wrap-around zum Ende).
function showPrev() {
activePage = (activePage - 1 + pageCount) % pageCount;
updateTrack();
}
buildDots();
// Klick-Steuerung der Pfeile.
if (nextArrow) nextArrow.addEventListener('click', showNext);
if (prevArrow) prevArrow.addEventListener('click', showPrev);
// Tastatur-Support für Barrierefreiheit.
document.addEventListener('keydown', function(event) {
if (event.key === 'ArrowRight') showNext();
if (event.key === 'ArrowLeft') showPrev();
});
// Reagiert auf Bildschirmgrössen-Änderungen.
window.addEventListener('resize', function() {
var newPerPage = getItemsPerPage();
if (newPerPage !== itemsPerPage) {
itemsPerPage = newPerPage;
pageCount = Math.ceil(items.length / itemsPerPage);
activePage = 0;
}
buildDots();
updateTrack();
});
// =============================================
// Lightbox: Bild vergrössern bei Klick
// =============================================
const lightbox = document.getElementById('gallery-lightbox');
const lightboxImage = lightbox ? lightbox.querySelector('.lightbox__image') : null;
function openLightbox(src, alt) {
if (!lightbox || !lightboxImage) return;
lightboxImage.src = src;
lightboxImage.alt = alt || 'Grossansicht';
lightbox.classList.add('is-open');
lightbox.setAttribute('aria-hidden', 'false');
}
function closeLightbox() {
if (!lightbox) return;
lightbox.classList.remove('is-open');
lightbox.setAttribute('aria-hidden', 'true');
lightboxImage.src = '';
}
// Klick auf Galerie-Bild öffnet die Lightbox.
items.forEach(function(item) {
var img = item.querySelector('img');
if (img) {
item.addEventListener('click', function() {
openLightbox(img.src, img.alt);
});
}
});
// Lightbox schliessen: Backdrop, Close-Button oder ESC-Taste.
if (lightbox) {
lightbox.querySelector('.lightbox__close').addEventListener('click', closeLightbox);
lightbox.querySelector('[data-close-lightbox]').addEventListener('click', closeLightbox);
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && lightbox.classList.contains('is-open')) {
closeLightbox();
}
});
}
}