first commit
This commit is contained in:
commit
ebc307fe04
114 changed files with 7748 additions and 0 deletions
185
js/main.js
Normal file
185
js/main.js
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
// Main JavaScript for KH3 Website
|
||||
|
||||
function safeInit(selector, callback) {
|
||||
const el = document.querySelector(selector);
|
||||
if (el) callback(el);
|
||||
}
|
||||
|
||||
function updateYear() {
|
||||
safeInit('#current-year', (el) => {
|
||||
el.textContent = new Date().getFullYear();
|
||||
});
|
||||
}
|
||||
|
||||
// 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", async function () {
|
||||
initDynamicAnimations();
|
||||
initNavigation();
|
||||
initActiveNav();
|
||||
initCustomCursor();
|
||||
initLoadingScreen();
|
||||
loadTeamMembers(); //
|
||||
// Add other initializations here if needed
|
||||
|
||||
updateYear();
|
||||
if (typeof loadIncludes === 'function') {
|
||||
await loadIncludes();
|
||||
// Re-initialize animations for dynamically included content like the footer
|
||||
initDynamicAnimations();
|
||||
}
|
||||
updateYear();
|
||||
});
|
||||
|
||||
// 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() {
|
||||
let currentPath = window.location.pathname.split('/').pop();
|
||||
let currentPage = currentPath ? currentPath.split('?')[0].split('#')[0] : 'index.html';
|
||||
|
||||
document.querySelectorAll('#navMenu a').forEach(link => {
|
||||
let linkPath = link.getAttribute('href').split('/').pop();
|
||||
let linkPage = linkPath ? linkPath : 'index.html';
|
||||
|
||||
if (currentPage === linkPage) {
|
||||
link.classList.add('active');
|
||||
} else {
|
||||
link.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue