-
-
Save ManojKiranA/0a0885581c26211fd627a3e8aa0e32c3 to your computer and use it in GitHub Desktop.
Simple ImageLightbox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ImageLightbox { | |
constructor(options = {}) { | |
// Configuration | |
this.config = { | |
autoMode: false, // Set to true for automatic mode, false for explicit only | |
selectors: [ | |
'img.lightbox-trigger', | |
'img[data-lightbox]', | |
'img.lightbox-enabled' | |
], | |
...options | |
}; | |
this.images = []; | |
this.currentIndex = 0; | |
this.lightbox = null; | |
this.lightboxImg = null; | |
this.init(); | |
} | |
init() { | |
this.createLightboxHTML(); | |
this.addStyles(); | |
this.attachEvents(); | |
this.scanImages(); | |
} | |
createLightboxHTML() { | |
this.lightbox = document.createElement('div'); | |
this.lightbox.id = 'js-lightbox'; | |
this.lightbox.innerHTML = ` | |
<div class="lightbox-content"> | |
<button class="close-btn" id="lightbox-close">×</button> | |
<button class="nav-btn prev-btn" id="lightbox-prev">‹</button> | |
<button class="nav-btn next-btn" id="lightbox-next">›</button> | |
<img id="lightbox-img" src="" alt=""> | |
<div class="image-counter" id="lightbox-counter"></div> | |
</div> | |
`; | |
document.body.appendChild(this.lightbox); | |
this.lightboxImg = document.getElementById('lightbox-img'); | |
} | |
addStyles() { | |
const style = document.createElement('style'); | |
style.textContent = ` | |
#js-lightbox { | |
display: none; | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
background-color: rgba(0, 0, 0, 0.9); | |
z-index: 10000; | |
opacity: 0; | |
transition: opacity 0.3s ease; | |
justify-content: center; | |
align-items: center; | |
} | |
#js-lightbox.active { | |
display: flex; | |
opacity: 1; | |
} | |
#js-lightbox .lightbox-content { | |
position: relative; | |
max-width: 90%; | |
max-height: 90%; | |
transform: scale(0.8); | |
transition: transform 0.3s ease; | |
} | |
#js-lightbox.active .lightbox-content { | |
transform: scale(1); | |
} | |
#js-lightbox img { | |
width: 100%; | |
height: auto; | |
max-width: 100%; | |
max-height: 90vh; | |
object-fit: contain; | |
border-radius: 8px; | |
} | |
#js-lightbox .close-btn { | |
position: absolute; | |
top: -40px; | |
right: 0; | |
background: none; | |
border: none; | |
color: white; | |
font-size: 30px; | |
cursor: pointer; | |
width: 40px; | |
height: 40px; | |
border-radius: 50%; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
transition: background-color 0.3s ease; | |
} | |
#js-lightbox .close-btn:hover { | |
background-color: rgba(255, 255, 255, 0.2); | |
} | |
#js-lightbox .nav-btn { | |
position: absolute; | |
top: 50%; | |
transform: translateY(-50%); | |
background: rgba(255, 255, 255, 0.2); | |
border: none; | |
color: white; | |
font-size: 24px; | |
cursor: pointer; | |
width: 50px; | |
height: 50px; | |
border-radius: 50%; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
transition: background-color 0.3s ease; | |
} | |
#js-lightbox .nav-btn:hover { | |
background-color: rgba(255, 255, 255, 0.4); | |
} | |
#js-lightbox .prev-btn { | |
left: -70px; | |
} | |
#js-lightbox .next-btn { | |
right: -70px; | |
} | |
#js-lightbox .image-counter { | |
position: absolute; | |
bottom: -40px; | |
left: 50%; | |
transform: translateX(-50%); | |
color: white; | |
font-size: 14px; | |
background: rgba(0,0,0,0.5); | |
padding: 5px 10px; | |
border-radius: 15px; | |
} | |
@media (max-width: 768px) { | |
#js-lightbox .nav-btn { | |
width: 40px; | |
height: 40px; | |
font-size: 20px; | |
} | |
#js-lightbox .prev-btn { | |
left: 10px; | |
top: 20px; | |
transform: none; | |
} | |
#js-lightbox .next-btn { | |
right: 10px; | |
top: 20px; | |
transform: none; | |
} | |
#js-lightbox .close-btn { | |
top: 10px; | |
right: 50%; | |
transform: translateX(50%); | |
} | |
} | |
img.lightbox-enabled { | |
cursor: pointer; | |
transition: transform 0.3s ease, box-shadow 0.3s ease; | |
} | |
img.lightbox-enabled:hover { | |
transform: scale(1.05); | |
box-shadow: 0 8px 25px rgba(0,0,0,0.3); | |
} | |
`; | |
document.head.appendChild(style); | |
} | |
scanImages() { | |
if (this.config.autoMode) { | |
// AUTOMATIC MODE: All images get lightbox | |
const allImages = document.querySelectorAll('img'); | |
this.images = Array.from(allImages); | |
} else { | |
// EXPLICIT MODE: Only images with specific classes/attributes | |
const selector = this.config.selectors.join(', '); | |
const explicitImages = document.querySelectorAll(selector); | |
this.images = Array.from(explicitImages); | |
} | |
// Add click events and styling to selected images | |
this.images.forEach((img, index) => { | |
img.classList.add('lightbox-enabled'); | |
img.addEventListener('click', (e) => { | |
e.preventDefault(); | |
this.openLightbox(index); | |
}); | |
}); | |
} | |
attachEvents() { | |
document.getElementById('lightbox-close').addEventListener('click', () => this.closeLightbox()); | |
this.lightbox.addEventListener('click', (e) => { | |
if (e.target === this.lightbox) { | |
this.closeLightbox(); | |
} | |
}); | |
document.getElementById('lightbox-prev').addEventListener('click', () => this.prevImage()); | |
document.getElementById('lightbox-next').addEventListener('click', () => this.nextImage()); | |
document.addEventListener('keydown', (e) => { | |
if (!this.lightbox.classList.contains('active')) return; | |
switch(e.key) { | |
case 'Escape': | |
this.closeLightbox(); | |
break; | |
case 'ArrowLeft': | |
this.prevImage(); | |
break; | |
case 'ArrowRight': | |
this.nextImage(); | |
break; | |
} | |
}); | |
} | |
openLightbox(index) { | |
this.currentIndex = index; | |
this.updateImage(); | |
this.lightbox.style.display = 'flex'; | |
setTimeout(() => { | |
this.lightbox.classList.add('active'); | |
}, 10); | |
document.body.style.overflow = 'hidden'; | |
} | |
closeLightbox() { | |
this.lightbox.classList.remove('active'); | |
setTimeout(() => { | |
this.lightbox.style.display = 'none'; | |
document.body.style.overflow = ''; | |
}, 300); | |
} | |
updateImage() { | |
const currentImg = this.images[this.currentIndex]; | |
this.lightboxImg.src = currentImg.src; | |
this.lightboxImg.alt = currentImg.alt || ''; | |
document.getElementById('lightbox-counter').textContent = `${this.currentIndex + 1} / ${this.images.length}`; | |
const prevBtn = document.getElementById('lightbox-prev'); | |
const nextBtn = document.getElementById('lightbox-next'); | |
if (this.images.length > 1) { | |
prevBtn.style.display = 'flex'; | |
nextBtn.style.display = 'flex'; | |
} else { | |
prevBtn.style.display = 'none'; | |
nextBtn.style.display = 'none'; | |
} | |
} | |
prevImage() { | |
this.currentIndex = this.currentIndex > 0 ? this.currentIndex - 1 : this.images.length - 1; | |
this.updateImage(); | |
} | |
nextImage() { | |
this.currentIndex = this.currentIndex < this.images.length - 1 ? this.currentIndex + 1 : 0; | |
this.updateImage(); | |
} | |
addImage(imgElement) { | |
if (!this.images.includes(imgElement)) { | |
this.images.push(imgElement); | |
imgElement.classList.add('lightbox-enabled'); | |
imgElement.addEventListener('click', (e) => { | |
e.preventDefault(); | |
this.openLightbox(this.images.indexOf(imgElement)); | |
}); | |
} | |
} | |
refresh() { | |
this.images = []; | |
this.scanImages(); | |
} | |
// Public method to toggle auto mode | |
setAutoMode(enabled) { | |
this.config.autoMode = enabled; | |
this.refresh(); | |
} | |
} | |
// Initialize with configuration | |
if (document.readyState === 'loading') { | |
document.addEventListener('DOMContentLoaded', () => { | |
// CONFIGURATION - Change autoMode here | |
window.imageLightbox = new ImageLightbox({ | |
autoMode: false // Set to true for automatic, false for explicit only | |
}); | |
}); | |
} else { | |
window.imageLightbox = new ImageLightbox({ | |
autoMode: false // Set to true for automatic, false for explicit only | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- These will have lightbox --> | |
<img src="image1.jpg" class="lightbox-trigger" alt="Image 1"> | |
<img src="image2.jpg" data-lightbox alt="Image 2"> | |
<img src="image3.jpg" class="lightbox-enabled" alt="Image 3"> | |
<!-- These will NOT have lightbox --> | |
<img src="logo.jpg" alt="Logo"> | |
<img src="icon.png" alt="Icon"> | |
<script> | |
// Explicit mode (default) | |
window.imageLightbox = new ImageLightbox({ autoMode: false }); | |
// Automatic mode | |
window.imageLightbox = new ImageLightbox({ autoMode: true }); | |
// Switch to automatic mode | |
window.imageLightbox.setAutoMode(true); | |
// Switch to explicit mode | |
window.imageLightbox.setAutoMode(false); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment