zoomora 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -15
- package/dist/zoomora.es.js +94 -28
- package/dist/zoomora.es.js.map +1 -1
- package/dist/zoomora.es.min.js +4 -4
- package/dist/zoomora.es.min.js.map +1 -1
- package/dist/zoomora.umd.js +94 -28
- package/dist/zoomora.umd.js.map +1 -1
- package/dist/zoomora.umd.min.js +4 -4
- package/dist/zoomora.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/zoomora.js +160 -47
package/dist/zoomora.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zoomora.umd.js","sources":["../src/zoomora.js"],"sourcesContent":["/*!\n * Zoomora Lightbox Plugin v1.1.0\n * A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features\n *\n * Copyright (c) 2025 Faruk Ahmed (FrontTheme)\n * Licensed under MIT License\n */\n\n// Import styles\nimport './styles/zoomora.scss';\n\n(function (global, factory) {\n 'use strict';\n\n if (typeof module === 'object' && typeof module.exports === 'object') {\n // CommonJS/Node.js\n module.exports = factory();\n } else if (typeof define === 'function' && define.amd) {\n // AMD\n define(factory);\n } else {\n // Browser globals\n global.Zoomora = factory();\n }\n}(typeof window !== 'undefined' ? window : this, function () {\n 'use strict';\n\n /**\n * Zoomora Lightbox Plugin\n * @class\n */\n class Zoomora {\n /**\n * Default configuration options\n * @type {Object}\n */\n static get defaults() {\n return {\n selector: '[data-zoomora]',\n showCounter: true,\n showThumbnails: true,\n showFullscreen: true,\n showZoom: true,\n transition: 'fade', // 'fade' or 'slide'\n useHref: false, // Use href instead of data-src\n maxZoomScale: 3, // Maximum zoom scale\n zoomStep: 0.1, // Zoom step for scroll wheel\n animationDuration: 300, // Animation duration in ms\n onOpen: null, // Callback when lightbox opens\n onClose: null, // Callback when lightbox closes\n onNext: null, // Callback when navigating to next item\n onPrev: null, // Callback when navigating to previous item\n\n // Auto-hide controls\n showAutoHideToggle: true, // Show auto-hide toggle button\n autoHideDelay: 3000, // Delay in ms before hiding controls\n autoHideEnabled: false, // Default state of auto-hide\n };\n }\n\n /**\n * Constructor\n * @param {Object} options - Configuration options\n */\n constructor(options = {}) {\n this.options = {...Zoomora.defaults, ...options};\n this.currentIndex = 0;\n this.items = [];\n this.isZoomed = false;\n this.isFullscreen = false;\n this.isDragging = false;\n this.thumbnailsVisible = true;\n this.startX = 0;\n this.startY = 0;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n this.isInitialized = false;\n this.eventListeners = new Map();\n\n // Auto-hide controls\n this.autoHideEnabled = false;\n this.autoHideTimeout = null;\n this.autoHideDelay = 3000;\n this.isControlsVisible = true;\n this.idleTimer = null;\n\n this.lastDragTime = 0;\n\n // Bound methods for event listeners\n this.boundMethods = {\n handleDocumentClick: this.handleDocumentClick.bind(this),\n handleKeydown: this.handleKeydown.bind(this),\n handleFullscreenChange: this.handleFullscreenChange.bind(this),\n handleZoomoraClick: this.handleZoomoraClick.bind(this),\n handleContentClick: this.handleContentClick.bind(this),\n handleMouseDown: this.handleMouseDown.bind(this),\n handleMouseMove: this.handleMouseMove.bind(this),\n handleMouseUp: this.handleMouseUp.bind(this),\n handleTouchStart: this.handleTouchStart.bind(this),\n handleTouchMove: this.handleTouchMove.bind(this),\n handleTouchEnd: this.handleTouchEnd.bind(this),\n };\n\n this.init();\n }\n\n /**\n * Initialize the plugin\n */\n init() {\n if (this.isInitialized) {\n console.warn('Zoomora: Plugin already initialized');\n return;\n }\n\n try {\n this.createLightbox();\n this.bindEvents();\n\n this.isInitialized = true;\n } catch (error) {\n console.error('Zoomora: Initialization failed', error);\n }\n }\n\n /**\n * Static method to bind to anchor tags with href\n * @param {string} selector - CSS selector\n * @param {Object} options - Configuration options\n * @returns {Zoomora} - New Zoomora instance\n */\n static bind(selector, options = {}) {\n const enhancedOptions = {\n ...options,\n selector: selector,\n useHref: true\n };\n return new Zoomora(enhancedOptions);\n }\n\n /**\n * Create lightbox HTML structure\n */\n createLightbox() {\n // Check if lightbox already exists\n if (document.getElementById('zoomoraLightbox')) {\n console.warn('Zoomora: Lightbox already exists in DOM');\n return;\n }\n\n // Build auto-hide button conditionally\n const autoHideButtonHTML = this.options.showAutoHideToggle ? `\n <button class=\"zoomora-btn\" id=\"zoomoraAutoHideBtn\" title=\"Toggle Auto-Hide Controls\">\n <i class=\"zoomorai-controls-off\"></i>\n </button>\n ` : '';\n\n const zoomoraHTML = `\n <div class=\"zoomora\" id=\"zoomoraLightbox\">\n <div class=\"zoomora-container\">\n <div class=\"zoomora-header\" id=\"zoomoraHeader\">\n <div class=\"zoomora-counter\" id=\"zoomoraCounter\">1 / 1</div>\n <div class=\"zoomora-controls\">\n <button class=\"zoomora-btn\" id=\"zoomoraThumbnailBtn\" title=\"Toggle Thumbnails\">\n <i class=\"zoomorai-thumbnails\"></i>\n </button>\n ${autoHideButtonHTML}\n <button class=\"zoomora-btn\" id=\"zoomoraZoomBtn\" title=\"Zoom\">\n <i class=\"zoomorai-zoom\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraFullscreenBtn\" title=\"Fullscreen\">\n <i class=\"zoomorai-expand\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCollapseBtn\" title=\"Exit Fullscreen\" style=\"display: none;\">\n <i class=\"zoomorai-collapse\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCloseBtn\" title=\"Close\">\n <i class=\"zoomorai-close\"></i>\n </button>\n </div>\n </div>\n \n <div class=\"zoomora-content\" id=\"zoomoraContent\">\n <div class=\"zoomora-loading\" id=\"zoomoraLoading\"></div>\n <div class=\"zoomora-slides-container\" id=\"zoomoraSlidesContainer\"></div>\n </div>\n \n <button class=\"zoomora-nav prev\" id=\"zoomoraPrevBtn\">\n <i class=\"zoomorai-arrow-left\"></i>\n </button>\n <button class=\"zoomora-nav next\" id=\"zoomoraNextBtn\">\n <i class=\"zoomorai-arrow-right\"></i>\n </button>\n \n <div class=\"zoomora-caption\" id=\"zoomoraCaption\"></div>\n <div class=\"zoomora-thumbnails\" id=\"zoomoraThumbs\"></div>\n </div>\n </div>\n `;\n\n document.body.insertAdjacentHTML('beforeend', zoomoraHTML);\n\n // Cache DOM elements\n this.zoomora = document.getElementById('zoomoraLightbox');\n this.header = document.getElementById('zoomoraHeader');\n this.content = document.getElementById('zoomoraContent');\n this.slidesContainer = document.getElementById('zoomoraSlidesContainer');\n this.counter = document.getElementById('zoomoraCounter');\n this.thumbs = document.getElementById('zoomoraThumbs');\n this.loading = document.getElementById('zoomoraLoading');\n this.caption = document.getElementById('zoomoraCaption');\n this.prevBtn = document.getElementById('zoomoraPrevBtn');\n this.nextBtn = document.getElementById('zoomoraNextBtn');\n\n // Verify all elements were created\n if (!this.zoomora || !this.content || !this.counter || !this.thumbs || !this.loading || !this.caption) {\n throw new Error('Failed to create required DOM elements');\n }\n }\n\n /**\n * Bind event listeners\n */\n bindEvents() {\n // Document click handler for opening lightbox\n this.addEventListener(document, 'click', this.boundMethods.handleDocumentClick);\n\n // Control button handlers\n this.addEventListener(document.getElementById('zoomoraCloseBtn'), 'click', () => this.close());\n this.addEventListener(document.getElementById('zoomoraPrevBtn'), 'click', () => this.prev());\n this.addEventListener(document.getElementById('zoomoraNextBtn'), 'click', () => this.next());\n this.addEventListener(document.getElementById('zoomoraZoomBtn'), 'click', () => this.toggleZoom());\n this.addEventListener(document.getElementById('zoomoraFullscreenBtn'), 'click', () => this.toggleFullscreen());\n this.addEventListener(document.getElementById('zoomoraCollapseBtn'), 'click', () => this.exitFullscreen());\n this.addEventListener(document.getElementById('zoomoraThumbnailBtn'), 'click', () => this.toggleThumbnails());\n\n // Fullscreen change events\n this.addEventListener(document, 'fullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'webkitfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'mozfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'MSFullscreenChange', this.boundMethods.handleFullscreenChange);\n\n // Keyboard navigation\n this.addEventListener(document, 'keydown', this.boundMethods.handleKeydown);\n\n // Lightbox click to close\n this.addEventListener(this.zoomora, 'click', this.boundMethods.handleZoomoraClick);\n\n // Content click for zoom toggle\n this.addEventListener(this.content, 'click', this.boundMethods.handleContentClick);\n\n // Mouse drag events\n this.addEventListener(this.content, 'mousedown', this.boundMethods.handleMouseDown);\n this.addEventListener(this.content, 'mousemove', this.boundMethods.handleMouseMove);\n this.addEventListener(this.content, 'mouseup', this.boundMethods.handleMouseUp);\n this.addEventListener(this.content, 'mouseleave', this.boundMethods.handleMouseUp);\n\n // Touch events\n this.addEventListener(this.content, 'touchstart', this.boundMethods.handleTouchStart, {passive: false});\n this.addEventListener(this.content, 'touchmove', this.boundMethods.handleTouchMove, {passive: false});\n this.addEventListener(this.content, 'touchend', this.boundMethods.handleTouchEnd);\n\n // Add auto-hide toggle button handler (only if enabled)\n if (this.options.showAutoHideToggle) {\n this.addEventListener(document.getElementById('zoomoraAutoHideBtn'), 'click', () => this.toggleAutoHide());\n\n // Add mouse/touch activity listeners for auto-hide\n this.addEventListener(this.zoomora, 'mousemove', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'touchstart', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'keydown', () => this.handleUserActivity());\n }\n }\n\n /**\n * Add event listener with cleanup tracking\n * @param {Element} element - DOM element\n * @param {string} event - Event type\n * @param {Function} handler - Event handler\n * @param {Object} options - Event options\n */\n addEventListener(element, event, handler, options = {}) {\n if (!element) return;\n\n element.addEventListener(event, handler, options);\n\n // Track for cleanup\n const key = `${element.constructor.name}_${event}`;\n if (!this.eventListeners.has(key)) {\n this.eventListeners.set(key, []);\n }\n this.eventListeners.get(key).push({element, event, handler, options});\n }\n\n /**\n * Handle document click events\n * @param {Event} e - Click event\n */\n handleDocumentClick(e) {\n const target = e.target.closest(this.options.selector);\n if (target) {\n e.preventDefault();\n this.open(target);\n }\n }\n\n /**\n * Handle keyboard events\n * @param {KeyboardEvent} e - Keyboard event\n */\n handleKeydown(e) {\n if (!this.zoomora.classList.contains('active')) return;\n\n switch (e.key) {\n case 'Escape':\n if (this.isFullscreen) {\n this.exitFullscreen();\n } else {\n this.close();\n }\n break;\n case 'ArrowLeft':\n this.prev();\n break;\n case 'ArrowRight':\n this.next();\n break;\n case 'z':\n case 'Z':\n this.toggleZoom();\n break;\n case 'f':\n case 'F':\n this.toggleFullscreen();\n break;\n case 't':\n case 'T':\n this.toggleThumbnails();\n break;\n }\n }\n\n /**\n * Handle fullscreen change events\n */\n handleFullscreenChange() {\n const isInFullscreen = document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement;\n\n if (!isInFullscreen && this.isFullscreen) {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n }\n\n /**\n * Handle zoomora container clicks\n * @param {Event} e - Click event\n */\n handleZoomoraClick(e) {\n if (e.target === this.zoomora) {\n this.close();\n }\n }\n\n /**\n * Handle content clicks\n * @param {Event} e - Click event\n */\n handleContentClick(e) {\n // Ignore click if we just finished dragging (within 200ms)\n if (Date.now() - this.lastDragTime < 200) {\n return;\n }\n\n const media = e.target.closest('.zoomora-media');\n if (media && !media.classList.contains('no-zoom')) {\n this.toggleZoom();\n }\n }\n\n /**\n * Handle mouse down events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseDown(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle mouse move events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle mouse up events\n */\n handleMouseUp() {\n this.endDrag();\n }\n\n /**\n * Handle touch start events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchStart(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle touch move events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle touch end events\n */\n handleTouchEnd() {\n this.endDrag();\n }\n\n /**\n * Get image source from element\n * @param {Element} item - DOM element\n * @returns {string} - Image source URL\n */\n getImageSource(item) {\n const src = item.dataset.src || item.src || item.getAttribute('src');\n const type = item.dataset.type || 'image';\n\n // Handle YouTube URLs for video types\n if (type === 'video' && src) {\n return this.convertToEmbedUrl(src);\n }\n\n return src;\n }\n\n /**\n * Convert YouTube URLs to embed format\n * @param url\n * @returns {*|string}\n */\n convertToEmbedUrl(url) {\n // If already an embed URL, return as is\n if (url.includes('youtube.com/embed/')) {\n return url;\n }\n\n // Handle different YouTube URL formats\n let videoId = null;\n let startTime = null;\n\n // Extract video ID and start time from different YouTube URL formats\n if (url.includes('youtube.com/watch')) {\n const urlParams = new URLSearchParams(url.split('?')[1]);\n videoId = urlParams.get('v');\n const t = urlParams.get('t');\n if (t) {\n // Convert time format (e.g., \"111s\" to seconds)\n startTime = t.replace('s', '');\n }\n } else if (url.includes('youtu.be/')) {\n const parts = url.split('/');\n const videoAndParams = parts[parts.length - 1];\n if (videoAndParams.includes('?')) {\n videoId = videoAndParams.split('?')[0];\n const urlParams = new URLSearchParams(videoAndParams.split('?')[1]);\n const t = urlParams.get('t');\n if (t) startTime = t.replace('s', '');\n } else {\n videoId = videoAndParams;\n }\n }\n\n if (videoId) {\n let embedUrl = `https://www.youtube.com/embed/${videoId}`;\n const params = new URLSearchParams();\n\n if (startTime) {\n params.append('start', startTime);\n }\n\n // Add other useful parameters\n params.append('rel', '0'); // Don't show related videos\n params.append('modestbranding', '1'); // Modest branding\n\n // Option: Add autoplay for YouTube videos (uncomment if desired)\n // params.append('autoplay', '1');\n\n if (params.toString()) {\n embedUrl += '?' + params.toString();\n }\n\n return embedUrl;\n }\n\n // If not a YouTube URL or couldn't parse, return original\n return url;\n }\n\n /**\n * Get thumbnail source from element\n * @param {Element} item - DOM element\n * @returns {string} - Thumbnail source URL\n */\n getThumbnailSource(item) {\n const type = item.dataset.type || 'image';\n\n // For video items, always use the img.src as thumbnail (poster image)\n if (type === 'video') {\n return item.src || item.getAttribute('src');\n }\n\n // For regular images, use data-src or fallback to src\n return item.dataset.src || item.src || item.getAttribute('src');\n }\n\n /**\n * Get group identifier from element\n * @param {Element} element - DOM element\n * @returns {string} - Group identifier\n */\n getGroup(element) {\n if (this.options.useHref) {\n return element.dataset.lightbox || element.dataset.gallery || 'default';\n }\n return element.dataset.zoomora || 'default';\n }\n\n /**\n * Open lightbox with specified element\n * @param {Element} element - DOM element to open\n */\n open(element) {\n if (!element) return;\n\n const group = this.getGroup(element);\n let groupSelector;\n\n if (this.options.useHref) {\n if (element.dataset.lightbox) {\n groupSelector = `[data-lightbox=\"${group}\"]`;\n } else if (element.dataset.gallery) {\n groupSelector = `[data-gallery=\"${group}\"]`;\n } else {\n groupSelector = this.options.selector;\n }\n } else {\n groupSelector = `[data-zoomora=\"${group}\"]`;\n }\n\n this.items = Array.from(document.querySelectorAll(groupSelector));\n this.currentIndex = Math.max(0, this.items.indexOf(element));\n\n // Reset states\n this.isZoomed = false;\n this.isFullscreen = false;\n this.thumbnailsVisible = true;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n this.zoomora.classList.add('active');\n document.body.style.overflow = 'hidden';\n\n this.loadContent();\n this.updateThumbnails();\n this.updateCounter();\n this.updateNavigation();\n this.updateCaption();\n this.updateButtons();\n\n // Initialize auto-hide if enabled\n if (this.autoHideEnabled) {\n this.startAutoHideTimer();\n } else {\n this.showControls();\n }\n\n // Trigger callback\n if (typeof this.options.onOpen === 'function') {\n this.options.onOpen(element, this.currentIndex);\n }\n }\n\n /**\n * Close lightbox\n */\n close() {\n if (this.isFullscreen) {\n this.exitFullscreen();\n }\n\n this.zoomora.classList.remove('active');\n document.body.style.overflow = '';\n this.isZoomed = false;\n this.isFullscreen = false;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n const media = this.content.querySelector('.zoomora-media');\n if (media) {\n media.classList.remove('zoomed');\n media.style.transform = '';\n media.style.cursor = '';\n }\n\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n this.showControls();\n\n // Trigger callback\n if (typeof this.options.onClose === 'function') {\n this.options.onClose(this.currentIndex);\n }\n }\n\n /**\n * Navigate to previous item\n */\n prev() {\n if (this.currentIndex > 0) {\n this.currentIndex--;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onPrev === 'function') {\n this.options.onPrev(this.currentIndex);\n }\n }\n }\n\n /**\n * Navigate to next item\n */\n next() {\n if (this.currentIndex < this.items.length - 1) {\n this.currentIndex++;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onNext === 'function') {\n this.options.onNext(this.currentIndex);\n }\n }\n }\n\n /**\n * Load content for current item\n */\n loadContent() {\n if (!this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const src = this.getImageSource(item);\n const type = item.dataset.type || 'image';\n\n if (!src) {\n console.error('Zoomora: No source found for item');\n return;\n }\n\n // Reset zoom state\n this.isZoomed = false;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n // Show loading spinner\n this.loading.style.display = 'block';\n\n if (this.slidesContainer) {\n this.slidesContainer.innerHTML = '';\n }\n\n setTimeout(() => {\n this.renderContent(src, type, item);\n }, 100);\n }\n\n /**\n * Render content based on type\n * @param {string} src - Source URL\n * @param {string} type - Content type\n * @param {Element} item - Original item element\n */\n renderContent(src, type, item) {\n const slideContainer = document.createElement('div');\n slideContainer.className = 'zoomora-slide-container';\n\n // Create slide wrapper\n const slide = document.createElement('div');\n slide.className = `zoomora-slide ${this.options.transition === 'slide' ? 'slide-effect' : 'fade-effect'}`;\n slide.style.opacity = '0';\n slide.style.transform = this.options.transition === 'slide' ? 'translateX(100%)' : 'scale(0.8)';\n\n let mediaElement;\n\n try {\n switch (type) {\n case 'video':\n if (src.endsWith('.mp4') || src.endsWith('.webm') || src.endsWith('.ogg')) {\n const videoContainer = document.createElement('div');\n videoContainer.className = 'zoomora-video-container';\n\n mediaElement = document.createElement('video');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('preload', 'metadata');\n\n const posterSrc = item.src || item.getAttribute('src');\n if (posterSrc) {\n mediaElement.setAttribute('poster', posterSrc);\n }\n\n const playButton = document.createElement('div');\n playButton.className = 'zoomora-play-button';\n playButton.innerHTML = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>`;\n\n playButton.addEventListener('click', () => {\n mediaElement.play();\n playButton.style.display = 'none';\n mediaElement.setAttribute('controls', '');\n });\n\n mediaElement.addEventListener('ended', () => {\n playButton.style.display = 'flex';\n });\n\n videoContainer.appendChild(mediaElement);\n videoContainer.appendChild(playButton);\n slideContainer.appendChild(videoContainer);\n } else {\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('allowfullscreen', '');\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n }\n break;\n\n case 'iframe':\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-iframe';\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n break;\n\n default:\n mediaElement = document.createElement('img');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-media';\n mediaElement.alt = item.alt || item.title || '';\n\n mediaElement.onload = () => {\n this.loading.style.display = 'none';\n this.checkZoomability(mediaElement);\n this.animateSlideIn(slide);\n };\n\n mediaElement.onerror = () => {\n this.loading.style.display = 'none';\n console.error('Zoomora: Failed to load image:', src);\n this.animateSlideIn(slide);\n };\n\n slideContainer.appendChild(mediaElement);\n }\n\n slide.appendChild(slideContainer);\n\n // Clear existing slides and add new one\n this.slidesContainer.innerHTML = '';\n this.slidesContainer.appendChild(slide);\n\n if (type !== 'image') {\n this.loading.style.display = 'none';\n this.animateSlideIn(slide);\n }\n\n } catch (error) {\n console.error('Zoomora: Error rendering content:', error);\n this.loading.style.display = 'none';\n }\n }\n\n // Animation helper\n animateSlideIn(slide) {\n // Force reflow\n slide.offsetHeight;\n\n // Add active class and animate\n slide.classList.add('active');\n\n if (this.options.transition === 'slide') {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'translateX(0)';\n slide.style.opacity = '1';\n } else {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'scale(1)';\n slide.style.opacity = '1';\n }\n }\n\n // Toggle auto-hide controls\n toggleAutoHide() {\n this.autoHideEnabled = !this.autoHideEnabled;\n const autoHideBtn = document.getElementById('zoomoraAutoHideBtn');\n\n if (this.autoHideEnabled) {\n autoHideBtn.classList.add('active');\n autoHideBtn.title = 'Disable Auto-Hide Controls';\n this.startAutoHideTimer();\n } else {\n autoHideBtn.classList.remove('active');\n autoHideBtn.title = 'Enable Auto-Hide Controls';\n this.stopAutoHideTimer();\n this.showControls();\n }\n }\n\n // Handle user activity\n handleUserActivity() {\n if (!this.autoHideEnabled) return;\n\n this.showControls();\n this.startAutoHideTimer();\n }\n\n // Start auto-hide timer\n startAutoHideTimer() {\n this.stopAutoHideTimer();\n\n this.autoHideTimeout = setTimeout(() => {\n this.hideControls();\n }, this.options.autoHideDelay);\n }\n\n // Stop auto-hide timer\n stopAutoHideTimer() {\n if (this.autoHideTimeout) {\n clearTimeout(this.autoHideTimeout);\n this.autoHideTimeout = null;\n }\n }\n\n // Show controls\n showControls() {\n if (this.isControlsVisible) return;\n\n this.isControlsVisible = true;\n this.zoomora.classList.remove('controls-hidden');\n\n // Animate controls back in\n if (this.header) {\n this.header.style.transform = 'translateY(0)';\n this.header.style.opacity = '1';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(0)';\n this.thumbs.style.opacity = '1';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(0)';\n this.prevBtn.style.opacity = '1';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(0)';\n this.nextBtn.style.opacity = '1';\n }\n }\n\n // Hide controls\n hideControls() {\n if (!this.isControlsVisible) return;\n\n this.isControlsVisible = false;\n this.zoomora.classList.add('controls-hidden');\n\n // Animate controls out\n if (this.header) {\n this.header.style.transform = 'translateY(-100%)';\n this.header.style.opacity = '0';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(100%)';\n this.thumbs.style.opacity = '0';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(-100%)';\n this.prevBtn.style.opacity = '0';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(100%)';\n this.nextBtn.style.opacity = '0';\n }\n }\n\n /**\n * Check if image can be zoomed\n * @param {HTMLImageElement} img - Image element\n */\n checkZoomability(img) {\n if (!img || !img.naturalWidth || !img.naturalHeight) return;\n\n const imgRect = img.getBoundingClientRect();\n const renderedWidth = imgRect.width;\n const renderedHeight = imgRect.height;\n const naturalWidth = img.naturalWidth;\n const naturalHeight = img.naturalHeight;\n\n const isScaledDown = naturalWidth > renderedWidth || naturalHeight > renderedHeight;\n const zoomRatioX = naturalWidth / renderedWidth;\n const zoomRatioY = naturalHeight / renderedHeight;\n const maxZoomRatio = Math.max(zoomRatioX, zoomRatioY);\n\n // Store zoom info\n img.dataset.zoomRatio = maxZoomRatio;\n img.dataset.naturalWidth = naturalWidth;\n img.dataset.naturalHeight = naturalHeight;\n img.dataset.renderedWidth = renderedWidth;\n img.dataset.renderedHeight = renderedHeight;\n\n // Enable zoom if significantly scaled down\n if (isScaledDown && maxZoomRatio > 1.1) {\n img.classList.remove('no-zoom');\n } else {\n img.classList.add('no-zoom');\n }\n }\n\n /**\n * Calculate zoom levels for an image\n * @param {HTMLImageElement} img - Image element\n * @returns {Object} Zoom configuration\n */\n /**\n * Calculate zoom levels for an image\n * @param {HTMLImageElement} img - Image element\n * @returns {Object} Zoom configuration\n */\n calculateZoomLevels(img) {\n if (!img || !img.naturalWidth || !img.naturalHeight) {\n return {canZoom: false, levels: [], currentLevel: 0};\n }\n\n // Get CONTAINER size (not current displayed image size)\n const container = this.content.getBoundingClientRect();\n const containerWidth = container.width;\n const containerHeight = container.height;\n\n const naturalWidth = img.naturalWidth;\n const naturalHeight = img.naturalHeight;\n\n // Calculate what the ORIGINAL fit-to-screen scale would be\n const scaleToFitWidth = containerWidth / naturalWidth;\n const scaleToFitHeight = containerHeight / naturalHeight;\n const fitScale = Math.min(scaleToFitWidth, scaleToFitHeight);\n\n // If image naturally fits or is smaller than container, can't zoom\n if (fitScale >= 0.95) {\n return {canZoom: false, levels: [], currentLevel: 0};\n }\n\n // Calculate zoom levels based on FIT scale (not current scale)\n const levels = [1]; // Start with fit-to-screen\n\n // Add progressive levels: 1.5x, 2x, 3x\n if (fitScale * 1.5 <= 1) levels.push(1.5);\n if (fitScale * 2 <= 1) levels.push(2);\n if (fitScale * 3 <= 1) levels.push(3);\n\n // Add actual size (100%) as final level\n const actualSizeScale = 1 / fitScale;\n if (actualSizeScale > levels[levels.length - 1]) {\n levels.push(actualSizeScale);\n }\n\n return {\n canZoom: levels.length > 1,\n levels: levels,\n currentLevel: 0,\n baseScale: fitScale,\n naturalWidth: naturalWidth,\n naturalHeight: naturalHeight\n };\n }\n\n /**\n * Update counter display\n */\n updateCounter() {\n if (this.options.showCounter && this.counter) {\n this.counter.textContent = `${this.currentIndex + 1} / ${this.items.length}`;\n }\n }\n\n /**\n * Update caption display\n */\n updateCaption() {\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption) {\n this.caption.textContent = caption;\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n this.caption.style.pointerEvents = 'auto';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n this.caption.style.pointerEvents = 'none';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n }\n }\n\n /**\n * Update thumbnails display\n */\n updateThumbnails() {\n if (!this.options.showThumbnails || !this.thumbs) return;\n\n if (this.items.length === 1) {\n this.caption.classList.add('single-item-thumbnail');\n this.thumbs.style.display = 'none';\n return;\n }\n\n this.caption.classList.remove('single-item-thumbnail');\n\n this.thumbs.style.display = 'flex';\n this.thumbs.innerHTML = '';\n\n this.items.forEach((item, index) => {\n const thumb = document.createElement('div');\n thumb.className = 'zoomora-thumb';\n if (index === this.currentIndex) thumb.classList.add('active');\n\n const img = document.createElement('img');\n const thumbSrc = this.getThumbnailSource(item);\n\n if (thumbSrc) {\n img.src = thumbSrc;\n img.alt = item.alt || item.title || '';\n img.onerror = () => {\n thumb.style.display = 'none';\n };\n }\n\n thumb.appendChild(img);\n\n thumb.addEventListener('click', () => {\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n });\n\n this.thumbs.appendChild(thumb);\n });\n }\n\n /**\n * Update navigation buttons\n */\n updateNavigation() {\n const prevBtn = document.getElementById('zoomoraPrevBtn');\n const nextBtn = document.getElementById('zoomoraNextBtn');\n\n if (prevBtn) {\n prevBtn.style.display = this.currentIndex > 0 ? 'flex' : 'none';\n }\n if (nextBtn) {\n nextBtn.style.display = this.currentIndex < this.items.length - 1 ? 'flex' : 'none';\n }\n }\n\n /**\n * Update control buttons\n */\n updateButtons() {\n const fullscreenBtn = document.getElementById('zoomoraFullscreenBtn');\n const collapseBtn = document.getElementById('zoomoraCollapseBtn');\n\n if (fullscreenBtn && collapseBtn) {\n if (this.isFullscreen) {\n fullscreenBtn.style.display = 'none';\n collapseBtn.style.display = 'flex';\n } else {\n fullscreenBtn.style.display = 'flex';\n collapseBtn.style.display = 'none';\n }\n }\n }\n\n /**\n * Toggle zoom state\n */\n toggleZoom() {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || media.tagName !== 'IMG') return;\n\n // Calculate zoom levels\n const zoomConfig = this.calculateZoomLevels(media);\n\n if (!zoomConfig.canZoom) {\n console.log('Image cannot be zoomed (already at full size or larger)');\n return;\n }\n\n // Get or initialize current zoom level\n if (!media.dataset.zoomLevel) {\n media.dataset.zoomLevel = '0';\n }\n\n let currentLevel = parseInt(media.dataset.zoomLevel) || 0;\n\n // Cycle to next level\n currentLevel++;\n if (currentLevel >= zoomConfig.levels.length) {\n // Reset to fit-to-screen\n currentLevel = 0;\n }\n\n const targetScale = zoomConfig.levels[currentLevel];\n media.dataset.zoomLevel = currentLevel.toString();\n\n if (currentLevel === 0) {\n // Back to fit-to-screen\n this.isZoomed = false;\n this.isDragging = false;\n media.classList.remove('dragging');\n media.style.transform = '';\n media.style.cursor = 'pointer';\n media.classList.remove('zoomed');\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n } else {\n // Zoom in - reset position to center\n this.isZoomed = true;\n this.currentScale = targetScale;\n this.currentX = 0; // Always reset to center on zoom change\n this.currentY = 0;\n\n media.style.transform = `translate(0px, 0px) scale(${targetScale})`;\n media.style.cursor = 'grab';\n media.classList.add('zoomed');\n\n console.log(`Zoomed to level ${currentLevel}/${zoomConfig.levels.length - 1} (${(targetScale * 100).toFixed(0)}%)`);\n }\n }\n\n /**\n * Update image transform based on current state\n * @param {HTMLElement} media - Media element\n */\n updateImageTransform(media) {\n if (!media) return;\n\n if (this.currentScale === 1) {\n media.style.transform = '';\n } else {\n // IMPORTANT: translate in scaled space, so divide by scale\n const translateX = this.currentX / this.currentScale;\n const translateY = this.currentY / this.currentScale;\n media.style.transform = `scale(${this.currentScale}) translate(${translateX}px, ${translateY}px)`;\n }\n }\n\n /**\n * Toggle fullscreen mode\n */\n toggleFullscreen() {\n if (!this.isFullscreen) {\n this.enterFullscreen();\n } else {\n this.exitFullscreen();\n }\n }\n\n /**\n * Enter fullscreen mode\n */\n enterFullscreen() {\n const element = this.zoomora;\n const requestFullscreen = element.requestFullscreen ||\n element.webkitRequestFullscreen ||\n element.mozRequestFullScreen ||\n element.msRequestFullscreen;\n\n if (requestFullscreen) {\n requestFullscreen.call(element).then(() => {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }).catch(err => {\n console.warn('Zoomora: Could not enter fullscreen:', err);\n this.fallbackFullscreen();\n });\n } else {\n this.fallbackFullscreen();\n }\n }\n\n /**\n * Exit fullscreen mode\n */\n exitFullscreen() {\n const isInFullscreen = document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement;\n\n if (isInFullscreen) {\n const exitFullscreen = document.exitFullscreen ||\n document.webkitExitFullscreen ||\n document.mozCancelFullScreen ||\n document.msExitFullscreen;\n\n if (exitFullscreen) {\n exitFullscreen.call(document).then(() => {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }).catch(err => {\n console.warn('Zoomora: Could not exit fullscreen:', err);\n this.fallbackExitFullscreen();\n });\n } else {\n this.fallbackExitFullscreen();\n }\n } else {\n this.fallbackExitFullscreen();\n }\n }\n\n /**\n * Fallback fullscreen using CSS\n */\n fallbackFullscreen() {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Exit CSS fullscreen\n */\n fallbackExitFullscreen() {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Toggle thumbnails visibility\n */\n toggleThumbnails() {\n if (this.items.length === 1) return;\n\n this.thumbnailsVisible = !this.thumbnailsVisible;\n if (this.thumbs) {\n this.thumbs.classList.toggle('thumbs-hidden', !this.thumbnailsVisible);\n\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption && this.thumbs.classList.contains('thumbs-hidden')) {\n this.caption.style.bottom = '20px';\n this.caption.style.transition = 'bottom 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.bottom = '120px';\n }\n }\n }\n\n /**\n * Start drag operation\n * @param {Event} e - Mouse or touch event\n */\n startDrag(e) {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || !this.isZoomed) return;\n\n this.isDragging = true;\n media.classList.add('dragging');\n media.style.cursor = 'grabbing';\n\n this.startX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n this.startY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n // Read current position from transform\n const transform = window.getComputedStyle(media).transform;\n if (transform && transform !== 'none') {\n const matrix = new DOMMatrix(transform);\n this.currentX = matrix.m41;\n this.currentY = matrix.m42;\n } else {\n this.currentX = 0;\n this.currentY = 0;\n }\n\n e.preventDefault();\n }\n\n /**\n * Handle drag movement\n * @param {Event} e - Mouse or touch event\n */\n drag(e) {\n if (!this.isDragging) return;\n e.preventDefault();\n\n const media = this.content.querySelector('.zoomora-media');\n if (!media) return;\n\n const clientX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n const clientY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n const deltaX = clientX - this.startX;\n const deltaY = clientY - this.startY;\n\n let newX = this.currentX + deltaX;\n let newY = this.currentY + deltaY;\n\n // Calculate boundaries for BOTH width AND height\n const container = this.content.getBoundingClientRect();\n const mediaRect = media.getBoundingClientRect();\n\n // How much the scaled image overflows the container\n const overflowX = Math.max(0, (mediaRect.width - container.width) / 2);\n const overflowY = Math.max(0, (mediaRect.height - container.height) / 2);\n\n // Constrain drag to overflow boundaries\n if (overflowX > 0) {\n newX = Math.max(-overflowX, Math.min(overflowX, newX));\n } else {\n newX = 0; // Center horizontally if no overflow\n }\n\n if (overflowY > 0) {\n newY = Math.max(-overflowY, Math.min(overflowY, newY));\n } else {\n newY = 0; // Center vertically if no overflow\n }\n\n // Apply transform\n media.style.transform = `translate(${newX}px, ${newY}px) scale(${this.currentScale})`;\n\n // Update for next frame\n this.startX = clientX;\n this.startY = clientY;\n this.currentX = newX;\n this.currentY = newY;\n }\n\n /**\n * End drag operation\n */\n endDrag() {\n if (!this.isDragging) return;\n\n this.isDragging = false;\n this.lastDragTime = Date.now();\n\n const media = this.content.querySelector('.zoomora-media');\n if (media) {\n media.classList.remove('dragging');\n if (this.isZoomed) {\n media.style.cursor = 'grab';\n }\n }\n }\n\n /**\n * Go to specific item by index\n * @param {number} index - Item index\n */\n goTo(index) {\n if (index < 0 || index >= this.items.length) return;\n\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n }\n\n /**\n * Get current item index\n * @returns {number} - Current index\n */\n getCurrentIndex() {\n return this.currentIndex;\n }\n\n /**\n * Get total number of items\n * @returns {number} - Total items\n */\n getTotalItems() {\n return this.items.length;\n }\n\n /**\n * Check if lightbox is open\n * @returns {boolean} - True if open\n */\n isOpen() {\n return this.zoomora && this.zoomora.classList.contains('active');\n }\n\n /**\n * Update options\n * @param {Object} newOptions - New options to merge\n */\n updateOptions(newOptions) {\n this.options = {...this.options, ...newOptions};\n }\n\n /**\n * Refresh the lightbox (re-scan for items)\n */\n refresh() {\n if (this.isOpen()) {\n const currentItem = this.items[this.currentIndex];\n if (currentItem) {\n this.open(currentItem);\n }\n }\n }\n\n /**\n * Destroy the lightbox instance\n */\n destroy() {\n if (!this.isInitialized) return;\n\n // Close if open\n if (this.isOpen()) {\n this.close();\n }\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n\n // Remove all event listeners\n this.eventListeners.forEach((listeners, key) => {\n listeners.forEach(({element, event, handler, options}) => {\n if (element && element.removeEventListener) {\n element.removeEventListener(event, handler, options);\n }\n });\n });\n this.eventListeners.clear();\n\n // Remove DOM elements\n if (this.zoomora && this.zoomora.parentNode) {\n this.zoomora.parentNode.removeChild(this.zoomora);\n }\n\n // Reset properties\n this.isInitialized = false;\n this.items = [];\n this.currentIndex = 0;\n this.zoomora = null;\n this.content = null;\n this.counter = null;\n this.thumbs = null;\n this.loading = null;\n this.caption = null;\n }\n }\n\n // Export the class\n return Zoomora;\n}));"],"names":["this"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"zoomora.umd.js","sources":["../src/zoomora.js"],"sourcesContent":["/*!\n * Zoomora Lightbox Plugin v1.2.0\n * A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features\n *\n * Copyright (c) 2026 Faruk Ahmed (FrontTheme)\n * Licensed under MIT License\n */\n\n// Import styles\nimport './styles/zoomora.scss';\n\n(function (global, factory) {\n 'use strict';\n\n if (typeof module === 'object' && typeof module.exports === 'object') {\n // CommonJS/Node.js\n module.exports = factory();\n } else if (typeof define === 'function' && define.amd) {\n // AMD\n define(factory);\n } else {\n // Browser globals\n global.Zoomora = factory();\n }\n}(typeof window !== 'undefined' ? window : this, function () {\n 'use strict';\n\n /**\n * Zoomora Lightbox Plugin\n * @class\n */\n class Zoomora {\n /**\n * Default configuration options\n * @type {Object}\n */\n static get defaults() {\n return {\n selector: '[data-zoomora]',\n showCounter: true,\n showThumbnails: true,\n showFullscreen: true,\n showZoom: true,\n transition: 'fade', // 'fade' or 'slide'\n useHref: false, // Use href instead of data-src\n maxZoomScale: 3, // Maximum zoom scale\n zoomStep: 0.1, // Zoom step for scroll wheel\n animationDuration: 300, // Animation duration in ms\n closeOnBackgroundClick: true, // Close lightbox when clicking on background\n onOpen: null, // Callback when lightbox opens\n onClose: null, // Callback when lightbox closes\n onNext: null, // Callback when navigating to next item\n onPrev: null, // Callback when navigating to previous item\n\n // Auto-hide controls\n showAutoHideToggle: true, // Show auto-hide toggle button\n autoHideDelay: 3000, // Delay in ms before hiding controls\n autoHideEnabled: false, // Default state of auto-hide\n };\n }\n\n /**\n * Constructor\n * @param {Object} options - Configuration options\n */\n constructor(options = {}) {\n this.options = {...Zoomora.defaults, ...options};\n this.currentIndex = 0;\n this.items = [];\n this.isZoomed = false;\n this.isFullscreen = false;\n this.isDragging = false;\n this.thumbnailsVisible = true;\n this.startX = 0;\n this.startY = 0;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n this.isInitialized = false;\n this.eventListeners = new Map();\n\n // Auto-hide controls\n this.autoHideEnabled = false;\n this.autoHideTimeout = null;\n this.autoHideDelay = 3000;\n this.isControlsVisible = true;\n this.idleTimer = null;\n\n this.lastDragTime = 0;\n\n // Bound methods for event listeners\n this.boundMethods = {\n handleDocumentClick: this.handleDocumentClick.bind(this),\n handleKeydown: this.handleKeydown.bind(this),\n handleFullscreenChange: this.handleFullscreenChange.bind(this),\n handleZoomoraClick: this.handleZoomoraClick.bind(this),\n handleContentClick: this.handleContentClick.bind(this),\n handleMouseDown: this.handleMouseDown.bind(this),\n handleMouseMove: this.handleMouseMove.bind(this),\n handleMouseUp: this.handleMouseUp.bind(this),\n handleTouchStart: this.handleTouchStart.bind(this),\n handleTouchMove: this.handleTouchMove.bind(this),\n handleTouchEnd: this.handleTouchEnd.bind(this),\n };\n\n this.init();\n }\n\n /**\n * Initialize the plugin\n */\n init() {\n if (this.isInitialized) {\n console.warn('Zoomora: Plugin already initialized');\n return;\n }\n\n try {\n this.createLightbox();\n this.bindEvents();\n\n this.isInitialized = true;\n } catch (error) {\n console.error('Zoomora: Initialization failed', error);\n }\n }\n\n /**\n * Static method to bind to anchor tags with href\n * @param {string} selector - CSS selector\n * @param {Object} options - Configuration options\n * @returns {Zoomora} - New Zoomora instance\n */\n static bind(selector, options = {}) {\n const enhancedOptions = {\n ...options,\n selector: selector,\n useHref: true\n };\n return new Zoomora(enhancedOptions);\n }\n\n /**\n * Create lightbox HTML structure\n */\n createLightbox() {\n // Check if lightbox already exists\n if (document.getElementById('zoomoraLightbox')) {\n console.warn('Zoomora: Lightbox already exists in DOM');\n return;\n }\n\n // Build auto-hide button conditionally\n const autoHideButtonHTML = this.options.showAutoHideToggle ? `\n <button class=\"zoomora-btn\" id=\"zoomoraAutoHideBtn\" title=\"Toggle Auto-Hide Controls\">\n <i class=\"zoomorai-controls-off\"></i>\n </button>\n ` : '';\n\n const zoomoraHTML = `\n <div class=\"zoomora\" id=\"zoomoraLightbox\">\n <div class=\"zoomora-container\">\n <div class=\"zoomora-header\" id=\"zoomoraHeader\">\n <div class=\"zoomora-counter\" id=\"zoomoraCounter\">1 / 1</div>\n <div class=\"zoomora-controls\">\n <button class=\"zoomora-btn\" id=\"zoomoraThumbnailBtn\" title=\"Toggle Thumbnails\">\n <i class=\"zoomorai-thumbnails\"></i>\n </button>\n ${autoHideButtonHTML}\n <button class=\"zoomora-btn\" id=\"zoomoraZoomBtn\" title=\"Zoom\">\n <i class=\"zoomorai-zoom\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraFullscreenBtn\" title=\"Fullscreen\">\n <i class=\"zoomorai-expand\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCollapseBtn\" title=\"Exit Fullscreen\" style=\"display: none;\">\n <i class=\"zoomorai-collapse\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCloseBtn\" title=\"Close\">\n <i class=\"zoomorai-close\"></i>\n </button>\n </div>\n </div>\n \n <div class=\"zoomora-content\" id=\"zoomoraContent\">\n <div class=\"zoomora-loading\" id=\"zoomoraLoading\"></div>\n <div class=\"zoomora-slides-container\" id=\"zoomoraSlidesContainer\"></div>\n </div>\n \n <button class=\"zoomora-nav prev\" id=\"zoomoraPrevBtn\">\n <i class=\"zoomorai-arrow-left\"></i>\n </button>\n <button class=\"zoomora-nav next\" id=\"zoomoraNextBtn\">\n <i class=\"zoomorai-arrow-right\"></i>\n </button>\n \n <div class=\"zoomora-caption\" id=\"zoomoraCaption\"></div>\n <div class=\"zoomora-thumbnails\" id=\"zoomoraThumbs\"></div>\n </div>\n </div>\n `;\n\n document.body.insertAdjacentHTML('beforeend', zoomoraHTML);\n\n // Cache DOM elements\n this.zoomora = document.getElementById('zoomoraLightbox');\n this.header = document.getElementById('zoomoraHeader');\n this.content = document.getElementById('zoomoraContent');\n this.slidesContainer = document.getElementById('zoomoraSlidesContainer');\n this.counter = document.getElementById('zoomoraCounter');\n this.thumbs = document.getElementById('zoomoraThumbs');\n this.loading = document.getElementById('zoomoraLoading');\n this.caption = document.getElementById('zoomoraCaption');\n this.prevBtn = document.getElementById('zoomoraPrevBtn');\n this.nextBtn = document.getElementById('zoomoraNextBtn');\n\n // Verify all elements were created\n if (!this.zoomora || !this.content || !this.counter || !this.thumbs || !this.loading || !this.caption) {\n throw new Error('Failed to create required DOM elements');\n }\n }\n\n /**\n * Bind event listeners\n */\n bindEvents() {\n // Document click handler for opening lightbox\n this.addEventListener(document, 'click', this.boundMethods.handleDocumentClick);\n\n // Control button handlers\n this.addEventListener(document.getElementById('zoomoraCloseBtn'), 'click', () => this.close());\n this.addEventListener(document.getElementById('zoomoraPrevBtn'), 'click', () => this.prev());\n this.addEventListener(document.getElementById('zoomoraNextBtn'), 'click', () => this.next());\n this.addEventListener(document.getElementById('zoomoraZoomBtn'), 'click', () => this.toggleZoom());\n this.addEventListener(document.getElementById('zoomoraFullscreenBtn'), 'click', () => this.toggleFullscreen());\n this.addEventListener(document.getElementById('zoomoraCollapseBtn'), 'click', () => this.exitFullscreen());\n this.addEventListener(document.getElementById('zoomoraThumbnailBtn'), 'click', () => this.toggleThumbnails());\n\n // Fullscreen change events\n this.addEventListener(document, 'fullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'webkitfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'mozfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'MSFullscreenChange', this.boundMethods.handleFullscreenChange);\n\n // Keyboard navigation\n this.addEventListener(document, 'keydown', this.boundMethods.handleKeydown);\n\n // Lightbox click to close\n this.addEventListener(this.zoomora, 'click', this.boundMethods.handleZoomoraClick);\n\n // Content click for zoom toggle and background click\n this.addEventListener(this.content, 'click', this.boundMethods.handleContentClick);\n\n // Mouse drag events\n this.addEventListener(this.content, 'mousedown', this.boundMethods.handleMouseDown);\n this.addEventListener(this.content, 'mousemove', this.boundMethods.handleMouseMove);\n this.addEventListener(this.content, 'mouseup', this.boundMethods.handleMouseUp);\n this.addEventListener(this.content, 'mouseleave', this.boundMethods.handleMouseUp);\n\n // Touch events\n this.addEventListener(this.content, 'touchstart', this.boundMethods.handleTouchStart, {passive: false});\n this.addEventListener(this.content, 'touchmove', this.boundMethods.handleTouchMove, {passive: false});\n this.addEventListener(this.content, 'touchend', this.boundMethods.handleTouchEnd);\n\n // Add auto-hide toggle button handler (only if enabled)\n if (this.options.showAutoHideToggle) {\n this.addEventListener(document.getElementById('zoomoraAutoHideBtn'), 'click', () => this.toggleAutoHide());\n\n // Add mouse/touch activity listeners for auto-hide\n this.addEventListener(this.zoomora, 'mousemove', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'touchstart', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'keydown', () => this.handleUserActivity());\n }\n }\n\n /**\n * Add event listener with cleanup tracking\n * @param {Element} element - DOM element\n * @param {string} event - Event type\n * @param {Function} handler - Event handler\n * @param {Object} options - Event options\n */\n addEventListener(element, event, handler, options = {}) {\n if (!element) return;\n\n element.addEventListener(event, handler, options);\n\n // Track for cleanup\n const key = `${element.constructor.name}_${event}`;\n if (!this.eventListeners.has(key)) {\n this.eventListeners.set(key, []);\n }\n this.eventListeners.get(key).push({element, event, handler, options});\n }\n\n /**\n * Handle document click events\n * @param {Event} e - Click event\n */\n handleDocumentClick(e) {\n const target = e.target.closest(this.options.selector);\n if (target) {\n e.preventDefault();\n this.open(target);\n }\n }\n\n /**\n * Handle keyboard events\n * @param {KeyboardEvent} e - Keyboard event\n */\n handleKeydown(e) {\n if (!this.zoomora.classList.contains('active')) return;\n\n switch (e.key) {\n case 'Escape':\n if (this.isFullscreen) {\n this.exitFullscreen();\n } else {\n this.close();\n }\n break;\n case 'ArrowLeft':\n this.prev();\n break;\n case 'ArrowRight':\n this.next();\n break;\n case 'z':\n case 'Z':\n this.toggleZoom();\n break;\n case 'f':\n case 'F':\n this.toggleFullscreen();\n break;\n case 't':\n case 'T':\n this.toggleThumbnails();\n break;\n }\n }\n\n /**\n * Handle fullscreen change events\n */\n handleFullscreenChange() {\n const isInFullscreen = !!(\n document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement\n );\n\n // Only update if state changed from fullscreen to not fullscreen\n if (!isInFullscreen && this.isFullscreen) {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n // Update if entering fullscreen\n else if (isInFullscreen && !this.isFullscreen) {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n }\n\n /**\n * Handle zoomora container clicks\n * @param {Event} e - Click event\n */\n handleZoomoraClick(e) {\n if (e.target === this.zoomora && this.options.closeOnBackgroundClick) {\n this.close();\n }\n }\n\n /**\n * Handle content clicks\n * @param {Event} e - Click event\n */\n handleContentClick(e) {\n // Ignore click if we just finished dragging (within 200ms)\n if (Date.now() - this.lastDragTime < 200) {\n return;\n }\n\n // Don't close on header clicks\n if (this.header && this.header.contains(e.target)) {\n return;\n }\n\n // Don't close on button clicks\n if (e.target.closest('button')) {\n return;\n }\n\n // Check if click is directly on actual media element (img, video, iframe)\n const mediaElement = e.target.closest('.zoomora-media, .zoomora-video, .zoomora-iframe');\n\n if (mediaElement) {\n // Only toggle zoom for images\n if (mediaElement.classList.contains('zoomora-media') && !mediaElement.classList.contains('no-zoom')) {\n this.toggleZoom();\n }\n return;\n }\n\n // Check if clicking inside video container but not on video itself\n const videoContainer = e.target.closest('.zoomora-video-container');\n if (videoContainer) {\n // If clicking on the play button, don't close\n if (e.target.closest('.zoomora-play-button')) {\n return;\n }\n // If clicking on background area of video container, close\n if (this.options.closeOnBackgroundClick) {\n this.close();\n }\n return;\n }\n\n // Check if clicking on background elements (including when zoomed)\n // This checks the actual target element, not just closest()\n const clickedElement = e.target;\n const isBackgroundElement =\n clickedElement.classList.contains('zoomora-content') ||\n clickedElement.classList.contains('zoomora-slide-container') ||\n clickedElement.classList.contains('zoomora-slide') ||\n clickedElement.classList.contains('zoomora-slides-container') ||\n clickedElement.id === 'zoomoraContent' ||\n clickedElement.id === 'zoomoraSlidesContainer';\n\n if (isBackgroundElement && this.options.closeOnBackgroundClick) {\n this.close();\n return;\n }\n\n // If we reach here and no media was clicked, close\n if (this.options.closeOnBackgroundClick) {\n this.close();\n }\n }\n\n /**\n * Handle mouse down events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseDown(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle mouse move events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle mouse up events\n */\n handleMouseUp() {\n this.endDrag();\n }\n\n /**\n * Handle touch start events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchStart(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle touch move events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle touch end events\n */\n handleTouchEnd() {\n this.endDrag();\n }\n\n /**\n * Get image source from element\n * @param {Element} item - DOM element\n * @returns {string} - Image source URL\n */\n getImageSource(item) {\n const src = item.dataset.src || item.src || item.getAttribute('src');\n const type = item.dataset.type || 'image';\n\n // Handle YouTube URLs for video types\n if (type === 'video' && src) {\n return this.convertToEmbedUrl(src);\n }\n\n return src;\n }\n\n /**\n * Convert YouTube URLs to embed format\n * @param url\n * @returns {*|string}\n */\n convertToEmbedUrl(url) {\n // If already an embed URL, return as is\n if (url.includes('youtube.com/embed/')) {\n return url;\n }\n\n // Handle different YouTube URL formats\n let videoId = null;\n let startTime = null;\n\n // Extract video ID and start time from different YouTube URL formats\n if (url.includes('youtube.com/watch')) {\n const urlParams = new URLSearchParams(url.split('?')[1]);\n videoId = urlParams.get('v');\n const t = urlParams.get('t');\n if (t) {\n // Convert time format (e.g., \"111s\" to seconds)\n startTime = t.replace('s', '');\n }\n } else if (url.includes('youtu.be/')) {\n const parts = url.split('/');\n const videoAndParams = parts[parts.length - 1];\n if (videoAndParams.includes('?')) {\n videoId = videoAndParams.split('?')[0];\n const urlParams = new URLSearchParams(videoAndParams.split('?')[1]);\n const t = urlParams.get('t');\n if (t) startTime = t.replace('s', '');\n } else {\n videoId = videoAndParams;\n }\n }\n\n if (videoId) {\n let embedUrl = `https://www.youtube.com/embed/${videoId}`;\n const params = new URLSearchParams();\n\n if (startTime) {\n params.append('start', startTime);\n }\n\n // Add other useful parameters\n params.append('rel', '0'); // Don't show related videos\n params.append('modestbranding', '1'); // Modest branding\n\n // Option: Add autoplay for YouTube videos (uncomment if desired)\n // params.append('autoplay', '1');\n\n if (params.toString()) {\n embedUrl += '?' + params.toString();\n }\n\n return embedUrl;\n }\n\n // If not a YouTube URL or couldn't parse, return original\n return url;\n }\n\n /**\n * Get thumbnail source from element\n * @param {Element} item - DOM element\n * @returns {string} - Thumbnail source URL\n */\n getThumbnailSource(item) {\n const type = item.dataset.type || 'image';\n\n // For video items, always use the img.src as thumbnail (poster image)\n if (type === 'video') {\n return item.src || item.getAttribute('src');\n }\n\n // For regular images, use data-src or fallback to src\n return item.dataset.src || item.src || item.getAttribute('src');\n }\n\n /**\n * Get group identifier from element\n * @param {Element} element - DOM element\n * @returns {string} - Group identifier\n */\n getGroup(element) {\n if (this.options.useHref) {\n return element.dataset.lightbox || element.dataset.gallery || 'default';\n }\n return element.dataset.zoomora || 'default';\n }\n\n /**\n * Open lightbox with specified element\n * @param {Element} element - DOM element to open\n */\n open(element) {\n if (!element) return;\n\n const group = this.getGroup(element);\n let groupSelector;\n\n if (this.options.useHref) {\n if (element.dataset.lightbox) {\n groupSelector = `[data-lightbox=\"${group}\"]`;\n } else if (element.dataset.gallery) {\n groupSelector = `[data-gallery=\"${group}\"]`;\n } else {\n groupSelector = this.options.selector;\n }\n } else {\n groupSelector = `[data-zoomora=\"${group}\"]`;\n }\n\n this.items = Array.from(document.querySelectorAll(groupSelector));\n this.currentIndex = Math.max(0, this.items.indexOf(element));\n\n // Reset states\n this.isZoomed = false;\n this.isFullscreen = false;\n this.thumbnailsVisible = true;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n this.zoomora.classList.add('active');\n document.body.style.overflow = 'hidden';\n\n this.loadContent();\n this.updateThumbnails();\n this.updateCounter();\n this.updateNavigation();\n this.updateCaption();\n this.updateButtons();\n\n // Initialize auto-hide if enabled\n if (this.autoHideEnabled) {\n this.startAutoHideTimer();\n } else {\n this.showControls();\n }\n\n // Trigger callback\n if (typeof this.options.onOpen === 'function') {\n this.options.onOpen(element, this.currentIndex);\n }\n }\n\n /**\n * Close lightbox\n */\n close() {\n if (this.isFullscreen) {\n this.exitFullscreen();\n }\n\n this.zoomora.classList.remove('active');\n document.body.style.overflow = '';\n this.isZoomed = false;\n this.isFullscreen = false;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n const media = this.content.querySelector('.zoomora-media');\n if (media) {\n media.classList.remove('zoomed');\n media.style.transform = '';\n media.style.cursor = '';\n }\n\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n this.showControls();\n\n // Trigger callback\n if (typeof this.options.onClose === 'function') {\n this.options.onClose(this.currentIndex);\n }\n }\n\n /**\n * Navigate to previous item\n */\n prev() {\n if (this.currentIndex > 0) {\n this.currentIndex--;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onPrev === 'function') {\n this.options.onPrev(this.currentIndex);\n }\n }\n }\n\n /**\n * Navigate to next item\n */\n next() {\n if (this.currentIndex < this.items.length - 1) {\n this.currentIndex++;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onNext === 'function') {\n this.options.onNext(this.currentIndex);\n }\n }\n }\n\n /**\n * Load content for current item\n */\n loadContent() {\n if (!this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const src = this.getImageSource(item);\n const type = item.dataset.type || 'image';\n\n if (!src) {\n console.error('Zoomora: No source found for item');\n return;\n }\n\n // Reset zoom state\n this.isZoomed = false;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n // Show loading spinner\n this.loading.style.display = 'block';\n\n if (this.slidesContainer) {\n this.slidesContainer.innerHTML = '';\n }\n\n setTimeout(() => {\n this.renderContent(src, type, item);\n }, 100);\n }\n\n /**\n * Render content based on type\n * @param {string} src - Source URL\n * @param {string} type - Content type\n * @param {Element} item - Original item element\n */\n renderContent(src, type, item) {\n const slideContainer = document.createElement('div');\n slideContainer.className = 'zoomora-slide-container';\n\n // Create slide wrapper\n const slide = document.createElement('div');\n slide.className = `zoomora-slide ${this.options.transition === 'slide' ? 'slide-effect' : 'fade-effect'}`;\n slide.style.opacity = '0';\n slide.style.transform = this.options.transition === 'slide' ? 'translateX(100%)' : 'scale(0.8)';\n\n let mediaElement;\n\n try {\n switch (type) {\n case 'video':\n if (src.endsWith('.mp4') || src.endsWith('.webm') || src.endsWith('.ogg')) {\n const videoContainer = document.createElement('div');\n videoContainer.className = 'zoomora-video-container';\n\n mediaElement = document.createElement('video');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('preload', 'metadata');\n\n const posterSrc = item.src || item.getAttribute('src');\n if (posterSrc) {\n mediaElement.setAttribute('poster', posterSrc);\n }\n\n const playButton = document.createElement('div');\n playButton.className = 'zoomora-play-button';\n playButton.innerHTML = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>`;\n\n playButton.addEventListener('click', () => {\n mediaElement.play();\n playButton.style.display = 'none';\n mediaElement.setAttribute('controls', '');\n });\n\n mediaElement.addEventListener('ended', () => {\n playButton.style.display = 'flex';\n });\n\n videoContainer.appendChild(mediaElement);\n videoContainer.appendChild(playButton);\n slideContainer.appendChild(videoContainer);\n } else {\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('allowfullscreen', '');\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n }\n break;\n\n case 'iframe':\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-iframe';\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n break;\n\n default:\n mediaElement = document.createElement('img');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-media';\n mediaElement.alt = item.alt || item.title || '';\n\n mediaElement.onload = () => {\n this.loading.style.display = 'none';\n this.checkZoomability(mediaElement);\n this.animateSlideIn(slide);\n };\n\n mediaElement.onerror = () => {\n this.loading.style.display = 'none';\n console.error('Zoomora: Failed to load image:', src);\n this.animateSlideIn(slide);\n };\n\n slideContainer.appendChild(mediaElement);\n }\n\n slide.appendChild(slideContainer);\n\n // Clear existing slides and add new one\n this.slidesContainer.innerHTML = '';\n this.slidesContainer.appendChild(slide);\n\n if (type !== 'image') {\n this.loading.style.display = 'none';\n this.animateSlideIn(slide);\n }\n\n } catch (error) {\n console.error('Zoomora: Error rendering content:', error);\n this.loading.style.display = 'none';\n }\n }\n\n // Animation helper\n animateSlideIn(slide) {\n // Force reflow\n slide.offsetHeight;\n\n // Add active class and animate\n slide.classList.add('active');\n\n if (this.options.transition === 'slide') {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'translateX(0)';\n slide.style.opacity = '1';\n } else {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'scale(1)';\n slide.style.opacity = '1';\n }\n }\n\n // Toggle auto-hide controls\n toggleAutoHide() {\n this.autoHideEnabled = !this.autoHideEnabled;\n const autoHideBtn = document.getElementById('zoomoraAutoHideBtn');\n\n if (this.autoHideEnabled) {\n autoHideBtn.classList.add('active');\n autoHideBtn.title = 'Disable Auto-Hide Controls';\n this.startAutoHideTimer();\n } else {\n autoHideBtn.classList.remove('active');\n autoHideBtn.title = 'Enable Auto-Hide Controls';\n this.stopAutoHideTimer();\n this.showControls();\n }\n }\n\n // Handle user activity\n handleUserActivity() {\n if (!this.autoHideEnabled) return;\n\n this.showControls();\n this.startAutoHideTimer();\n }\n\n // Start auto-hide timer\n startAutoHideTimer() {\n this.stopAutoHideTimer();\n\n this.autoHideTimeout = setTimeout(() => {\n this.hideControls();\n }, this.options.autoHideDelay);\n }\n\n // Stop auto-hide timer\n stopAutoHideTimer() {\n if (this.autoHideTimeout) {\n clearTimeout(this.autoHideTimeout);\n this.autoHideTimeout = null;\n }\n }\n\n // Show controls\n showControls() {\n if (this.isControlsVisible) return;\n\n this.isControlsVisible = true;\n this.zoomora.classList.remove('controls-hidden');\n\n // Animate controls back in\n if (this.header) {\n this.header.style.transform = 'translateY(0)';\n this.header.style.opacity = '1';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(0)';\n this.thumbs.style.opacity = '1';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(0)';\n this.prevBtn.style.opacity = '1';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(0)';\n this.nextBtn.style.opacity = '1';\n }\n }\n\n // Hide controls\n hideControls() {\n if (!this.isControlsVisible) return;\n\n this.isControlsVisible = false;\n this.zoomora.classList.add('controls-hidden');\n\n // Animate controls out\n if (this.header) {\n this.header.style.transform = 'translateY(-100%)';\n this.header.style.opacity = '0';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(100%)';\n this.thumbs.style.opacity = '0';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(-100%)';\n this.prevBtn.style.opacity = '0';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(100%)';\n this.nextBtn.style.opacity = '0';\n }\n }\n\n /**\n * Check if image can be zoomed\n * @param {HTMLImageElement} img - Image element\n */\n checkZoomability(img) {\n if (!img || !img.naturalWidth || !img.naturalHeight) return;\n\n const imgRect = img.getBoundingClientRect();\n const renderedWidth = imgRect.width;\n const renderedHeight = imgRect.height;\n const naturalWidth = img.naturalWidth;\n const naturalHeight = img.naturalHeight;\n\n const isScaledDown = naturalWidth > renderedWidth || naturalHeight > renderedHeight;\n const zoomRatioX = naturalWidth / renderedWidth;\n const zoomRatioY = naturalHeight / renderedHeight;\n const maxZoomRatio = Math.max(zoomRatioX, zoomRatioY);\n\n // Store zoom info\n img.dataset.zoomRatio = maxZoomRatio;\n img.dataset.naturalWidth = naturalWidth;\n img.dataset.naturalHeight = naturalHeight;\n img.dataset.renderedWidth = renderedWidth;\n img.dataset.renderedHeight = renderedHeight;\n\n // Enable zoom if significantly scaled down\n if (isScaledDown && maxZoomRatio > 1.1) {\n img.classList.remove('no-zoom');\n } else {\n img.classList.add('no-zoom');\n }\n }\n\n /**\n * Calculate zoom levels for an image\n * @param {HTMLImageElement} img - Image element\n * @returns {Object} Zoom configuration\n */\n calculateZoomLevels(img) {\n if (!img || !img.naturalWidth || !img.naturalHeight) {\n return {canZoom: false, levels: [], currentLevel: 0};\n }\n\n // Get CONTAINER size (not current displayed image size)\n const container = this.content.getBoundingClientRect();\n const containerWidth = container.width;\n const containerHeight = container.height;\n\n const naturalWidth = img.naturalWidth;\n const naturalHeight = img.naturalHeight;\n\n // Calculate what the ORIGINAL fit-to-screen scale would be\n const scaleToFitWidth = containerWidth / naturalWidth;\n const scaleToFitHeight = containerHeight / naturalHeight;\n const fitScale = Math.min(scaleToFitWidth, scaleToFitHeight);\n\n // If image naturally fits or is smaller than container, can't zoom\n if (fitScale >= 0.95) {\n return {canZoom: false, levels: [], currentLevel: 0};\n }\n\n // Calculate zoom levels based on FIT scale (not current scale)\n const levels = [1]; // Start with fit-to-screen\n\n // Add progressive levels: 1.5x, 2x, 3x\n if (fitScale * 1.5 <= 1) levels.push(1.5);\n if (fitScale * 2 <= 1) levels.push(2);\n if (fitScale * 3 <= 1) levels.push(3);\n\n // Add actual size (100%) as final level\n const actualSizeScale = 1 / fitScale;\n if (actualSizeScale > levels[levels.length - 1]) {\n levels.push(actualSizeScale);\n }\n\n return {\n canZoom: levels.length > 1,\n levels: levels,\n currentLevel: 0,\n baseScale: fitScale,\n naturalWidth: naturalWidth,\n naturalHeight: naturalHeight\n };\n }\n\n /**\n * Update counter display\n */\n updateCounter() {\n if (this.options.showCounter && this.counter) {\n this.counter.textContent = `${this.currentIndex + 1} / ${this.items.length}`;\n }\n }\n\n /**\n * Update caption display\n */\n updateCaption() {\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption) {\n this.caption.textContent = caption;\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n this.caption.style.pointerEvents = 'auto';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n this.caption.style.pointerEvents = 'none';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n }\n }\n\n /**\n * Update thumbnails display\n */\n updateThumbnails() {\n if (!this.options.showThumbnails || !this.thumbs) return;\n\n if (this.items.length === 1) {\n this.caption.classList.add('single-item-thumbnail');\n this.thumbs.style.display = 'none';\n return;\n }\n\n this.caption.classList.remove('single-item-thumbnail');\n\n this.thumbs.style.display = 'flex';\n this.thumbs.innerHTML = '';\n\n this.items.forEach((item, index) => {\n const thumb = document.createElement('div');\n thumb.className = 'zoomora-thumb';\n if (index === this.currentIndex) thumb.classList.add('active');\n\n const img = document.createElement('img');\n const thumbSrc = this.getThumbnailSource(item);\n\n if (thumbSrc) {\n img.src = thumbSrc;\n img.alt = item.alt || item.title || '';\n img.onerror = () => {\n thumb.style.display = 'none';\n };\n }\n\n thumb.appendChild(img);\n\n thumb.addEventListener('click', () => {\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n });\n\n this.thumbs.appendChild(thumb);\n });\n }\n\n /**\n * Update navigation buttons\n */\n updateNavigation() {\n const prevBtn = document.getElementById('zoomoraPrevBtn');\n const nextBtn = document.getElementById('zoomoraNextBtn');\n\n if (prevBtn) {\n prevBtn.style.display = this.currentIndex > 0 ? 'flex' : 'none';\n }\n if (nextBtn) {\n nextBtn.style.display = this.currentIndex < this.items.length - 1 ? 'flex' : 'none';\n }\n }\n\n /**\n * Update control buttons\n */\n updateButtons() {\n const fullscreenBtn = document.getElementById('zoomoraFullscreenBtn');\n const collapseBtn = document.getElementById('zoomoraCollapseBtn');\n\n if (fullscreenBtn && collapseBtn) {\n if (this.isFullscreen) {\n fullscreenBtn.style.display = 'none';\n collapseBtn.style.display = 'flex';\n } else {\n fullscreenBtn.style.display = 'flex';\n collapseBtn.style.display = 'none';\n }\n }\n }\n\n /**\n * Toggle zoom state\n */\n toggleZoom() {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || media.tagName !== 'IMG') return;\n\n // Calculate zoom levels\n const zoomConfig = this.calculateZoomLevels(media);\n\n if (!zoomConfig.canZoom) {\n return;\n }\n\n // Get or initialize current zoom level\n if (!media.dataset.zoomLevel) {\n media.dataset.zoomLevel = '0';\n }\n\n let currentLevel = parseInt(media.dataset.zoomLevel) || 0;\n\n // Cycle to next level\n currentLevel++;\n if (currentLevel >= zoomConfig.levels.length) {\n // Reset to fit-to-screen\n currentLevel = 0;\n }\n\n const targetScale = zoomConfig.levels[currentLevel];\n media.dataset.zoomLevel = currentLevel.toString();\n\n if (currentLevel === 0) {\n // Back to fit-to-screen\n this.isZoomed = false;\n this.isDragging = false;\n media.classList.remove('dragging');\n media.style.transform = '';\n media.style.cursor = 'pointer';\n media.classList.remove('zoomed');\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n } else {\n // Zoom in - reset position to center\n this.isZoomed = true;\n this.currentScale = targetScale;\n this.currentX = 0; // Always reset to center on zoom change\n this.currentY = 0;\n\n media.style.transform = `translate(0px, 0px) scale(${targetScale})`;\n media.style.cursor = 'grab';\n media.classList.add('zoomed');\n }\n }\n\n /**\n * Update image transform based on current state\n * @param {HTMLElement} media - Media element\n */\n updateImageTransform(media) {\n if (!media) return;\n\n if (this.currentScale === 1) {\n media.style.transform = '';\n } else {\n // IMPORTANT: translate in scaled space, so divide by scale\n const translateX = this.currentX / this.currentScale;\n const translateY = this.currentY / this.currentScale;\n media.style.transform = `scale(${this.currentScale}) translate(${translateX}px, ${translateY}px)`;\n }\n }\n\n /**\n * Toggle fullscreen mode\n */\n toggleFullscreen() {\n if (!this.isFullscreen) {\n this.enterFullscreen();\n } else {\n this.exitFullscreen();\n }\n }\n\n /**\n * Enter fullscreen mode\n */\n enterFullscreen() {\n const element = this.zoomora;\n\n try {\n // Try standard API first\n if (element.requestFullscreen) {\n element.requestFullscreen()\n .then(() => {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n })\n .catch(err => {\n console.warn('Zoomora: Fullscreen request failed:', err.message);\n this.fallbackFullscreen();\n });\n }\n // Try webkit (Safari, older Chrome)\n else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n // Webkit doesn't return a promise, so set state immediately\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n // Try moz (Firefox)\n else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n // Try ms (IE11)\n else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n // Fallback to CSS fullscreen\n else {\n console.warn('Zoomora: Fullscreen API not supported, using CSS fallback');\n this.fallbackFullscreen();\n }\n } catch (error) {\n console.error('Zoomora: Error entering fullscreen:', error);\n this.fallbackFullscreen();\n }\n }\n\n /**\n * Exit fullscreen mode\n */\n exitFullscreen() {\n // First check if we're actually in fullscreen\n const isInFullscreen = !!(\n document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement\n );\n\n if (!isInFullscreen) {\n // Not in real fullscreen, just exit CSS fullscreen\n this.fallbackExitFullscreen();\n return;\n }\n\n try {\n // Try standard API first\n if (document.exitFullscreen) {\n document.exitFullscreen()\n .then(() => {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n })\n .catch(err => {\n console.warn('Zoomora: Exit fullscreen failed:', err.message);\n this.fallbackExitFullscreen();\n });\n }\n // Try webkit\n else if (document.webkitExitFullscreen) {\n document.webkitExitFullscreen();\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n // Try moz\n else if (document.mozCancelFullScreen) {\n document.mozCancelFullScreen();\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n // Try ms\n else if (document.msExitFullscreen) {\n document.msExitFullscreen();\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n // Fallback\n else {\n this.fallbackExitFullscreen();\n }\n } catch (error) {\n console.error('Zoomora: Error exiting fullscreen:', error);\n this.fallbackExitFullscreen();\n }\n }\n\n /**\n * Fallback fullscreen using CSS\n */\n fallbackFullscreen() {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Exit CSS fullscreen\n */\n fallbackExitFullscreen() {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Toggle thumbnails visibility\n */\n toggleThumbnails() {\n if (this.items.length === 1) return;\n\n this.thumbnailsVisible = !this.thumbnailsVisible;\n if (this.thumbs) {\n this.thumbs.classList.toggle('thumbs-hidden', !this.thumbnailsVisible);\n\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption && this.thumbs.classList.contains('thumbs-hidden')) {\n this.caption.style.bottom = '20px';\n this.caption.style.transition = 'bottom 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.bottom = '120px';\n }\n }\n }\n\n /**\n * Start drag operation\n * @param {Event} e - Mouse or touch event\n */\n startDrag(e) {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || !this.isZoomed) return;\n\n this.isDragging = true;\n media.classList.add('dragging');\n media.style.cursor = 'grabbing';\n\n this.startX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n this.startY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n // Read current position from transform\n const transform = window.getComputedStyle(media).transform;\n if (transform && transform !== 'none') {\n const matrix = new DOMMatrix(transform);\n this.currentX = matrix.m41;\n this.currentY = matrix.m42;\n } else {\n this.currentX = 0;\n this.currentY = 0;\n }\n\n e.preventDefault();\n }\n\n /**\n * Handle drag movement\n * @param {Event} e - Mouse or touch event\n */\n drag(e) {\n if (!this.isDragging) return;\n e.preventDefault();\n\n const media = this.content.querySelector('.zoomora-media');\n if (!media) return;\n\n const clientX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n const clientY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n const deltaX = clientX - this.startX;\n const deltaY = clientY - this.startY;\n\n let newX = this.currentX + deltaX;\n let newY = this.currentY + deltaY;\n\n // Calculate boundaries for BOTH width AND height\n const container = this.content.getBoundingClientRect();\n const mediaRect = media.getBoundingClientRect();\n\n // How much the scaled image overflows the container\n const overflowX = Math.max(0, (mediaRect.width - container.width) / 2);\n const overflowY = Math.max(0, (mediaRect.height - container.height) / 2);\n\n // Constrain drag to overflow boundaries\n if (overflowX > 0) {\n newX = Math.max(-overflowX, Math.min(overflowX, newX));\n } else {\n newX = 0; // Center horizontally if no overflow\n }\n\n if (overflowY > 0) {\n newY = Math.max(-overflowY, Math.min(overflowY, newY));\n } else {\n newY = 0; // Center vertically if no overflow\n }\n\n // Apply transform\n media.style.transform = `translate(${newX}px, ${newY}px) scale(${this.currentScale})`;\n\n // Update for next frame\n this.startX = clientX;\n this.startY = clientY;\n this.currentX = newX;\n this.currentY = newY;\n }\n\n /**\n * End drag operation\n */\n endDrag() {\n if (!this.isDragging) return;\n\n this.isDragging = false;\n this.lastDragTime = Date.now();\n\n const media = this.content.querySelector('.zoomora-media');\n if (media) {\n media.classList.remove('dragging');\n if (this.isZoomed) {\n media.style.cursor = 'grab';\n }\n }\n }\n\n /**\n * Go to specific item by index\n * @param {number} index - Item index\n */\n goTo(index) {\n if (index < 0 || index >= this.items.length) return;\n\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n }\n\n /**\n * Get current item index\n * @returns {number} - Current index\n */\n getCurrentIndex() {\n return this.currentIndex;\n }\n\n /**\n * Get total number of items\n * @returns {number} - Total items\n */\n getTotalItems() {\n return this.items.length;\n }\n\n /**\n * Check if lightbox is open\n * @returns {boolean} - True if open\n */\n isOpen() {\n return this.zoomora && this.zoomora.classList.contains('active');\n }\n\n /**\n * Update options\n * @param {Object} newOptions - New options to merge\n */\n updateOptions(newOptions) {\n this.options = {...this.options, ...newOptions};\n }\n\n /**\n * Refresh the lightbox (re-scan for items)\n */\n refresh() {\n if (this.isOpen()) {\n const currentItem = this.items[this.currentIndex];\n if (currentItem) {\n this.open(currentItem);\n }\n }\n }\n\n /**\n * Destroy the lightbox instance\n */\n destroy() {\n if (!this.isInitialized) return;\n\n // Close if open\n if (this.isOpen()) {\n this.close();\n }\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n\n // Remove all event listeners\n this.eventListeners.forEach((listeners, key) => {\n listeners.forEach(({element, event, handler, options}) => {\n if (element && element.removeEventListener) {\n element.removeEventListener(event, handler, options);\n }\n });\n });\n this.eventListeners.clear();\n\n // Remove DOM elements\n if (this.zoomora && this.zoomora.parentNode) {\n this.zoomora.parentNode.removeChild(this.zoomora);\n }\n\n // Reset properties\n this.isInitialized = false;\n this.items = [];\n this.currentIndex = 0;\n this.zoomora = null;\n this.content = null;\n this.counter = null;\n this.thumbs = null;\n this.loading = null;\n this.caption = null;\n }\n }\n\n // Export the class\n return Zoomora;\n}));"],"names":["this"],"mappings":"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"}
|
package/dist/zoomora.umd.min.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
!function(t){"function"==typeof define&&define.amd?define(t):t()}(function(){"use strict";var t,e,s=Object.defineProperty,i=Object.defineProperties,
|
|
1
|
+
!function(t){"function"==typeof define&&define.amd?define(t):t()}(function(){"use strict";var t,e,s=Object.defineProperty,i=Object.defineProperties,o=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable,l=(t,e,i)=>e in t?s(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,h=(t,e)=>{for(var s in e||(e={}))a.call(e,s)&&l(t,s,e[s]);if(n)for(var s of n(e))r.call(e,s)&&l(t,s,e[s]);return t};
|
|
2
2
|
/*!
|
|
3
|
-
* Zoomora Lightbox Plugin v1.
|
|
3
|
+
* Zoomora Lightbox Plugin v1.2.0
|
|
4
4
|
* A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features
|
|
5
5
|
*
|
|
6
|
-
* Copyright (c)
|
|
6
|
+
* Copyright (c) 2026 Faruk Ahmed (FrontTheme)
|
|
7
7
|
* Licensed under MIT License
|
|
8
8
|
*/
|
|
9
|
-
t="undefined"!=typeof window?window:void 0,e=function(){class t{static get defaults(){return{selector:"[data-zoomora]",showCounter:!0,showThumbnails:!0,showFullscreen:!0,showZoom:!0,transition:"fade",useHref:!1,maxZoomScale:3,zoomStep:.1,animationDuration:300,onOpen:null,onClose:null,onNext:null,onPrev:null,showAutoHideToggle:!0,autoHideDelay:3e3,autoHideEnabled:!1}}constructor(e={}){this.options=h(h({},t.defaults),e),this.currentIndex=0,this.items=[],this.isZoomed=!1,this.isFullscreen=!1,this.isDragging=!1,this.thumbnailsVisible=!0,this.startX=0,this.startY=0,this.currentX=0,this.currentY=0,this.currentScale=1,this.isInitialized=!1,this.eventListeners=new Map,this.autoHideEnabled=!1,this.autoHideTimeout=null,this.autoHideDelay=3e3,this.isControlsVisible=!0,this.idleTimer=null,this.lastDragTime=0,this.boundMethods={handleDocumentClick:this.handleDocumentClick.bind(this),handleKeydown:this.handleKeydown.bind(this),handleFullscreenChange:this.handleFullscreenChange.bind(this),handleZoomoraClick:this.handleZoomoraClick.bind(this),handleContentClick:this.handleContentClick.bind(this),handleMouseDown:this.handleMouseDown.bind(this),handleMouseMove:this.handleMouseMove.bind(this),handleMouseUp:this.handleMouseUp.bind(this),handleTouchStart:this.handleTouchStart.bind(this),handleTouchMove:this.handleTouchMove.bind(this),handleTouchEnd:this.handleTouchEnd.bind(this)},this.init()}init(){if(!this.isInitialized)try{this.createLightbox(),this.bindEvents(),this.isInitialized=!0}catch(t){}}static bind(e,s={}){const o=(a=h({},s),i(a,n({selector:e,useHref:!0})));var a;return new t(o)}createLightbox(){if(document.getElementById("zoomoraLightbox"))return;const t=`\n <div class="zoomora" id="zoomoraLightbox">\n <div class="zoomora-container">\n <div class="zoomora-header" id="zoomoraHeader">\n <div class="zoomora-counter" id="zoomoraCounter">1 / 1</div>\n <div class="zoomora-controls">\n <button class="zoomora-btn" id="zoomoraThumbnailBtn" title="Toggle Thumbnails">\n <i class="zoomorai-thumbnails"></i>\n </button>\n ${this.options.showAutoHideToggle?'\n <button class="zoomora-btn" id="zoomoraAutoHideBtn" title="Toggle Auto-Hide Controls">\n <i class="zoomorai-controls-off"></i>\n </button>\n ':""}\n <button class="zoomora-btn" id="zoomoraZoomBtn" title="Zoom">\n <i class="zoomorai-zoom"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraFullscreenBtn" title="Fullscreen">\n <i class="zoomorai-expand"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraCollapseBtn" title="Exit Fullscreen" style="display: none;">\n <i class="zoomorai-collapse"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraCloseBtn" title="Close">\n <i class="zoomorai-close"></i>\n </button>\n </div>\n </div>\n \n <div class="zoomora-content" id="zoomoraContent">\n <div class="zoomora-loading" id="zoomoraLoading"></div>\n <div class="zoomora-slides-container" id="zoomoraSlidesContainer"></div>\n </div>\n \n <button class="zoomora-nav prev" id="zoomoraPrevBtn">\n <i class="zoomorai-arrow-left"></i>\n </button>\n <button class="zoomora-nav next" id="zoomoraNextBtn">\n <i class="zoomorai-arrow-right"></i>\n </button>\n \n <div class="zoomora-caption" id="zoomoraCaption"></div>\n <div class="zoomora-thumbnails" id="zoomoraThumbs"></div>\n </div>\n </div>\n `;if(document.body.insertAdjacentHTML("beforeend",t),this.zoomora=document.getElementById("zoomoraLightbox"),this.header=document.getElementById("zoomoraHeader"),this.content=document.getElementById("zoomoraContent"),this.slidesContainer=document.getElementById("zoomoraSlidesContainer"),this.counter=document.getElementById("zoomoraCounter"),this.thumbs=document.getElementById("zoomoraThumbs"),this.loading=document.getElementById("zoomoraLoading"),this.caption=document.getElementById("zoomoraCaption"),this.prevBtn=document.getElementById("zoomoraPrevBtn"),this.nextBtn=document.getElementById("zoomoraNextBtn"),!(this.zoomora&&this.content&&this.counter&&this.thumbs&&this.loading&&this.caption))throw new Error("Failed to create required DOM elements")}bindEvents(){this.addEventListener(document,"click",this.boundMethods.handleDocumentClick),this.addEventListener(document.getElementById("zoomoraCloseBtn"),"click",()=>this.close()),this.addEventListener(document.getElementById("zoomoraPrevBtn"),"click",()=>this.prev()),this.addEventListener(document.getElementById("zoomoraNextBtn"),"click",()=>this.next()),this.addEventListener(document.getElementById("zoomoraZoomBtn"),"click",()=>this.toggleZoom()),this.addEventListener(document.getElementById("zoomoraFullscreenBtn"),"click",()=>this.toggleFullscreen()),this.addEventListener(document.getElementById("zoomoraCollapseBtn"),"click",()=>this.exitFullscreen()),this.addEventListener(document.getElementById("zoomoraThumbnailBtn"),"click",()=>this.toggleThumbnails()),this.addEventListener(document,"fullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"webkitfullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"mozfullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"MSFullscreenChange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"keydown",this.boundMethods.handleKeydown),this.addEventListener(this.zoomora,"click",this.boundMethods.handleZoomoraClick),this.addEventListener(this.content,"click",this.boundMethods.handleContentClick),this.addEventListener(this.content,"mousedown",this.boundMethods.handleMouseDown),this.addEventListener(this.content,"mousemove",this.boundMethods.handleMouseMove),this.addEventListener(this.content,"mouseup",this.boundMethods.handleMouseUp),this.addEventListener(this.content,"mouseleave",this.boundMethods.handleMouseUp),this.addEventListener(this.content,"touchstart",this.boundMethods.handleTouchStart,{passive:!1}),this.addEventListener(this.content,"touchmove",this.boundMethods.handleTouchMove,{passive:!1}),this.addEventListener(this.content,"touchend",this.boundMethods.handleTouchEnd),this.options.showAutoHideToggle&&(this.addEventListener(document.getElementById("zoomoraAutoHideBtn"),"click",()=>this.toggleAutoHide()),this.addEventListener(this.zoomora,"mousemove",()=>this.handleUserActivity()),this.addEventListener(this.zoomora,"touchstart",()=>this.handleUserActivity()),this.addEventListener(this.zoomora,"keydown",()=>this.handleUserActivity()))}addEventListener(t,e,s,i={}){if(!t)return;t.addEventListener(e,s,i);const n=`${t.constructor.name}_${e}`;this.eventListeners.has(n)||this.eventListeners.set(n,[]),this.eventListeners.get(n).push({element:t,event:e,handler:s,options:i})}handleDocumentClick(t){const e=t.target.closest(this.options.selector);e&&(t.preventDefault(),this.open(e))}handleKeydown(t){if(this.zoomora.classList.contains("active"))switch(t.key){case"Escape":this.isFullscreen?this.exitFullscreen():this.close();break;case"ArrowLeft":this.prev();break;case"ArrowRight":this.next();break;case"z":case"Z":this.toggleZoom();break;case"f":case"F":this.toggleFullscreen();break;case"t":case"T":this.toggleThumbnails()}}handleFullscreenChange(){!(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement)&&this.isFullscreen&&(this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons())}handleZoomoraClick(t){t.target===this.zoomora&&this.close()}handleContentClick(t){if(Date.now()-this.lastDragTime<200)return;const e=t.target.closest(".zoomora-media");e&&!e.classList.contains("no-zoom")&&this.toggleZoom()}handleMouseDown(t){this.startDrag(t)}handleMouseMove(t){this.drag(t)}handleMouseUp(){this.endDrag()}handleTouchStart(t){this.startDrag(t)}handleTouchMove(t){this.drag(t)}handleTouchEnd(){this.endDrag()}getImageSource(t){const e=t.dataset.src||t.src||t.getAttribute("src");return"video"===(t.dataset.type||"image")&&e?this.convertToEmbedUrl(e):e}convertToEmbedUrl(t){if(t.includes("youtube.com/embed/"))return t;let e=null,s=null;if(t.includes("youtube.com/watch")){const i=new URLSearchParams(t.split("?")[1]);e=i.get("v");const n=i.get("t");n&&(s=n.replace("s",""))}else if(t.includes("youtu.be/")){const i=t.split("/"),n=i[i.length-1];if(n.includes("?")){e=n.split("?")[0];const t=new URLSearchParams(n.split("?")[1]).get("t");t&&(s=t.replace("s",""))}else e=n}if(e){let t=`https://www.youtube.com/embed/${e}`;const i=new URLSearchParams;return s&&i.append("start",s),i.append("rel","0"),i.append("modestbranding","1"),i.toString()&&(t+="?"+i.toString()),t}return t}getThumbnailSource(t){return"video"===(t.dataset.type||"image")?t.src||t.getAttribute("src"):t.dataset.src||t.src||t.getAttribute("src")}getGroup(t){return this.options.useHref?t.dataset.lightbox||t.dataset.gallery||"default":t.dataset.zoomora||"default"}open(t){if(!t)return;const e=this.getGroup(t);let s;s=this.options.useHref?t.dataset.lightbox?`[data-lightbox="${e}"]`:t.dataset.gallery?`[data-gallery="${e}"]`:this.options.selector:`[data-zoomora="${e}"]`,this.items=Array.from(document.querySelectorAll(s)),this.currentIndex=Math.max(0,this.items.indexOf(t)),this.isZoomed=!1,this.isFullscreen=!1,this.thumbnailsVisible=!0,this.currentX=0,this.currentY=0,this.currentScale=1,this.zoomora.classList.add("active"),document.body.style.overflow="hidden",this.loadContent(),this.updateThumbnails(),this.updateCounter(),this.updateNavigation(),this.updateCaption(),this.updateButtons(),this.autoHideEnabled?this.startAutoHideTimer():this.showControls(),"function"==typeof this.options.onOpen&&this.options.onOpen(t,this.currentIndex)}close(){this.isFullscreen&&this.exitFullscreen(),this.zoomora.classList.remove("active"),document.body.style.overflow="",this.isZoomed=!1,this.isFullscreen=!1,this.currentX=0,this.currentY=0,this.currentScale=1;const t=this.content.querySelector(".zoomora-media");t&&(t.classList.remove("zoomed"),t.style.transform="",t.style.cursor=""),this.zoomora.classList.remove("fullscreen"),this.updateButtons(),this.stopAutoHideTimer(),this.showControls(),"function"==typeof this.options.onClose&&this.options.onClose(this.currentIndex)}prev(){this.currentIndex>0&&(this.currentIndex--,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption(),"function"==typeof this.options.onPrev&&this.options.onPrev(this.currentIndex))}next(){this.currentIndex<this.items.length-1&&(this.currentIndex++,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption(),"function"==typeof this.options.onNext&&this.options.onNext(this.currentIndex))}loadContent(){if(!this.items[this.currentIndex])return;const t=this.items[this.currentIndex],e=this.getImageSource(t),s=t.dataset.type||"image";e&&(this.isZoomed=!1,this.currentX=0,this.currentY=0,this.currentScale=1,this.loading.style.display="block",this.slidesContainer&&(this.slidesContainer.innerHTML=""),setTimeout(()=>{this.renderContent(e,s,t)},100))}renderContent(t,e,s){const i=document.createElement("div");i.className="zoomora-slide-container";const n=document.createElement("div");let o;n.className="zoomora-slide "+("slide"===this.options.transition?"slide-effect":"fade-effect"),n.style.opacity="0",n.style.transform="slide"===this.options.transition?"translateX(100%)":"scale(0.8)";try{switch(e){case"video":if(t.endsWith(".mp4")||t.endsWith(".webm")||t.endsWith(".ogg")){const e=document.createElement("div");e.className="zoomora-video-container",o=document.createElement("video"),o.src=t,o.className="zoomora-video",o.setAttribute("preload","metadata");const n=s.src||s.getAttribute("src");n&&o.setAttribute("poster",n);const a=document.createElement("div");a.className="zoomora-play-button",a.innerHTML='<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>',a.addEventListener("click",()=>{o.play(),a.style.display="none",o.setAttribute("controls","")}),o.addEventListener("ended",()=>{a.style.display="flex"}),e.appendChild(o),e.appendChild(a),i.appendChild(e)}else o=document.createElement("iframe"),o.src=t,o.className="zoomora-video",o.setAttribute("allowfullscreen",""),o.setAttribute("frameborder","0"),i.appendChild(o);break;case"iframe":o=document.createElement("iframe"),o.src=t,o.className="zoomora-iframe",o.setAttribute("frameborder","0"),i.appendChild(o);break;default:o=document.createElement("img"),o.src=t,o.className="zoomora-media",o.alt=s.alt||s.title||"",o.onload=()=>{this.loading.style.display="none",this.checkZoomability(o),this.animateSlideIn(n)},o.onerror=()=>{this.loading.style.display="none",this.animateSlideIn(n)},i.appendChild(o)}n.appendChild(i),this.slidesContainer.innerHTML="",this.slidesContainer.appendChild(n),"image"!==e&&(this.loading.style.display="none",this.animateSlideIn(n))}catch(t){this.loading.style.display="none"}}animateSlideIn(t){t.offsetHeight,t.classList.add("active"),"slide"===this.options.transition?(t.style.transition=`transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`,t.style.transform="translateX(0)",t.style.opacity="1"):(t.style.transition=`transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`,t.style.transform="scale(1)",t.style.opacity="1")}toggleAutoHide(){this.autoHideEnabled=!this.autoHideEnabled;const t=document.getElementById("zoomoraAutoHideBtn");this.autoHideEnabled?(t.classList.add("active"),t.title="Disable Auto-Hide Controls",this.startAutoHideTimer()):(t.classList.remove("active"),t.title="Enable Auto-Hide Controls",this.stopAutoHideTimer(),this.showControls())}handleUserActivity(){this.autoHideEnabled&&(this.showControls(),this.startAutoHideTimer())}startAutoHideTimer(){this.stopAutoHideTimer(),this.autoHideTimeout=setTimeout(()=>{this.hideControls()},this.options.autoHideDelay)}stopAutoHideTimer(){this.autoHideTimeout&&(clearTimeout(this.autoHideTimeout),this.autoHideTimeout=null)}showControls(){this.isControlsVisible||(this.isControlsVisible=!0,this.zoomora.classList.remove("controls-hidden"),this.header&&(this.header.style.transform="translateY(0)",this.header.style.opacity="1"),this.caption&&(this.caption.style.transform="translateX(-50%) translateY(0)",this.caption.style.opacity="1"),this.thumbs&&(this.thumbs.style.transform="translateX(-50%) translateY(0)",this.thumbs.style.opacity="1"),this.prevBtn&&(this.prevBtn.style.transform="translateX(0)",this.prevBtn.style.opacity="1"),this.nextBtn&&(this.nextBtn.style.transform="translateX(0)",this.nextBtn.style.opacity="1"))}hideControls(){this.isControlsVisible&&(this.isControlsVisible=!1,this.zoomora.classList.add("controls-hidden"),this.header&&(this.header.style.transform="translateY(-100%)",this.header.style.opacity="0"),this.caption&&(this.caption.style.transform="translateX(-50%) translateY(100%)",this.caption.style.opacity="0"),this.thumbs&&(this.thumbs.style.transform="translateX(-50%) translateY(100%)",this.thumbs.style.opacity="0"),this.prevBtn&&(this.prevBtn.style.transform="translateX(-100%)",this.prevBtn.style.opacity="0"),this.nextBtn&&(this.nextBtn.style.transform="translateX(100%)",this.nextBtn.style.opacity="0"))}checkZoomability(t){if(!t||!t.naturalWidth||!t.naturalHeight)return;const e=t.getBoundingClientRect(),s=e.width,i=e.height,n=t.naturalWidth,o=t.naturalHeight,a=n>s||o>i,r=n/s,l=o/i,h=Math.max(r,l);t.dataset.zoomRatio=h,t.dataset.naturalWidth=n,t.dataset.naturalHeight=o,t.dataset.renderedWidth=s,t.dataset.renderedHeight=i,a&&h>1.1?t.classList.remove("no-zoom"):t.classList.add("no-zoom")}calculateZoomLevels(t){if(!t||!t.naturalWidth||!t.naturalHeight)return{canZoom:!1,levels:[],currentLevel:0};const e=this.content.getBoundingClientRect(),s=e.width,i=e.height,n=t.naturalWidth,o=t.naturalHeight,a=s/n,r=i/o,l=Math.min(a,r);if(l>=.95)return{canZoom:!1,levels:[],currentLevel:0};const h=[1];1.5*l<=1&&h.push(1.5),2*l<=1&&h.push(2),3*l<=1&&h.push(3);const d=1/l;return d>h[h.length-1]&&h.push(d),{canZoom:h.length>1,levels:h,currentLevel:0,baseScale:l,naturalWidth:n,naturalHeight:o}}updateCounter(){this.options.showCounter&&this.counter&&(this.counter.textContent=`${this.currentIndex+1} / ${this.items.length}`)}updateCaption(){if(!this.caption||!this.items[this.currentIndex])return;const t=this.items[this.currentIndex],e=t.dataset.caption||t.title||"";e?(this.caption.textContent=e,this.caption.style.transform="translateX(-50%) translateY(0)",this.caption.style.opacity="1",this.caption.style.pointerEvents="auto",this.caption.style.transition="opacity 0.3s ease, transform 0.3s ease"):(this.caption.style.transform="translateX(-50%) translateY(100%)",this.caption.style.opacity="0",this.caption.style.pointerEvents="none",this.caption.style.transition="opacity 0.3s ease, transform 0.3s ease")}updateThumbnails(){if(this.options.showThumbnails&&this.thumbs){if(1===this.items.length)return this.caption.classList.add("single-item-thumbnail"),void(this.thumbs.style.display="none");this.caption.classList.remove("single-item-thumbnail"),this.thumbs.style.display="flex",this.thumbs.innerHTML="",this.items.forEach((t,e)=>{const s=document.createElement("div");s.className="zoomora-thumb",e===this.currentIndex&&s.classList.add("active");const i=document.createElement("img"),n=this.getThumbnailSource(t);n&&(i.src=n,i.alt=t.alt||t.title||"",i.onerror=()=>{s.style.display="none"}),s.appendChild(i),s.addEventListener("click",()=>{this.currentIndex=e,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption()}),this.thumbs.appendChild(s)})}}updateNavigation(){const t=document.getElementById("zoomoraPrevBtn"),e=document.getElementById("zoomoraNextBtn");t&&(t.style.display=this.currentIndex>0?"flex":"none"),e&&(e.style.display=this.currentIndex<this.items.length-1?"flex":"none")}updateButtons(){const t=document.getElementById("zoomoraFullscreenBtn"),e=document.getElementById("zoomoraCollapseBtn");t&&e&&(this.isFullscreen?(t.style.display="none",e.style.display="flex"):(t.style.display="flex",e.style.display="none"))}toggleZoom(){const t=this.content.querySelector(".zoomora-media");if(!t||"IMG"!==t.tagName)return;const e=this.calculateZoomLevels(t);if(!e.canZoom)return;t.dataset.zoomLevel||(t.dataset.zoomLevel="0");let s=parseInt(t.dataset.zoomLevel)||0;s++,s>=e.levels.length&&(s=0);const i=e.levels[s];t.dataset.zoomLevel=s.toString(),0===s?(this.isZoomed=!1,this.isDragging=!1,t.classList.remove("dragging"),t.style.transform="",t.style.cursor="pointer",t.classList.remove("zoomed"),this.currentX=0,this.currentY=0,this.currentScale=1):(this.isZoomed=!0,this.currentScale=i,this.currentX=0,this.currentY=0,t.style.transform=`translate(0px, 0px) scale(${i})`,t.style.cursor="grab",t.classList.add("zoomed"))}updateImageTransform(t){if(t)if(1===this.currentScale)t.style.transform="";else{const e=this.currentX/this.currentScale,s=this.currentY/this.currentScale;t.style.transform=`scale(${this.currentScale}) translate(${e}px, ${s}px)`}}toggleFullscreen(){this.isFullscreen?this.exitFullscreen():this.enterFullscreen()}enterFullscreen(){const t=this.zoomora,e=t.requestFullscreen||t.webkitRequestFullscreen||t.mozRequestFullScreen||t.msRequestFullscreen;e?e.call(t).then(()=>{this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()}).catch(t=>{this.fallbackFullscreen()}):this.fallbackFullscreen()}exitFullscreen(){if(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement){const t=document.exitFullscreen||document.webkitExitFullscreen||document.mozCancelFullScreen||document.msExitFullscreen;t?t.call(document).then(()=>{this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()}).catch(t=>{this.fallbackExitFullscreen()}):this.fallbackExitFullscreen()}else this.fallbackExitFullscreen()}fallbackFullscreen(){this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()}fallbackExitFullscreen(){this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()}toggleThumbnails(){if(1!==this.items.length&&(this.thumbnailsVisible=!this.thumbnailsVisible,this.thumbs)){if(this.thumbs.classList.toggle("thumbs-hidden",!this.thumbnailsVisible),!this.caption||!this.items[this.currentIndex])return;const t=this.items[this.currentIndex];(t.dataset.caption||t.title)&&this.thumbs.classList.contains("thumbs-hidden")?(this.caption.style.bottom="20px",this.caption.style.transition="bottom 0.3s ease, transform 0.3s ease"):this.caption.style.bottom="120px"}}startDrag(t){const e=this.content.querySelector(".zoomora-media");if(!e||!this.isZoomed)return;this.isDragging=!0,e.classList.add("dragging"),e.style.cursor="grabbing",this.startX=t.clientX||t.touches&&t.touches[0].clientX||0,this.startY=t.clientY||t.touches&&t.touches[0].clientY||0;const s=window.getComputedStyle(e).transform;if(s&&"none"!==s){const t=new DOMMatrix(s);this.currentX=t.m41,this.currentY=t.m42}else this.currentX=0,this.currentY=0;t.preventDefault()}drag(t){if(!this.isDragging)return;t.preventDefault();const e=this.content.querySelector(".zoomora-media");if(!e)return;const s=t.clientX||t.touches&&t.touches[0].clientX||0,i=t.clientY||t.touches&&t.touches[0].clientY||0,n=s-this.startX,o=i-this.startY;let a=this.currentX+n,r=this.currentY+o;const l=this.content.getBoundingClientRect(),h=e.getBoundingClientRect(),d=Math.max(0,(h.width-l.width)/2),c=Math.max(0,(h.height-l.height)/2);a=d>0?Math.max(-d,Math.min(d,a)):0,r=c>0?Math.max(-c,Math.min(c,r)):0,e.style.transform=`translate(${a}px, ${r}px) scale(${this.currentScale})`,this.startX=s,this.startY=i,this.currentX=a,this.currentY=r}endDrag(){if(!this.isDragging)return;this.isDragging=!1,this.lastDragTime=Date.now();const t=this.content.querySelector(".zoomora-media");t&&(t.classList.remove("dragging"),this.isZoomed&&(t.style.cursor="grab"))}goTo(t){t<0||t>=this.items.length||(this.currentIndex=t,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption())}getCurrentIndex(){return this.currentIndex}getTotalItems(){return this.items.length}isOpen(){return this.zoomora&&this.zoomora.classList.contains("active")}updateOptions(t){this.options=h(h({},this.options),t)}refresh(){if(this.isOpen()){const t=this.items[this.currentIndex];t&&this.open(t)}}destroy(){this.isInitialized&&(this.isOpen()&&this.close(),this.stopAutoHideTimer(),this.eventListeners.forEach((t,e)=>{t.forEach(({element:t,event:e,handler:s,options:i})=>{t&&t.removeEventListener&&t.removeEventListener(e,s,i)})}),this.eventListeners.clear(),this.zoomora&&this.zoomora.parentNode&&this.zoomora.parentNode.removeChild(this.zoomora),this.isInitialized=!1,this.items=[],this.currentIndex=0,this.zoomora=null,this.content=null,this.counter=null,this.thumbs=null,this.loading=null,this.caption=null)}}return t},"object"==typeof module&&"object"==typeof module.exports?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Zoomora=e()});
|
|
9
|
+
t="undefined"!=typeof window?window:void 0,e=function(){class t{static get defaults(){return{selector:"[data-zoomora]",showCounter:!0,showThumbnails:!0,showFullscreen:!0,showZoom:!0,transition:"fade",useHref:!1,maxZoomScale:3,zoomStep:.1,animationDuration:300,closeOnBackgroundClick:!0,onOpen:null,onClose:null,onNext:null,onPrev:null,showAutoHideToggle:!0,autoHideDelay:3e3,autoHideEnabled:!1}}constructor(e={}){this.options=h(h({},t.defaults),e),this.currentIndex=0,this.items=[],this.isZoomed=!1,this.isFullscreen=!1,this.isDragging=!1,this.thumbnailsVisible=!0,this.startX=0,this.startY=0,this.currentX=0,this.currentY=0,this.currentScale=1,this.isInitialized=!1,this.eventListeners=new Map,this.autoHideEnabled=!1,this.autoHideTimeout=null,this.autoHideDelay=3e3,this.isControlsVisible=!0,this.idleTimer=null,this.lastDragTime=0,this.boundMethods={handleDocumentClick:this.handleDocumentClick.bind(this),handleKeydown:this.handleKeydown.bind(this),handleFullscreenChange:this.handleFullscreenChange.bind(this),handleZoomoraClick:this.handleZoomoraClick.bind(this),handleContentClick:this.handleContentClick.bind(this),handleMouseDown:this.handleMouseDown.bind(this),handleMouseMove:this.handleMouseMove.bind(this),handleMouseUp:this.handleMouseUp.bind(this),handleTouchStart:this.handleTouchStart.bind(this),handleTouchMove:this.handleTouchMove.bind(this),handleTouchEnd:this.handleTouchEnd.bind(this)},this.init()}init(){if(!this.isInitialized)try{this.createLightbox(),this.bindEvents(),this.isInitialized=!0}catch(t){}}static bind(e,s={}){const n=(a=h({},s),i(a,o({selector:e,useHref:!0})));var a;return new t(n)}createLightbox(){if(document.getElementById("zoomoraLightbox"))return;const t=`\n <div class="zoomora" id="zoomoraLightbox">\n <div class="zoomora-container">\n <div class="zoomora-header" id="zoomoraHeader">\n <div class="zoomora-counter" id="zoomoraCounter">1 / 1</div>\n <div class="zoomora-controls">\n <button class="zoomora-btn" id="zoomoraThumbnailBtn" title="Toggle Thumbnails">\n <i class="zoomorai-thumbnails"></i>\n </button>\n ${this.options.showAutoHideToggle?'\n <button class="zoomora-btn" id="zoomoraAutoHideBtn" title="Toggle Auto-Hide Controls">\n <i class="zoomorai-controls-off"></i>\n </button>\n ':""}\n <button class="zoomora-btn" id="zoomoraZoomBtn" title="Zoom">\n <i class="zoomorai-zoom"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraFullscreenBtn" title="Fullscreen">\n <i class="zoomorai-expand"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraCollapseBtn" title="Exit Fullscreen" style="display: none;">\n <i class="zoomorai-collapse"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraCloseBtn" title="Close">\n <i class="zoomorai-close"></i>\n </button>\n </div>\n </div>\n \n <div class="zoomora-content" id="zoomoraContent">\n <div class="zoomora-loading" id="zoomoraLoading"></div>\n <div class="zoomora-slides-container" id="zoomoraSlidesContainer"></div>\n </div>\n \n <button class="zoomora-nav prev" id="zoomoraPrevBtn">\n <i class="zoomorai-arrow-left"></i>\n </button>\n <button class="zoomora-nav next" id="zoomoraNextBtn">\n <i class="zoomorai-arrow-right"></i>\n </button>\n \n <div class="zoomora-caption" id="zoomoraCaption"></div>\n <div class="zoomora-thumbnails" id="zoomoraThumbs"></div>\n </div>\n </div>\n `;if(document.body.insertAdjacentHTML("beforeend",t),this.zoomora=document.getElementById("zoomoraLightbox"),this.header=document.getElementById("zoomoraHeader"),this.content=document.getElementById("zoomoraContent"),this.slidesContainer=document.getElementById("zoomoraSlidesContainer"),this.counter=document.getElementById("zoomoraCounter"),this.thumbs=document.getElementById("zoomoraThumbs"),this.loading=document.getElementById("zoomoraLoading"),this.caption=document.getElementById("zoomoraCaption"),this.prevBtn=document.getElementById("zoomoraPrevBtn"),this.nextBtn=document.getElementById("zoomoraNextBtn"),!(this.zoomora&&this.content&&this.counter&&this.thumbs&&this.loading&&this.caption))throw new Error("Failed to create required DOM elements")}bindEvents(){this.addEventListener(document,"click",this.boundMethods.handleDocumentClick),this.addEventListener(document.getElementById("zoomoraCloseBtn"),"click",()=>this.close()),this.addEventListener(document.getElementById("zoomoraPrevBtn"),"click",()=>this.prev()),this.addEventListener(document.getElementById("zoomoraNextBtn"),"click",()=>this.next()),this.addEventListener(document.getElementById("zoomoraZoomBtn"),"click",()=>this.toggleZoom()),this.addEventListener(document.getElementById("zoomoraFullscreenBtn"),"click",()=>this.toggleFullscreen()),this.addEventListener(document.getElementById("zoomoraCollapseBtn"),"click",()=>this.exitFullscreen()),this.addEventListener(document.getElementById("zoomoraThumbnailBtn"),"click",()=>this.toggleThumbnails()),this.addEventListener(document,"fullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"webkitfullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"mozfullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"MSFullscreenChange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"keydown",this.boundMethods.handleKeydown),this.addEventListener(this.zoomora,"click",this.boundMethods.handleZoomoraClick),this.addEventListener(this.content,"click",this.boundMethods.handleContentClick),this.addEventListener(this.content,"mousedown",this.boundMethods.handleMouseDown),this.addEventListener(this.content,"mousemove",this.boundMethods.handleMouseMove),this.addEventListener(this.content,"mouseup",this.boundMethods.handleMouseUp),this.addEventListener(this.content,"mouseleave",this.boundMethods.handleMouseUp),this.addEventListener(this.content,"touchstart",this.boundMethods.handleTouchStart,{passive:!1}),this.addEventListener(this.content,"touchmove",this.boundMethods.handleTouchMove,{passive:!1}),this.addEventListener(this.content,"touchend",this.boundMethods.handleTouchEnd),this.options.showAutoHideToggle&&(this.addEventListener(document.getElementById("zoomoraAutoHideBtn"),"click",()=>this.toggleAutoHide()),this.addEventListener(this.zoomora,"mousemove",()=>this.handleUserActivity()),this.addEventListener(this.zoomora,"touchstart",()=>this.handleUserActivity()),this.addEventListener(this.zoomora,"keydown",()=>this.handleUserActivity()))}addEventListener(t,e,s,i={}){if(!t)return;t.addEventListener(e,s,i);const o=`${t.constructor.name}_${e}`;this.eventListeners.has(o)||this.eventListeners.set(o,[]),this.eventListeners.get(o).push({element:t,event:e,handler:s,options:i})}handleDocumentClick(t){const e=t.target.closest(this.options.selector);e&&(t.preventDefault(),this.open(e))}handleKeydown(t){if(this.zoomora.classList.contains("active"))switch(t.key){case"Escape":this.isFullscreen?this.exitFullscreen():this.close();break;case"ArrowLeft":this.prev();break;case"ArrowRight":this.next();break;case"z":case"Z":this.toggleZoom();break;case"f":case"F":this.toggleFullscreen();break;case"t":case"T":this.toggleThumbnails()}}handleFullscreenChange(){const t=!!(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement);!t&&this.isFullscreen?(this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()):t&&!this.isFullscreen&&(this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons())}handleZoomoraClick(t){t.target===this.zoomora&&this.options.closeOnBackgroundClick&&this.close()}handleContentClick(t){if(Date.now()-this.lastDragTime<200)return;if(this.header&&this.header.contains(t.target))return;if(t.target.closest("button"))return;const e=t.target.closest(".zoomora-media, .zoomora-video, .zoomora-iframe");if(e)return void(e.classList.contains("zoomora-media")&&!e.classList.contains("no-zoom")&&this.toggleZoom());if(t.target.closest(".zoomora-video-container")){if(t.target.closest(".zoomora-play-button"))return;return void(this.options.closeOnBackgroundClick&&this.close())}const s=t.target;((s.classList.contains("zoomora-content")||s.classList.contains("zoomora-slide-container")||s.classList.contains("zoomora-slide")||s.classList.contains("zoomora-slides-container")||"zoomoraContent"===s.id||"zoomoraSlidesContainer"===s.id)&&this.options.closeOnBackgroundClick||this.options.closeOnBackgroundClick)&&this.close()}handleMouseDown(t){this.startDrag(t)}handleMouseMove(t){this.drag(t)}handleMouseUp(){this.endDrag()}handleTouchStart(t){this.startDrag(t)}handleTouchMove(t){this.drag(t)}handleTouchEnd(){this.endDrag()}getImageSource(t){const e=t.dataset.src||t.src||t.getAttribute("src");return"video"===(t.dataset.type||"image")&&e?this.convertToEmbedUrl(e):e}convertToEmbedUrl(t){if(t.includes("youtube.com/embed/"))return t;let e=null,s=null;if(t.includes("youtube.com/watch")){const i=new URLSearchParams(t.split("?")[1]);e=i.get("v");const o=i.get("t");o&&(s=o.replace("s",""))}else if(t.includes("youtu.be/")){const i=t.split("/"),o=i[i.length-1];if(o.includes("?")){e=o.split("?")[0];const t=new URLSearchParams(o.split("?")[1]).get("t");t&&(s=t.replace("s",""))}else e=o}if(e){let t=`https://www.youtube.com/embed/${e}`;const i=new URLSearchParams;return s&&i.append("start",s),i.append("rel","0"),i.append("modestbranding","1"),i.toString()&&(t+="?"+i.toString()),t}return t}getThumbnailSource(t){return"video"===(t.dataset.type||"image")?t.src||t.getAttribute("src"):t.dataset.src||t.src||t.getAttribute("src")}getGroup(t){return this.options.useHref?t.dataset.lightbox||t.dataset.gallery||"default":t.dataset.zoomora||"default"}open(t){if(!t)return;const e=this.getGroup(t);let s;s=this.options.useHref?t.dataset.lightbox?`[data-lightbox="${e}"]`:t.dataset.gallery?`[data-gallery="${e}"]`:this.options.selector:`[data-zoomora="${e}"]`,this.items=Array.from(document.querySelectorAll(s)),this.currentIndex=Math.max(0,this.items.indexOf(t)),this.isZoomed=!1,this.isFullscreen=!1,this.thumbnailsVisible=!0,this.currentX=0,this.currentY=0,this.currentScale=1,this.zoomora.classList.add("active"),document.body.style.overflow="hidden",this.loadContent(),this.updateThumbnails(),this.updateCounter(),this.updateNavigation(),this.updateCaption(),this.updateButtons(),this.autoHideEnabled?this.startAutoHideTimer():this.showControls(),"function"==typeof this.options.onOpen&&this.options.onOpen(t,this.currentIndex)}close(){this.isFullscreen&&this.exitFullscreen(),this.zoomora.classList.remove("active"),document.body.style.overflow="",this.isZoomed=!1,this.isFullscreen=!1,this.currentX=0,this.currentY=0,this.currentScale=1;const t=this.content.querySelector(".zoomora-media");t&&(t.classList.remove("zoomed"),t.style.transform="",t.style.cursor=""),this.zoomora.classList.remove("fullscreen"),this.updateButtons(),this.stopAutoHideTimer(),this.showControls(),"function"==typeof this.options.onClose&&this.options.onClose(this.currentIndex)}prev(){this.currentIndex>0&&(this.currentIndex--,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption(),"function"==typeof this.options.onPrev&&this.options.onPrev(this.currentIndex))}next(){this.currentIndex<this.items.length-1&&(this.currentIndex++,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption(),"function"==typeof this.options.onNext&&this.options.onNext(this.currentIndex))}loadContent(){if(!this.items[this.currentIndex])return;const t=this.items[this.currentIndex],e=this.getImageSource(t),s=t.dataset.type||"image";e&&(this.isZoomed=!1,this.currentX=0,this.currentY=0,this.currentScale=1,this.loading.style.display="block",this.slidesContainer&&(this.slidesContainer.innerHTML=""),setTimeout(()=>{this.renderContent(e,s,t)},100))}renderContent(t,e,s){const i=document.createElement("div");i.className="zoomora-slide-container";const o=document.createElement("div");let n;o.className="zoomora-slide "+("slide"===this.options.transition?"slide-effect":"fade-effect"),o.style.opacity="0",o.style.transform="slide"===this.options.transition?"translateX(100%)":"scale(0.8)";try{switch(e){case"video":if(t.endsWith(".mp4")||t.endsWith(".webm")||t.endsWith(".ogg")){const e=document.createElement("div");e.className="zoomora-video-container",n=document.createElement("video"),n.src=t,n.className="zoomora-video",n.setAttribute("preload","metadata");const o=s.src||s.getAttribute("src");o&&n.setAttribute("poster",o);const a=document.createElement("div");a.className="zoomora-play-button",a.innerHTML='<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>',a.addEventListener("click",()=>{n.play(),a.style.display="none",n.setAttribute("controls","")}),n.addEventListener("ended",()=>{a.style.display="flex"}),e.appendChild(n),e.appendChild(a),i.appendChild(e)}else n=document.createElement("iframe"),n.src=t,n.className="zoomora-video",n.setAttribute("allowfullscreen",""),n.setAttribute("frameborder","0"),i.appendChild(n);break;case"iframe":n=document.createElement("iframe"),n.src=t,n.className="zoomora-iframe",n.setAttribute("frameborder","0"),i.appendChild(n);break;default:n=document.createElement("img"),n.src=t,n.className="zoomora-media",n.alt=s.alt||s.title||"",n.onload=()=>{this.loading.style.display="none",this.checkZoomability(n),this.animateSlideIn(o)},n.onerror=()=>{this.loading.style.display="none",this.animateSlideIn(o)},i.appendChild(n)}o.appendChild(i),this.slidesContainer.innerHTML="",this.slidesContainer.appendChild(o),"image"!==e&&(this.loading.style.display="none",this.animateSlideIn(o))}catch(t){this.loading.style.display="none"}}animateSlideIn(t){t.offsetHeight,t.classList.add("active"),"slide"===this.options.transition?(t.style.transition=`transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`,t.style.transform="translateX(0)",t.style.opacity="1"):(t.style.transition=`transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`,t.style.transform="scale(1)",t.style.opacity="1")}toggleAutoHide(){this.autoHideEnabled=!this.autoHideEnabled;const t=document.getElementById("zoomoraAutoHideBtn");this.autoHideEnabled?(t.classList.add("active"),t.title="Disable Auto-Hide Controls",this.startAutoHideTimer()):(t.classList.remove("active"),t.title="Enable Auto-Hide Controls",this.stopAutoHideTimer(),this.showControls())}handleUserActivity(){this.autoHideEnabled&&(this.showControls(),this.startAutoHideTimer())}startAutoHideTimer(){this.stopAutoHideTimer(),this.autoHideTimeout=setTimeout(()=>{this.hideControls()},this.options.autoHideDelay)}stopAutoHideTimer(){this.autoHideTimeout&&(clearTimeout(this.autoHideTimeout),this.autoHideTimeout=null)}showControls(){this.isControlsVisible||(this.isControlsVisible=!0,this.zoomora.classList.remove("controls-hidden"),this.header&&(this.header.style.transform="translateY(0)",this.header.style.opacity="1"),this.caption&&(this.caption.style.transform="translateX(-50%) translateY(0)",this.caption.style.opacity="1"),this.thumbs&&(this.thumbs.style.transform="translateX(-50%) translateY(0)",this.thumbs.style.opacity="1"),this.prevBtn&&(this.prevBtn.style.transform="translateX(0)",this.prevBtn.style.opacity="1"),this.nextBtn&&(this.nextBtn.style.transform="translateX(0)",this.nextBtn.style.opacity="1"))}hideControls(){this.isControlsVisible&&(this.isControlsVisible=!1,this.zoomora.classList.add("controls-hidden"),this.header&&(this.header.style.transform="translateY(-100%)",this.header.style.opacity="0"),this.caption&&(this.caption.style.transform="translateX(-50%) translateY(100%)",this.caption.style.opacity="0"),this.thumbs&&(this.thumbs.style.transform="translateX(-50%) translateY(100%)",this.thumbs.style.opacity="0"),this.prevBtn&&(this.prevBtn.style.transform="translateX(-100%)",this.prevBtn.style.opacity="0"),this.nextBtn&&(this.nextBtn.style.transform="translateX(100%)",this.nextBtn.style.opacity="0"))}checkZoomability(t){if(!t||!t.naturalWidth||!t.naturalHeight)return;const e=t.getBoundingClientRect(),s=e.width,i=e.height,o=t.naturalWidth,n=t.naturalHeight,a=o>s||n>i,r=o/s,l=n/i,h=Math.max(r,l);t.dataset.zoomRatio=h,t.dataset.naturalWidth=o,t.dataset.naturalHeight=n,t.dataset.renderedWidth=s,t.dataset.renderedHeight=i,a&&h>1.1?t.classList.remove("no-zoom"):t.classList.add("no-zoom")}calculateZoomLevels(t){if(!t||!t.naturalWidth||!t.naturalHeight)return{canZoom:!1,levels:[],currentLevel:0};const e=this.content.getBoundingClientRect(),s=e.width,i=e.height,o=t.naturalWidth,n=t.naturalHeight,a=s/o,r=i/n,l=Math.min(a,r);if(l>=.95)return{canZoom:!1,levels:[],currentLevel:0};const h=[1];1.5*l<=1&&h.push(1.5),2*l<=1&&h.push(2),3*l<=1&&h.push(3);const c=1/l;return c>h[h.length-1]&&h.push(c),{canZoom:h.length>1,levels:h,currentLevel:0,baseScale:l,naturalWidth:o,naturalHeight:n}}updateCounter(){this.options.showCounter&&this.counter&&(this.counter.textContent=`${this.currentIndex+1} / ${this.items.length}`)}updateCaption(){if(!this.caption||!this.items[this.currentIndex])return;const t=this.items[this.currentIndex],e=t.dataset.caption||t.title||"";e?(this.caption.textContent=e,this.caption.style.transform="translateX(-50%) translateY(0)",this.caption.style.opacity="1",this.caption.style.pointerEvents="auto",this.caption.style.transition="opacity 0.3s ease, transform 0.3s ease"):(this.caption.style.transform="translateX(-50%) translateY(100%)",this.caption.style.opacity="0",this.caption.style.pointerEvents="none",this.caption.style.transition="opacity 0.3s ease, transform 0.3s ease")}updateThumbnails(){if(this.options.showThumbnails&&this.thumbs){if(1===this.items.length)return this.caption.classList.add("single-item-thumbnail"),void(this.thumbs.style.display="none");this.caption.classList.remove("single-item-thumbnail"),this.thumbs.style.display="flex",this.thumbs.innerHTML="",this.items.forEach((t,e)=>{const s=document.createElement("div");s.className="zoomora-thumb",e===this.currentIndex&&s.classList.add("active");const i=document.createElement("img"),o=this.getThumbnailSource(t);o&&(i.src=o,i.alt=t.alt||t.title||"",i.onerror=()=>{s.style.display="none"}),s.appendChild(i),s.addEventListener("click",()=>{this.currentIndex=e,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption()}),this.thumbs.appendChild(s)})}}updateNavigation(){const t=document.getElementById("zoomoraPrevBtn"),e=document.getElementById("zoomoraNextBtn");t&&(t.style.display=this.currentIndex>0?"flex":"none"),e&&(e.style.display=this.currentIndex<this.items.length-1?"flex":"none")}updateButtons(){const t=document.getElementById("zoomoraFullscreenBtn"),e=document.getElementById("zoomoraCollapseBtn");t&&e&&(this.isFullscreen?(t.style.display="none",e.style.display="flex"):(t.style.display="flex",e.style.display="none"))}toggleZoom(){const t=this.content.querySelector(".zoomora-media");if(!t||"IMG"!==t.tagName)return;const e=this.calculateZoomLevels(t);if(!e.canZoom)return;t.dataset.zoomLevel||(t.dataset.zoomLevel="0");let s=parseInt(t.dataset.zoomLevel)||0;s++,s>=e.levels.length&&(s=0);const i=e.levels[s];t.dataset.zoomLevel=s.toString(),0===s?(this.isZoomed=!1,this.isDragging=!1,t.classList.remove("dragging"),t.style.transform="",t.style.cursor="pointer",t.classList.remove("zoomed"),this.currentX=0,this.currentY=0,this.currentScale=1):(this.isZoomed=!0,this.currentScale=i,this.currentX=0,this.currentY=0,t.style.transform=`translate(0px, 0px) scale(${i})`,t.style.cursor="grab",t.classList.add("zoomed"))}updateImageTransform(t){if(t)if(1===this.currentScale)t.style.transform="";else{const e=this.currentX/this.currentScale,s=this.currentY/this.currentScale;t.style.transform=`scale(${this.currentScale}) translate(${e}px, ${s}px)`}}toggleFullscreen(){this.isFullscreen?this.exitFullscreen():this.enterFullscreen()}enterFullscreen(){const t=this.zoomora;try{t.requestFullscreen?t.requestFullscreen().then(()=>{this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()}).catch(t=>{this.fallbackFullscreen()}):t.webkitRequestFullscreen?(t.webkitRequestFullscreen(),this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()):t.mozRequestFullScreen?(t.mozRequestFullScreen(),this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()):t.msRequestFullscreen?(t.msRequestFullscreen(),this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()):this.fallbackFullscreen()}catch(t){this.fallbackFullscreen()}}exitFullscreen(){if(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement)try{document.exitFullscreen?document.exitFullscreen().then(()=>{this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()}).catch(t=>{this.fallbackExitFullscreen()}):document.webkitExitFullscreen?(document.webkitExitFullscreen(),this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()):document.mozCancelFullScreen?(document.mozCancelFullScreen(),this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()):document.msExitFullscreen?(document.msExitFullscreen(),this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()):this.fallbackExitFullscreen()}catch(t){this.fallbackExitFullscreen()}else this.fallbackExitFullscreen()}fallbackFullscreen(){this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()}fallbackExitFullscreen(){this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()}toggleThumbnails(){if(1!==this.items.length&&(this.thumbnailsVisible=!this.thumbnailsVisible,this.thumbs)){if(this.thumbs.classList.toggle("thumbs-hidden",!this.thumbnailsVisible),!this.caption||!this.items[this.currentIndex])return;const t=this.items[this.currentIndex];(t.dataset.caption||t.title)&&this.thumbs.classList.contains("thumbs-hidden")?(this.caption.style.bottom="20px",this.caption.style.transition="bottom 0.3s ease, transform 0.3s ease"):this.caption.style.bottom="120px"}}startDrag(t){const e=this.content.querySelector(".zoomora-media");if(!e||!this.isZoomed)return;this.isDragging=!0,e.classList.add("dragging"),e.style.cursor="grabbing",this.startX=t.clientX||t.touches&&t.touches[0].clientX||0,this.startY=t.clientY||t.touches&&t.touches[0].clientY||0;const s=window.getComputedStyle(e).transform;if(s&&"none"!==s){const t=new DOMMatrix(s);this.currentX=t.m41,this.currentY=t.m42}else this.currentX=0,this.currentY=0;t.preventDefault()}drag(t){if(!this.isDragging)return;t.preventDefault();const e=this.content.querySelector(".zoomora-media");if(!e)return;const s=t.clientX||t.touches&&t.touches[0].clientX||0,i=t.clientY||t.touches&&t.touches[0].clientY||0,o=s-this.startX,n=i-this.startY;let a=this.currentX+o,r=this.currentY+n;const l=this.content.getBoundingClientRect(),h=e.getBoundingClientRect(),c=Math.max(0,(h.width-l.width)/2),d=Math.max(0,(h.height-l.height)/2);a=c>0?Math.max(-c,Math.min(c,a)):0,r=d>0?Math.max(-d,Math.min(d,r)):0,e.style.transform=`translate(${a}px, ${r}px) scale(${this.currentScale})`,this.startX=s,this.startY=i,this.currentX=a,this.currentY=r}endDrag(){if(!this.isDragging)return;this.isDragging=!1,this.lastDragTime=Date.now();const t=this.content.querySelector(".zoomora-media");t&&(t.classList.remove("dragging"),this.isZoomed&&(t.style.cursor="grab"))}goTo(t){t<0||t>=this.items.length||(this.currentIndex=t,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption())}getCurrentIndex(){return this.currentIndex}getTotalItems(){return this.items.length}isOpen(){return this.zoomora&&this.zoomora.classList.contains("active")}updateOptions(t){this.options=h(h({},this.options),t)}refresh(){if(this.isOpen()){const t=this.items[this.currentIndex];t&&this.open(t)}}destroy(){this.isInitialized&&(this.isOpen()&&this.close(),this.stopAutoHideTimer(),this.eventListeners.forEach((t,e)=>{t.forEach(({element:t,event:e,handler:s,options:i})=>{t&&t.removeEventListener&&t.removeEventListener(e,s,i)})}),this.eventListeners.clear(),this.zoomora&&this.zoomora.parentNode&&this.zoomora.parentNode.removeChild(this.zoomora),this.isInitialized=!1,this.items=[],this.currentIndex=0,this.zoomora=null,this.content=null,this.counter=null,this.thumbs=null,this.loading=null,this.caption=null)}}return t},"object"==typeof module&&"object"==typeof module.exports?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Zoomora=e()});
|
|
10
10
|
//# sourceMappingURL=zoomora.umd.min.js.map
|