// Global variables let contactModal = null; let handleModalClick = null; let handleEscapeKey = null; let scrollHandler = null; // Function to open contact modal function openContactModal() { console.log('Opening contact modal'); if (contactModal) { contactModal.classList.remove('hidden'); contactModal.classList.add('flex'); document.body.style.overflow = 'hidden'; } } // Function to close contact modal function closeContactModal() { console.log('Closing contact modal'); if (contactModal) { contactModal.classList.add('hidden'); contactModal.classList.remove('flex'); document.body.style.overflow = 'auto'; } } // Smooth scroll function for anchor links function smoothScrollToSection(targetId) { console.log('Scrolling to:', targetId); const targetElement = document.querySelector(targetId); if (targetElement) { const headerHeight = 80; const elementPosition = targetElement.offsetTop - headerHeight; window.scrollTo({ top: elementPosition, behavior: 'smooth' }); } } // Improved scroll animation function function initSimpleScrollAnimations() { console.log('๐ŸŽฌ Starting scroll animations...'); // Function to check if element is currently in viewport function isElementInViewport(el) { const rect = el.getBoundingClientRect(); const windowHeight = window.innerHeight || document.documentElement.clientHeight; const windowWidth = window.innerWidth || document.documentElement.clientWidth; return ( rect.top < windowHeight * 0.8 && rect.bottom > windowHeight * 0.1 && rect.left < windowWidth && rect.right > 0 ); } // Function to check if element is in hero section function isInHeroSection(el) { const heroSection = document.getElementById('seud6t9'); if (!heroSection) return false; return heroSection.contains(el); } // Function to animate elements on scroll scrollHandler = function() { const elements = document.querySelectorAll('.scroll-animate:not(.animated)'); elements.forEach((element) => { // Skip hero elements - they're handled separately if (isInHeroSection(element)) { return; } if (isElementInViewport(element)) { console.log(`โœจ Animating scroll element: ${element.tagName}`); const delay = parseInt(element.dataset.delay) || 0; setTimeout(() => { element.style.opacity = '1'; element.style.transform = 'translateY(0) translateX(0) scale(1)'; element.classList.add('animated'); }, delay); } }); // Check if we're done with all non-hero elements const remainingElements = document.querySelectorAll('.scroll-animate:not(.animated)'); const nonHeroRemaining = Array.from(remainingElements).filter(el => !isInHeroSection(el)); if (nonHeroRemaining.length === 0) { console.log('โœ… All scroll elements animated, removing scroll listener'); window.removeEventListener('scroll', scrollHandler); window.removeEventListener('resize', scrollHandler); } }; // Set initial styles for all scroll-animate elements const allElements = document.querySelectorAll('.scroll-animate'); console.log(`Found ${allElements.length} elements to animate`); allElements.forEach((element, index) => { const animation = element.dataset.animation || 'fade-in-up'; const isHero = isInHeroSection(element); if (isHero) { // Hero elements: animate immediately without fully hiding console.log(`๐Ÿ  Hero element ${index + 1}:`, element.tagName); const delay = parseInt(element.dataset.delay) || 0; // Set up transition element.style.transition = 'all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94)'; element.style.willChange = 'opacity, transform'; // Start with slight transparency and minimal transform element.style.opacity = '0.3'; switch(animation) { case 'fade-in-left': element.style.transform = 'translateX(-20px)'; break; case 'fade-in-right': element.style.transform = 'translateX(20px)'; break; case 'fade-in-up': element.style.transform = 'translateY(15px)'; break; case 'fade-in-down': element.style.transform = 'translateY(-15px)'; break; case 'scale-in': element.style.transform = 'scale(0.98) translateY(5px)'; break; default: element.style.transform = 'translateY(15px)'; } // Animate to final state setTimeout(() => { element.style.opacity = '1'; element.style.transform = 'translateY(0) translateX(0) scale(1)'; element.classList.add('animated'); }, delay); } else { // Non-hero elements: hide completely and animate on scroll console.log(`๐ŸŽฏ Scroll element ${index + 1}:`, { tag: element.tagName, animation: animation, delay: element.dataset.delay || '0' }); // Set initial styles - completely hidden for scroll elements element.style.opacity = '0'; element.style.transition = 'all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94)'; element.style.willChange = 'opacity, transform'; // Apply initial transform based on animation type switch(animation) { case 'fade-in-left': element.style.transform = 'translateX(-50px)'; break; case 'fade-in-right': element.style.transform = 'translateX(50px)'; break; case 'fade-in-up': element.style.transform = 'translateY(50px)'; break; case 'fade-in-down': element.style.transform = 'translateY(-50px)'; break; case 'scale-in': element.style.transform = 'scale(0.8) translateY(30px)'; break; default: element.style.transform = 'translateY(50px)'; } } }); // Initial check for scroll elements that might already be in viewport setTimeout(() => { console.log('๐Ÿƒ Running initial check for scroll elements...'); scrollHandler(); }, 150); // Add scroll listeners window.addEventListener('scroll', scrollHandler, { passive: true }); window.addEventListener('resize', scrollHandler, { passive: true }); console.log('โœ… Scroll animations initialized'); } // Export init function export function init() { console.log('๐Ÿš€ Initializing page JavaScript...'); // Get modal reference contactModal = document.getElementById('contactModal'); console.log('Modal found:', !!contactModal); // Define event handlers handleModalClick = function(event) { if (event.target === contactModal) { closeContactModal(); } }; handleEscapeKey = function(event) { if (event.key === 'Escape') { closeContactModal(); } }; // Add event listeners for modal if (contactModal) { contactModal.addEventListener('click', handleModalClick); } document.addEventListener('keydown', handleEscapeKey); // Handle internal navigation links const internalLinks = document.querySelectorAll('a[href^="#"]'); console.log('Found internal links:', internalLinks.length); internalLinks.forEach(link => { const href = link.getAttribute('href'); if (href === '#crochet' || href === '#pintura') { console.log('Setting up link for:', href); link.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); console.log('Link clicked:', href); smoothScrollToSection(href); }); } }); // Initialize scroll animations setTimeout(() => { initSimpleScrollAnimations(); }, 50); // Make functions globally available window.openContactModal = openContactModal; window.closeContactModal = closeContactModal; console.log('โœ… JavaScript initialization complete'); } // Export teardown function export function teardown() { console.log('๐Ÿงน Tearing down JavaScript...'); // Remove event listeners if (contactModal && handleModalClick) { contactModal.removeEventListener('click', handleModalClick); } if (handleEscapeKey) { document.removeEventListener('keydown', handleEscapeKey); } // Remove scroll listeners if (scrollHandler) { window.removeEventListener('scroll', scrollHandler); window.removeEventListener('resize', scrollHandler); } // Remove internal link event listeners const internalLinks = document.querySelectorAll('a[href^="#"]'); internalLinks.forEach(link => { const href = link.getAttribute('href'); if (href === '#crochet' || href === '#pintura') { const newLink = link.cloneNode(true); link.parentNode.replaceChild(newLink, link); } }); // Show all scroll-animate elements in case they're hidden const hiddenElements = document.querySelectorAll('.scroll-animate:not(.animated)'); hiddenElements.forEach(element => { element.style.opacity = '1'; element.style.transform = 'none'; }); document.body.style.overflow = 'auto'; // Clean up global functions if (window.openContactModal) { delete window.openContactModal; } if (window.closeContactModal) { delete window.closeContactModal; } // Reset variables contactModal = null; handleModalClick = null; handleEscapeKey = null; scrollHandler = null; console.log('โœ… Teardown complete'); }