Files
2026-10-12 17:18:17 +02:00

127 lines
4.2 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
setupNavigationHighlight();
setupNavigationClicks();
setupCopyright();
setupServiceSections();
setupCards();
});
function setupNavigationHighlight() {
const sections = document.querySelectorAll('.scroll_section');
const navOptions = document.querySelectorAll('.nav_option');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const sectionId = entry.target.id;
window.history.replaceState(null, null, `#${sectionId}`);
navOptions.forEach(link => {
link.classList.toggle('active', link.getAttribute('href') === `#${sectionId}`);
});
}
});
}, {
threshold: 0.5
});
sections.forEach(section => observer.observe(section));
}
function setupNavigationClicks() {
document.querySelectorAll('.nav_option').forEach(link => {
link.addEventListener('click', (event) => {
event.preventDefault();
const targetId = link.getAttribute('href');
const targetSection = document.querySelector(targetId);
if (targetSection) {
targetSection.scrollIntoView({
behavior: 'smooth'
});
}
});
});
}
function setupCopyright() {
document.getElementById('copyright').textContent = `© ${new Date().getFullYear()} - douwco.be`;
}
/* Unified expandable card system, shared by the About Me and My Games grids.
Clicking a card expands it (spanning two grid columns); clicking again or
picking another card in the same grid collapses it. */
function setupCards() {
const cards = document.querySelectorAll('.game-card');
cards.forEach(card => {
card.addEventListener('click', (event) => {
if (event.target.closest('a')) {
return;
}
const grid = card.closest('.games-grid, .about-me-projects-grid');
const isExpanded = card.classList.contains('expanded');
if (grid) {
grid.querySelectorAll('.game-card').forEach(c => c.classList.remove('expanded'));
}
if (!isExpanded) {
card.classList.add('expanded');
}
event.stopPropagation();
});
const playButton = card.querySelector('.play-button');
if (playButton) {
playButton.addEventListener('click', (event) => {
event.stopPropagation();
});
}
});
}
function setupServiceSections() {
document.querySelectorAll('.service-section').forEach(section => {
const items = section.querySelectorAll('.service-selector-item');
const visualImg = section.querySelector('.service-visual-img');
const title = section.querySelector('.service-title');
const description = section.querySelector('.service-description');
const link = section.querySelector('.go-to-app-button');
if (items.length === 0 || !visualImg || !title || !description || !link) return;
let isAnimating = false;
const applyItem = (item) => {
visualImg.src = item.dataset.image;
visualImg.alt = item.dataset.name;
title.textContent = item.dataset.name;
description.textContent = item.dataset.description;
link.href = item.dataset.url;
};
const selectItem = (item) => {
if (isAnimating || item.classList.contains('selected')) return;
isAnimating = true;
items.forEach(i => i.classList.toggle('selected', i === item));
visualImg.classList.add('fading');
setTimeout(() => {
applyItem(item);
requestAnimationFrame(() => {
visualImg.classList.remove('fading');
setTimeout(() => {
isAnimating = false;
}, 300);
});
}, 300);
};
items.forEach(item => {
item.addEventListener('click', () => selectItem(item));
});
});
}