kh3_site_fixed/js/main.js
2026-02-11 19:37:15 +00:00

169 lines
No EOL
6 KiB
JavaScript

// Main JavaScript for KH3 Website
// This function will handle all animations defined by data-attributes in the HTML
function initDynamicAnimations() {
const animatedElements = document.querySelectorAll("[data-anim]");
animatedElements.forEach((el) => {
const delay = el.getAttribute("data-anim-delay") || "0";
el.style.animationDelay = `${delay}ms`;
// CORRECTED: Adds the required 'animate-' prefix for Tailwind to recognize the animation
el.classList.add(`animate-${el.getAttribute('data-anim')}`);
el.style.animationFillMode = 'forwards'; // Ensure animation state persists after it runs
});
}
// Navigation functionality
function initNavigation() {
const menuToggle = document.getElementById("menuToggle");
const navMenu = document.getElementById("navMenu");
const menuGrid = document.getElementById("menuGrid");
const navLinks = document.querySelectorAll(".nav-link");
if (menuToggle && navMenu && menuGrid) {
let isMenuOpen = false;
const menuPetal = document.getElementById("menuPetal");
const menuWrap = document.getElementById("menuWrap");
if (menuWrap) menuWrap.classList.remove("open");
menuToggle.addEventListener("click", () => {
isMenuOpen = !isMenuOpen; // Toggle the state
navMenu.classList.toggle("hidden");
if (menuWrap) menuWrap.classList.toggle("open");
});
document.addEventListener("click", (e) => {
if (isMenuOpen && !menuToggle.contains(e.target) && !navMenu.contains(e.target)) {
navMenu.classList.add("hidden");
if (menuWrap) menuWrap.classList.remove("open");
isMenuOpen = false;
}
});
navLinks.forEach((link) => {
link.addEventListener("click", () => {
navMenu.classList.add("hidden");
if (menuWrap) menuWrap.classList.remove("open");
isMenuOpen = false;
});
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && isMenuOpen) {
navMenu.classList.add("hidden");
if (menuWrap) menuWrap.classList.remove("open");
isMenuOpen = false;
}
});
}
}
// Custom cursor
function initCustomCursor() {
if (window.innerWidth <= 768) return;
const cursor = document.getElementById("customCursor");
if (!cursor) return;
document.addEventListener("mousemove", (e) => {
cursor.style.left = e.clientX - 12 + "px";
cursor.style.top = e.clientY - 12 + "px";
});
}
// Loading screen
function initLoadingScreen() {
const loadingScreen = document.getElementById("loadingScreen");
if (loadingScreen) {
setTimeout(() => {
loadingScreen.style.opacity = "0";
setTimeout(() => {
loadingScreen.style.display = "none";
}, 500);
}, 1000);
}
}
// --- Main Execution ---
document.addEventListener("DOMContentLoaded", function () {
initDynamicAnimations();
initNavigation();
initActiveNav();
initCustomCursor();
initLoadingScreen();
loadTeamMembers(); //
// Add other initializations here if needed
document.getElementById('current-year').textContent = new Date().getFullYear();
});
// Handle back/forward navigation cache
window.addEventListener('pageshow', function (event) {
if (event.persisted) {
// Page was loaded from cache, so we reload to ensure scripts run correctly
window.location.reload();
}
});
// NEW: Function to load team members from JSON
async function loadTeamMembers() {
const container = document.getElementById('teamGridContainer');
// Only run this function if the container exists on the current page (i.e., on who.html)
if (!container) {
return;
}
try {
const response = await fetch('data/team.json');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const teamMembers = await response.json();
const teamHTML = teamMembers.map((member, index) => {
// Create the HTML for each team member card
return `
<div class="group relative team-card opacity-0" data-anim="fade-in-up" data-anim-delay="${200 + index * 100}">
<div class="bg-kh3-grey/20 p-8 rounded-lg hover:bg-kh3-grey/30 transition-all duration-500 transform hover:scale-105 hover:-translate-y-2">
<div class="w-48 h-64 bg-gradient-to-br from-kh3-red/20 to-kh3-grey/40 rounded-lg mx-auto mb-6 flex items-center justify-center overflow-hidden group-hover:shadow-lg group-hover:shadow-red-500/20 transition-all duration-500">
<img src="${member.image}" alt="${member.name.join(' ')}" class="w-full h-full object-cover rounded-lg transition-all duration-500 group-hover:scale-110" />
</div>
<div class="text-center">
<h3 class="text-2xl font-bold text-white mb-2 transition-all duration-300 group-hover:text-kh3-red group-hover:scale-105">
${member.name.join('<br>')}
</h3>
<p class="text-kh3-red font-medium transition-all duration-300 group-hover:text-red-400">
${member.title}
</p>
</div>
</div>
</div>
`;
}).join('');
container.innerHTML = teamHTML;
// After adding the cards to the DOM, re-run the animation initializer to apply the staggered delays
initDynamicAnimations();
} catch (error) {
console.error("Could not load team members:", error);
container.innerHTML = `<p class="text-center text-kh3-red col-span-full">Failed to load team members. Please try again later.</p>`;
}
}
function initActiveNav() {
const currentPage = window.location.pathname.split('/').pop();
const navLinks = document.querySelectorAll('#navMenu a');
navLinks.forEach(link => {
const linkPage = link.getAttribute('href').split('/').pop();
// Handle the index page case where the path might be empty
if (currentPage === '' && (linkPage === 'index.html' || linkPage === '')) {
link.classList.add('active');
}
// Handle other pages
else if (linkPage !== '' && currentPage === linkPage) {
link.classList.add('active');
}
});
}