2026-04-23 10:05:35 +00:00

123 lines
5.0 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
const toastElement = document.getElementById('pageToast');
const toastBody = document.getElementById('pageToastBody');
const pageToast = toastElement ? new bootstrap.Toast(toastElement, { delay: 2200 }) : null;
const showToast = (message) => {
if (!pageToast || !toastBody || !message) return;
toastBody.textContent = message;
pageToast.show();
};
document.querySelectorAll('[data-toast-message]').forEach((link) => {
link.addEventListener('click', () => showToast(link.getAttribute('data-toast-message')));
});
const revealItems = document.querySelectorAll('.reveal');
if ('IntersectionObserver' in window && revealItems.length) {
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
revealObserver.unobserve(entry.target);
}
});
}, { threshold: 0.16 });
revealItems.forEach((item) => revealObserver.observe(item));
} else {
revealItems.forEach((item) => item.classList.add('is-visible'));
}
const filterButtons = document.querySelectorAll('.btn-filter');
const galleryItems = document.querySelectorAll('.gallery-item');
const filterStatus = document.getElementById('filterStatus');
filterButtons.forEach((button) => {
button.addEventListener('click', () => {
const filter = button.dataset.filter || 'all';
filterButtons.forEach((btn) => btn.classList.remove('active'));
button.classList.add('active');
let visibleCount = 0;
galleryItems.forEach((item) => {
const matches = filter === 'all' || item.dataset.era === filter;
item.classList.toggle('is-hidden', !matches);
if (matches) visibleCount += 1;
});
const statusText = filter === 'all'
? `Showing all ${visibleCount} images.`
: `Showing ${visibleCount} ${filter} image${visibleCount === 1 ? '' : 's'}.`;
if (filterStatus) filterStatus.textContent = statusText;
showToast(statusText);
});
});
const galleryModal = document.getElementById('galleryModal');
if (galleryModal) {
const modalLabel = document.getElementById('galleryModalLabel');
const modalMeta = document.getElementById('galleryModalMeta');
const modalImage = document.getElementById('galleryModalImage');
const modalCaption = document.getElementById('galleryModalCaption');
galleryModal.addEventListener('show.bs.modal', (event) => {
const trigger = event.relatedTarget;
if (!trigger) return;
const title = trigger.getAttribute('data-title') || 'Gallery image';
const eraLabel = trigger.getAttribute('data-era-label') || 'Archive';
const year = trigger.getAttribute('data-year') || '';
const caption = trigger.getAttribute('data-caption') || '';
const image = trigger.getAttribute('data-image') || '';
const alt = trigger.getAttribute('data-alt') || title;
if (modalLabel) modalLabel.textContent = title;
if (modalMeta) modalMeta.textContent = `${eraLabel} · ${year}`;
if (modalCaption) modalCaption.textContent = caption;
if (modalImage) {
modalImage.src = image;
modalImage.alt = alt;
}
});
}
const sections = document.querySelectorAll('main section[id]');
const navLinks = document.querySelectorAll('#mainNav .nav-link');
const setActiveLink = () => {
let currentId = '';
sections.forEach((section) => {
const top = section.getBoundingClientRect().top;
if (top <= 140) currentId = section.id;
});
navLinks.forEach((link) => {
const href = link.getAttribute('href');
link.classList.toggle('active', href === `#${currentId}`);
});
};
setActiveLink();
document.addEventListener('scroll', setActiveLink, { passive: true });
const parallaxItems = document.querySelectorAll('[data-parallax]');
if (parallaxItems.length && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
const updateParallax = () => {
parallaxItems.forEach((item) => {
const rect = item.getBoundingClientRect();
const centerOffset = (window.innerHeight * 0.5 - rect.top) / window.innerHeight;
const depth = item.dataset.parallax === 'media' ? 16 : 10;
const translateY = Math.max(-depth, Math.min(depth, centerOffset * depth));
item.style.transform = `translate3d(0, ${translateY}px, 0)`;
});
};
updateParallax();
window.addEventListener('scroll', updateParallax, { passive: true });
window.addEventListener('resize', updateParallax);
}
});