62 lines
2.2 KiB
JavaScript
62 lines
2.2 KiB
JavaScript
// Gallery tab — thumbnails from gallery/manifest.json + full-size lightbox.
|
|
// The manifest is (re)generated by generate_thumbnails.py.
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const container = document.getElementById('gallery-container');
|
|
const lightbox = document.getElementById('lightbox');
|
|
const lightboxImg = document.getElementById('lightbox-img');
|
|
const lightboxVideo = document.getElementById('lightbox-video');
|
|
|
|
if (!container || !lightbox) return;
|
|
|
|
// Animated GIFs are served as MP4 (a few % of the size), so those
|
|
// open in the <video>; everything else in the <img>.
|
|
const openLightbox = (src) => {
|
|
const isVideo = src.endsWith('.mp4');
|
|
lightboxImg.style.display = isVideo ? 'none' : 'block';
|
|
lightboxVideo.style.display = isVideo ? 'block' : 'none';
|
|
if (isVideo) {
|
|
lightboxVideo.src = src;
|
|
lightboxVideo.play().catch(() => {});
|
|
} else {
|
|
lightboxImg.src = src;
|
|
}
|
|
lightbox.style.display = 'block';
|
|
};
|
|
|
|
const closeLightbox = () => {
|
|
lightbox.style.display = 'none';
|
|
lightboxImg.removeAttribute('src');
|
|
// Stop playback and any download still in progress
|
|
lightboxVideo.pause();
|
|
lightboxVideo.removeAttribute('src');
|
|
lightboxVideo.load();
|
|
};
|
|
|
|
// Close on the X, on a click outside the media, or with Escape
|
|
lightbox.addEventListener('click', (e) => {
|
|
if (e.target !== lightboxImg && e.target !== lightboxVideo) closeLightbox();
|
|
});
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && lightbox.style.display === 'block') closeLightbox();
|
|
});
|
|
|
|
const thumbPath = (file) => `gallery/thumbnails/${file.replace(/\.[^.]+$/, '')}.jpg`;
|
|
|
|
fetch('gallery/manifest.json')
|
|
.then(res => {
|
|
if (!res.ok) throw new Error(res.status);
|
|
return res.json();
|
|
})
|
|
.then(files => {
|
|
files.forEach((file, i) => {
|
|
const img = document.createElement('img');
|
|
img.src = thumbPath(file);
|
|
img.alt = `Gallery image ${i + 1}`;
|
|
img.loading = 'lazy';
|
|
img.onclick = () => openLightbox(`gallery/${file}`);
|
|
container.appendChild(img);
|
|
});
|
|
})
|
|
.catch(err => console.error('Could not load gallery manifest:', err));
|
|
});
|