Simple Lightbox
This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/480727/1285876/LighboxModern.js
class LightboxModern { _swipeStartX = null; _swipeStartY = null; _swipeEndX = null; _swipeEndY = null; _clickTimeStart = null; _clickTimeEnd = null; // Tentukan threshold untuk dianggap sebagai swipe _THRESHOLD = 20; _CLICK_TIME_THRESHOLD = 100; _currentImage = null; _progress = 1 _idFadeOutTool = null; constructor(container, { images = [] } = {}) { this.container = container; this.container.classList.add("LightboxModern", "FadeIn") this.container.innerHTML = "" this.progress = this._renderProgress(); this.container.append(this.progress); this.images = images const imagesContainer = this._renderListImage(images); this.container.append(imagesContainer) this._updateProgress() // this.swiper = this._SwipeListener() // this.container.append(this.swiper) this.tool = this._RenderTool() this.container.append(this.tool) } _renderListImage(images) { const container = document.createElement("div"); container.classList.add("ImagesContainer"); this._listenSwipe(container) for(const index in images) { const wrapper = document.createElement("div"); wrapper.classList.add("ImageWrapper"); if(index == 0) { wrapper.classList.add("FadeIn") this._currentImage = wrapper; } const imgElement = document.createElement("img"); imgElement.src = images[index]; imgElement.alt = `Images Number ${index + 1}`; const padding = document.createElement("div") padding.classList.add("ImagePadding"); wrapper.append(imgElement, padding) container.append(wrapper) } return container; } _renderProgress() { const container = document.createElement("div"); container.classList.add("Progress"); return container; } _updateProgress() { this.progress.style.width = `${Math.floor(this._progress / this.images.length * 100)}%` } _SwipeListener() { const container = document.createElement("div"); container.classList.add("Swiper") _listenSwipe return container; } _listenSwipe(element) { element.addEventListener("touchstart", (e) => { this._clickTimeStart = new Date().getTime() this._swipeStartX = e.touches[0].clientX; this._swipeStartY = e.touches[0].clientY; }) element.addEventListener("touchmove", (e) => { if(e.touches.length === 1) { e.preventDefault(); // Mencegah scroll selama swipe this._swipeEndX = e.touches[0].clientX; this._swipeEndY = e.touches[0].clientY; } }) element.addEventListener("touchend", (e) => { this._clickTimeEnd = new Date().getTime() this._detectSwipe() }) } _RenderTool() { const container = document.createElement("div"); container.classList.add("LightboxTool") this._listenSwipe(container) const header = document.createElement("div"); header.classList.add("ToolHeader") const closeButton = document.createElement("button") closeButton.classList.add("btn") closeButton.innerText = "Close" closeButton.addEventListener("click", () => { this.container.classList.remove("FadeIn") }) const fullScreenButton = document.createElement("button") fullScreenButton.classList.add("btn") fullScreenButton.innerText = "[ ]" fullScreenButton.onclick = () => { if(document.fullscreenElement) { document.exitFullscreen() } else { document.documentElement.requestFullscreen() } } header.append(fullScreenButton, closeButton) const footer = document.createElement("div") footer.classList.add("ToolFooter") const downloadImage = document.createElement("button") downloadImage.classList.add("btn") downloadImage.innerText = "Download Image" downloadImage.onclick = () => this.downloadImage(this._currentImage.querySelector("img").src) const downloadAllImage = document.createElement("button") downloadAllImage.classList.add("btn") downloadAllImage.innerText = "Download All Image" downloadAllImage.onclick = () => { downloadAllImage.disabled = true; for(const image of this.images) { this.downloadImage(image) } downloadAllImage.disabled = false; } footer.append(downloadImage, downloadAllImage) container.append(header, footer); container.addEventListener("click", () => { container.classList.toggle("FadeIn") }) return container } _fadeOutImage() { if(this._currentImage) this._currentImage.classList.remove("FadeIn") } _nextImage() { const nextElement = this._currentImage.nextElementSibling; this._fadeOutImage(); if( nextElement ) { nextElement.classList.add("FadeIn") this._currentImage = nextElement; this._progress += 1 } else { const currentImage = this.container.querySelector(".ImagesContainer .ImageWrapper"); currentImage.classList.add("FadeIn") this._currentImage = currentImage; this._progress = 1 } } _prevImage() { const prevElement = this._currentImage.previousElementSibling; this._fadeOutImage() if(prevElement) { prevElement.classList.add("FadeIn") this._currentImage = prevElement; this._progress -= 1 } else { const currentImage = this.container.querySelector(".ImagesContainer").lastElementChild currentImage.classList.add("FadeIn") this._currentImage = currentImage; this._progress = this.images.length } } _detectSwipe() { const deltaX = this._swipeEndX - this._swipeStartX; const deltaY = this._swipeEndY - this._swipeStartY; const deltaTime = this._clickTimeEnd - this._clickTimeStart if((Math.abs(deltaX) > this._THRESHOLD || Math.abs(deltaY) > this._THRESHOLD) && deltaTime > this._CLICK_TIME_THRESHOLD) { if(deltaX > 0) { this._prevImage(); } else { this._nextImage(); } this._updateProgress() } else if(deltaTime < this._CLICK_TIME_THRESHOLD ) { this.tool.classList.toggle("FadeIn") if(this._idFadeOutTool) clearTimeout(this._idFadeOutTool) this._idFadeOutTool = setTimeout(() => this.tool.classList.remove("FadeIn") , 1500) } else { console.log('Tidak ada swipe yang terdeteksi.'); } } downloadImage(url) { const link = document.createElement("a") link.href = url link.click() } }