| |
| 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-up'); |
| entry.target.style.opacity = '1'; |
| |
| |
| if (entry.target.hasAttribute('data-count')) { |
| animateCounter(entry.target); |
| } |
| } |
| }); |
| }, observerOptions); |
|
|
| |
| document.addEventListener('DOMContentLoaded', () => { |
| |
| const featureCards = document.querySelectorAll('.group[data-observe]'); |
| featureCards.forEach((el, index) => { |
| el.style.opacity = '0'; |
| el.style.animationDelay = `${index * 0.1}s`; |
| observer.observe(el); |
| }); |
|
|
| |
| const stats = document.querySelectorAll('[data-count]'); |
| stats.forEach(stat => { |
| stat.style.opacity = '1'; |
| observer.observe(stat); |
| }); |
|
|
| |
| const nav = document.querySelector('nav'); |
| let lastScroll = 0; |
|
|
| window.addEventListener('scroll', () => { |
| const currentScroll = window.pageYOffset; |
| |
| if (currentScroll > 100) { |
| nav?.classList.add('bg-slate-950/80', 'backdrop-blur-md', 'border-b', 'border-white/10'); |
| nav?.classList.remove('bg-transparent'); |
| } else { |
| nav?.classList.remove('bg-slate-950/80', 'backdrop-blur-md', 'border-b', 'border-white/10'); |
| nav?.classList.add('bg-transparent'); |
| } |
|
|
| lastScroll = currentScroll; |
| }); |
|
|
| |
| 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' |
| }); |
| } |
| }); |
| }); |
|
|
| |
| const form = document.getElementById('contactForm'); |
| form?.addEventListener('submit', (e) => { |
| e.preventDefault(); |
| |
| |
| const button = form.querySelector('button[type="submit"]'); |
| const originalText = button.innerText; |
| |
| button.innerText = 'Sending...'; |
| button.disabled = true; |
| |
| setTimeout(() => { |
| button.innerText = 'Message Sent!'; |
| button.classList.add('bg-green-600'); |
| |
| setTimeout(() => { |
| button.innerText = originalText; |
| button.classList.remove('bg-green-600'); |
| button.disabled = false; |
| form.reset(); |
| }, 2000); |
| }, 1500); |
| }); |
|
|
| |
| document.addEventListener('mousemove', (e) => { |
| const orbs = document.querySelectorAll('.animate-float'); |
| const x = e.clientX / window.innerWidth; |
| const y = e.clientY / window.innerHeight; |
|
|
| orbs.forEach((orb, index) => { |
| const speed = (index + 1) * 20; |
| const xOffset = (0.5 - x) * speed; |
| const yOffset = (0.5 - y) * speed; |
| |
| orb.style.transform = `translate(${xOffset}px, ${yOffset}px)`; |
| }); |
| }); |
| }); |
|
|
| |
| function animateCounter(element) { |
| const target = parseInt(element.getAttribute('data-count')); |
| const duration = 2000; |
| const start = 0; |
| const increment = target / (duration / 16); |
| let current = 0; |
|
|
| const timer = setInterval(() => { |
| current += increment; |
| if (current >= target) { |
| element.textContent = target + (element.nextElementSibling?.textContent.includes('%') ? '%' : '+'); |
| clearInterval(timer); |
| } else { |
| element.textContent = Math.floor(current) + (element.nextElementSibling?.textContent.includes('%') ? '%' : '+'); |
| } |
| }, 16); |
| } |
|
|
| |
| function toggleMobileMenu() { |
| const mobileMenu = document.getElementById('mobileMenu'); |
| const isOpen = !mobileMenu.classList.contains('translate-x-full'); |
| |
| if (isOpen) { |
| mobileMenu.classList.add('translate-x-full'); |
| mobileMenu.classList.remove('translate-x-0'); |
| document.body.style.overflow = ''; |
| } else { |
| mobileMenu.classList.remove('translate-x-full'); |
| mobileMenu.classList.add('translate-x-0'); |
| document.body.style.overflow = 'hidden'; |
| } |
| } |
|
|
| |
| window.addEventListener('resize', () => { |
| if (window.innerWidth >= 768) { |
| const mobileMenu = document.getElementById('mobileMenu'); |
| mobileMenu?.classList.add('translate-x-full'); |
| mobileMenu?.classList.remove('translate-x-0'); |
| document.body.style.overflow = ''; |
| } |
| }); |