(function() { const DEFAULT_CONFIG = { maxVisibleColumns: 2, transitionDuration: 300, inactiveClass: "inactive", }; const MIN_ANIMATION_WIDTH = 992; function requireElement(selector, errorMessage) { const element = document.querySelector(selector); if (!element) throw new Error(errorMessage); return element; } function queryAll(selector) { return Array.from(document.querySelectorAll(selector)); } function setInteractiveInactive(element, inactive) { element.classList.toggle(DEFAULT_CONFIG.inactiveClass, inactive); element.setAttribute("aria-hidden", inactive.toString()); element.tabIndex = inactive ? -1 : 0; } class ColumnAnimation { constructor(config = {}) { this.backButton = null; this.hideButton = null; this.observer = null; this.resizeHandler = null; this.config = { ...DEFAULT_CONFIG, ...config }; this.columns = queryAll("[data-animation-element='column']"); if (this.columns.length === 0) { console.warn("[ColumnAnimation] Keine Spalten mit data-animation-element='column' gefunden."); } const backButtonElement = document.querySelector("[data-animation-element='back-button']"); if (backButtonElement) { this.backButton = backButtonElement; } const hideButtonElement = document.querySelector("[data-filter-element='hide-button']"); if (hideButtonElement) { this.hideButton = hideButtonElement; } this.updateTransform(); this.updateBackButtonVisibility(); this.startObserving(); this.resizeHandler = () => { this.update(); }; window.addEventListener("resize", this.resizeHandler); } shouldAnimate() { return window.innerWidth >= MIN_ANIMATION_WIDTH; } getVisibleColumnCount() { return this.columns.filter((col) => !col.classList.contains(this.config.inactiveClass)).length; } isLayer1Visible() { const layer1 = document.querySelector("[data-layer='1'][data-animation-element='column']"); if (!layer1) return false; return !layer1.classList.contains(this.config.inactiveClass); } updateTransform(visibleCount) { if (!this.shouldAnimate()) { for (const col of this.columns) { col.style.transition = "none"; col.style.transform = ""; requestAnimationFrame(() => { col.style.transition = ""; }); } return; } for (const col of this.columns) { col.style.transition = ""; } const count = visibleCount ?? this.getVisibleColumnCount(); const shift = Math.max(0, count - this.config.maxVisibleColumns); const translateValue = `translateX(${shift * -100}%)`; for (const col of this.columns) { col.style.transform = translateValue; } } updateBackButtonVisibility(visibleCount) { if (!this.backButton) return; let shouldShow; if (this.shouldAnimate()) { const count = visibleCount ?? this.getVisibleColumnCount(); shouldShow = count > this.config.maxVisibleColumns; } else { shouldShow = this.isLayer1Visible(); } setInteractiveInactive(this.backButton, !shouldShow); if (this.hideButton) { setInteractiveInactive(this.hideButton, shouldShow); } } update() { const visibleCount = this.getVisibleColumnCount(); requestAnimationFrame(() => { this.updateTransform(visibleCount); this.updateBackButtonVisibility(visibleCount); }); } updateWithDelay(delay = this.config.transitionDuration) { const visibleCount = this.getVisibleColumnCount(); this.updateTransform(visibleCount); this.updateBackButtonVisibility(visibleCount); setTimeout(() => { this.update(); }, delay); } reset() { for (const col of this.columns) { col.style.transform = "translateX(0%)"; } this.updateBackButtonVisibility(); } startObserving() { if (!window.MutationObserver) { console.warn("[ColumnAnimation] MutationObserver nicht verfügbar. Automatische Updates deaktiviert."); return; } this.observer = new MutationObserver((mutations) => { let shouldUpdate = false; for (const mutation of mutations) { if (mutation.type === "attributes") { const target = mutation.target; if (this.columns.includes(target) && mutation.attributeName === "class") { shouldUpdate = true; break; } } } if (shouldUpdate) { requestAnimationFrame(() => { this.update(); }); } }); for (const col of this.columns) { this.observer.observe(col, { attributes: true, attributeFilter: ["class"], }); } } destroy() { if (this.observer) { this.observer.disconnect(); this.observer = null; } if (this.resizeHandler) { window.removeEventListener("resize", this.resizeHandler); this.resizeHandler = null; } } } let animationInstance = null; function initAnimation(config) { if (animationInstance) { animationInstance.destroy(); } animationInstance = new ColumnAnimation(config); return animationInstance; } function getAnimation() { return animationInstance; } function updateAnimation() { if (animationInstance) { animationInstance.update(); } } function updateAnimationWithDelay(delay) { if (animationInstance) { animationInstance.updateWithDelay(delay); } } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", () => { initAnimation(); }); } else { initAnimation(); } // Mache Funktionen global verfügbar für filter.js if (typeof window !== 'undefined') { window.updateAnimation = updateAnimation; window.updateAnimationWithDelay = updateAnimationWithDelay; } })();