Spaces:
Running
Running
| // Intersection Observer for Fade-in Animations | |
| const observerOptions = { | |
| root: null, | |
| rootMargin: '0px', | |
| threshold: 0.1 | |
| }; | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('animate-fade-in'); | |
| observer.unobserve(entry.target); | |
| } | |
| }); | |
| }, observerOptions); | |
| // Observe all cards and sections | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const animateElements = document.querySelectorAll('.group, section > div'); | |
| animateElements.forEach((el, index) => { | |
| el.style.opacity = '0'; | |
| el.style.transform = 'translateY(20px)'; | |
| el.style.transition = `opacity 0.6s ease ${index * 0.1}s, transform 0.6s ease ${index * 0.1}s`; | |
| observer.observe(el); | |
| }); | |
| }); | |
| // Custom Animation Classes | |
| const style = document.createElement('style'); | |
| style.textContent = ` | |
| .animate-fade-in { | |
| opacity: 1 !important; | |
| transform: translateY(0) !important; | |
| } | |
| @keyframes float { | |
| 0%, 100% { transform: translateY(0px); } | |
| 50% { transform: translateY(-20px); } | |
| } | |
| .animate-float-slow { | |
| animation: float 6s ease-in-out infinite; | |
| } | |
| .animate-float-medium { | |
| animation: float 4s ease-in-out infinite; | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| // Tool Cards Interaction | |
| document.querySelectorAll('.tool-card').forEach(card => { | |
| card.addEventListener('mouseenter', function() { | |
| this.style.transform = 'translateY(-8px) scale(1.02)'; | |
| }); | |
| card.addEventListener('mouseleave', function() { | |
| this.style.transform = 'translateY(0) scale(1)'; | |
| }); | |
| }); | |
| // Smooth Scroll for Anchor Links | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| const target = document.querySelector(this.getAttribute('href')); | |
| if (target) { | |
| target.scrollIntoView({ | |
| behavior: 'smooth', | |
| block: 'start' | |
| }); | |
| } | |
| }); | |
| }); | |
| // Mobile Menu Toggle Functionality (handled in web component, but backup here) | |
| function toggleMobileMenu() { | |
| const mobileMenu = document.querySelector('[data-mobile-menu]'); | |
| if (mobileMenu) { | |
| mobileMenu.classList.toggle('hidden'); | |
| mobileMenu.classList.toggle('flex'); | |
| } | |
| } | |
| // Parallax Effect for Hero Section | |
| window.addEventListener('scroll', () => { | |
| const scrolled = window.pageYOffset; | |
| const parallaxElements = document.querySelectorAll('.parallax'); | |
| parallaxElements.forEach(el => { | |
| const speed = el.dataset.speed || 0.5; | |
| el.style.transform = `translateY(${scrolled * speed}px)`; | |
| }); | |
| }); | |
| // Dynamic Year Update | |
| const yearElements = document.querySelectorAll('.current-year'); | |
| yearElements.forEach(el => { | |
| el.textContent = new Date().getFullYear(); | |
| }); | |
| // Form Validation | |
| function validateEmail(email) { | |
| const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; | |
| return re.test(email); | |
| } | |
| // Newsletter Form Handler | |
| const newsletterForms = document.querySelectorAll('form'); | |
| newsletterForms.forEach(form => { | |
| form.addEventListener('submit', (e) => { | |
| const emailInput = form.querySelector('input[type="email"]'); | |
| if (emailInput && !validateEmail(emailInput.value)) { | |
| e.preventDefault(); | |
| emailInput.classList.add('border-red-500'); | |
| setTimeout(() => { | |
| emailInput.classList.remove('border-red-500'); | |
| }, 3000); | |
| } | |
| }); | |
| }); | |
| // Toast Notification System | |
| function showToast(message, type = 'success') { | |
| const toast = document.createElement('div'); | |
| toast.className = `fixed bottom-4 right-4 px-6 py-4 rounded-xl text-white font-medium z-50 transform translate-y-20 transition-transform duration-300 ${ | |
| type === 'success' ? 'bg-green-600' : 'bg-red-600' | |
| }`; | |
| toast.textContent = message; | |
| document.body.appendChild(toast); | |
| setTimeout(() => { | |
| toast.style.transform = 'translateY(0)'; | |
| }, 100); | |
| setTimeout(() => { | |
| toast.style.transform = 'translateY(20px)'; | |
| setTimeout(() => toast.remove(), 300); | |
| }, 3000); | |
| } | |
| // Button Click Handlers for "Free" emphasis | |
| document.querySelectorAll('button, a').forEach(btn => { | |
| if (btn.textContent.includes('Try now') || btn.textContent.includes('Create')) { | |
| btn.addEventListener('click', (e) => { | |
| if (!btn.getAttribute('href') || btn.getAttribute('href') === '#') { | |
| e.preventDefault(); | |
| showToast('Opening free tool... No credit card required!'); | |
| } | |
| }); | |
| } | |
| }); | |
| // Performance: Lazy load images | |
| if ('IntersectionObserver' in window) { | |
| const imageObserver = new IntersectionObserver((entries, observer) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const img = entry.target; | |
| img.src = img.dataset.src || img.src; | |
| img.classList.remove('lazy'); | |
| imageObserver.unobserve(img); | |
| } | |
| }); | |
| }); | |
| document.querySelectorAll('img').forEach(img => imageObserver.observe(img)); | |
| } | |
| // Keyboard Navigation Enhancement | |
| document.addEventListener('keydown', (e) => { | |
| if (e.key === 'Tab') { | |
| document.body.classList.add('keyboard-navigation'); | |
| } | |
| }); | |
| document.addEventListener('mousedown', () => { | |
| document.body.classList.remove('keyboard-navigation'); | |
| }); |