/** * BreakPilot Studio - Lightbox Module * * Vollbild-Bildvorschau und Modal-Funktionen: * - Lightbox für Arbeitsblatt-Vorschauen * - Keyboard-Navigation (Escape zum Schließen) * - Click-outside zum Schließen * * Refactored: 2026-01-19 */ // DOM-Referenzen let lightboxEl = null; let lightboxImg = null; let lightboxCaption = null; let lightboxClose = null; // Callback für Close-Event let onCloseCallback = null; /** * Initialisiert die Lightbox * Sucht nach Standard-IDs oder erstellt das DOM */ export function initLightbox() { lightboxEl = document.getElementById('lightbox'); lightboxImg = document.getElementById('lightbox-img'); lightboxCaption = document.getElementById('lightbox-caption'); lightboxClose = document.getElementById('lightbox-close'); // Falls keine Lightbox im DOM, erstelle sie if (!lightboxEl) { createLightboxDOM(); } // Event-Listener if (lightboxClose) { lightboxClose.addEventListener('click', closeLightbox); } if (lightboxEl) { lightboxEl.addEventListener('click', (ev) => { // Schließen bei Klick auf Hintergrund if (ev.target === lightboxEl) { closeLightbox(); } }); } // Escape-Taste document.addEventListener('keydown', (ev) => { if (ev.key === 'Escape' && isLightboxOpen()) { closeLightbox(); } }); } /** * Erstellt das Lightbox-DOM dynamisch */ function createLightboxDOM() { lightboxEl = document.createElement('div'); lightboxEl.id = 'lightbox'; lightboxEl.className = 'lightbox hidden'; lightboxEl.innerHTML = ` `; document.body.appendChild(lightboxEl); // Referenzen aktualisieren lightboxImg = document.getElementById('lightbox-img'); lightboxCaption = document.getElementById('lightbox-caption'); lightboxClose = document.getElementById('lightbox-close'); // CSS injizieren falls nicht vorhanden if (!document.getElementById('lightbox-styles')) { const style = document.createElement('style'); style.id = 'lightbox-styles'; style.textContent = ` .lightbox { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); z-index: 10000; display: flex; align-items: center; justify-content: center; opacity: 1; transition: opacity 0.3s ease; } .lightbox.hidden { display: none; opacity: 0; } .lightbox-content { position: relative; max-width: 90%; max-height: 90%; } .lightbox-img { max-width: 100%; max-height: 85vh; object-fit: contain; border-radius: 8px; box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5); } .lightbox-close { position: absolute; top: -40px; right: 0; background: transparent; border: none; color: white; font-size: 14px; cursor: pointer; padding: 8px 16px; border-radius: 4px; transition: background 0.2s; } .lightbox-close:hover { background: rgba(255, 255, 255, 0.1); } .lightbox-caption { color: white; text-align: center; margin-top: 12px; font-size: 14px; } `; document.head.appendChild(style); } } /** * Öffnet die Lightbox mit einem Bild * @param {string} src - Bild-URL * @param {string} [caption] - Optionale Bildunterschrift */ export function openLightbox(src, caption = '') { if (!src) { console.warn('openLightbox: No image source provided'); return; } // Lazy-Init falls noch nicht initialisiert if (!lightboxEl) { initLightbox(); } if (lightboxImg) { lightboxImg.src = src; lightboxImg.alt = caption || 'Vorschau'; } if (lightboxCaption) { lightboxCaption.textContent = caption; } if (lightboxEl) { lightboxEl.classList.remove('hidden'); // Body-Scroll verhindern document.body.style.overflow = 'hidden'; } } /** * Schließt die Lightbox */ export function closeLightbox() { if (lightboxEl) { lightboxEl.classList.add('hidden'); // Body-Scroll wiederherstellen document.body.style.overflow = ''; } if (lightboxImg) { lightboxImg.src = ''; } // Callback ausführen if (onCloseCallback) { onCloseCallback(); } } /** * Prüft ob die Lightbox geöffnet ist * @returns {boolean} */ export function isLightboxOpen() { return lightboxEl && !lightboxEl.classList.contains('hidden'); } /** * Setzt einen Callback für das Close-Event * @param {function} callback */ export function onClose(callback) { onCloseCallback = callback; } /** * Wechselt das Bild in der offenen Lightbox * @param {string} src - Neue Bild-URL * @param {string} [caption] - Neue Bildunterschrift */ export function changeLightboxImage(src, caption = '') { if (lightboxImg) { lightboxImg.src = src; lightboxImg.alt = caption || 'Vorschau'; } if (lightboxCaption) { lightboxCaption.textContent = caption; } } /** * Setzt den Text des Close-Buttons * @param {string} text - Der neue Text */ export function setCloseButtonText(text) { if (lightboxClose) { lightboxClose.textContent = text; } }