const isStudioPage = window.location.pathname.includes("studio"); const isProjectsPage = window.location.pathname.includes("projects"); const isPlaygroundPage = window.location.pathname.includes("playground"); const isAboutPage = window.location.pathname.includes("about"); document.addEventListener("DOMContentLoaded", function () { setupCustomCursor(); typeHeaderText(); if (isStudioPage) { renderProjectDetails(artworks); } else if(isProjectsPage) { renderProjectDetails(projects); } else if (isPlaygroundPage) { renderProjectDetails(items); } }); // Custom cursor function setupCustomCursor() { // Check if the device supports hover if (window.matchMedia('(hover: hover) and (pointer: fine)').matches) { const cursor = document.querySelector('.custom-cursor'); const cursorElements = document.querySelectorAll('.cursor-element'); const artworkGrid = document.getElementById('artworkGrid'); document.addEventListener('mousemove', function (e) { cursor.style.top = e.clientY + 'px'; cursor.style.left = e.clientX + 'px'; }); cursorElements.forEach(function (e) { e.addEventListener('mouseenter', function () { cursor.classList.add('hovering'); }); e.addEventListener('mouseleave', function () { cursor.classList.remove('hovering'); }); }); if (isStudioPage && artworkGrid) { artworkGrid.addEventListener('mouseenter', function () { cursor.classList.add('artwork-hover-active'); }); artworkGrid.addEventListener('mouseleave', function () { cursor.classList.remove('artwork-hover-active'); }); } } else { // If not a device with hover support, ensure the custom cursor is hidden const cursor = document.querySelector('.custom-cursor'); if (cursor) { cursor.style.display = 'none'; } } } // Typing effect in header function typeHeaderText() { const headerText = document.querySelector('header a h1'); const texts = ['Ella Tang', '< 佳 韵 />']; let currTextIdx = 0, idx = 0, isDeleting = false; function typeEffect() { const curr = texts[currTextIdx]; headerText.textContent = curr.substring(0, idx); if (!isDeleting && idx < curr.length) { idx++; } else if (isDeleting && idx > 0) { idx--; } else { isDeleting = !isDeleting; if (!isDeleting) currTextIdx = (currTextIdx + 1) % texts.length; setTimeout(typeEffect, isDeleting ? 1500 : 1000); return; } setTimeout(typeEffect, isDeleting ? 150 : 200); } typeEffect(); } // Opening animation on page load window.addEventListener('load', function () { // Trigger the opening fade-in effect document.querySelector('.opening-container .fade-in').classList.add('visible'); // Slide up and hide the opening animation container after it completes setTimeout(function () { const openingContainer = document.querySelector('.opening-container'); openingContainer.style.animation = 'slideUp 1.5s ease forwards'; // Hide main content initially, then reveal it after animation setTimeout(function() { document.querySelector('.opening-container').style.display = 'none'; document.querySelector('.main-container').classList.remove('hidden'); // Trigger fade-in for elements after the opening animation const fadeInElements = document.querySelectorAll(".fade-in, .fade-in-up, .fade-in-down, .fade-in-left, .fade-in-right"); fadeInElements.forEach(function (element) { element.classList.add("visible"); }); openingContainer.style.display = 'none'; document.querySelector('.main-container').classList.remove('hidden'); }, 1000); // Delay matches slide-up animation duration }, 1000); // Delay matches opening fade-in animation duration }); // Update button active/inactive styles function updateFilterBtn(category) { const buttons = document.querySelectorAll('.filters button'); buttons.forEach(function(button) { const buttonCategory = button.getAttribute('data-category') || button.innerText.toLowerCase(); if (category === 'all' && buttonCategory === 'all' || buttonCategory === category) { button.classList.add('active'); button.classList.remove('inactive'); } else { button.classList.remove('active'); button.classList.add('inactive'); } }); } // Artwork detail function renderProjectDetails(dataArray) { // Extract project identifier from URL (folder name before 'index.html') const urlParts = window.location.pathname.split('/'); const projectIdentifier = urlParts[urlParts.length - 2]; // Gets 'inner-beast' from the URL // Find the project that matches the URL identifier const project = dataArray.find(item => item.link.includes(projectIdentifier)); // Render project details if a matching project is found if (project) { // Check if elements exist before updating content const titleElement = document.querySelector('.project-title'); const dateElement = document.querySelector('.project-date'); const descriptionElement = document.querySelector('.project-description'); const imageElement = document.querySelector('.artwork-image img'); const paragraphElement = document.querySelector('.artwork-paragraph'); const numberElement = document.querySelector('.project-number'); if (titleElement) titleElement.textContent = project.title; if (dateElement) dateElement.textContent = project.date; if (descriptionElement) descriptionElement.textContent = project.description || "No description available."; if (imageElement) { imageElement.src = project.image; imageElement.alt = project.title; } if (paragraphElement) paragraphElement.innerHTML = project.paragraph || "Additional details will be added soon."; if (numberElement) numberElement.textContent = `00${dataArray.indexOf(project) + 1}`; // Format project number } }