document.addEventListener('DOMContentLoaded', function() { // Enhanced parallax effect const parallaxLayers = document.querySelectorAll('.parallax-layer'); let ticking = false; let lastScrollY = 0; function updateParallax() { const scrollY = window.pageYOffset; const windowHeight = window.innerHeight; const documentHeight = document.body.scrollHeight; parallaxLayers.forEach(layer => { const depth = parseFloat(layer.getAttribute('data-depth')); const layerOffset = layer.getBoundingClientRect().top; const layerHeight = layer.offsetHeight; // Calculate position in viewport (0-1) const viewportPosition = (layerOffset + layerHeight) / (windowHeight + layerHeight); // Enhanced movement calculation with easing const movement = -(scrollY * depth * (0.5 + viewportPosition * 0.5)); // Apply transform with hardware acceleration layer.style.transform = `translate3d(0, ${movement}px, 0)`; // Optional: Add perspective for more depth layer.style.perspective = '1000px'; layer.style.backfaceVisibility = 'hidden'; }); ticking = false; } function onScroll() { lastScrollY = window.scrollY; if (!ticking) { window.requestAnimationFrame(updateParallax); ticking = true; } } window.addEventListener('scroll', onScroll, { passive: true }); window.addEventListener('resize', updateParallax); // Initial call updateParallax(); // Enhanced horizontal scroll for testimonials with momentum function setupHorizontalScroll() { const track = document.querySelector('.testimonial-track'); if (!track) return; let isDown = false; let startX; let scrollLeft; let velocity = 0; let animationFrame; let lastTime = 0; track.addEventListener('mousedown', (e) => { isDown = true; startX = e.pageX - track.offsetLeft; scrollLeft = track.scrollLeft; cancelAnimationFrame(animationFrame); }); track.addEventListener('mouseleave', () => { isDown = false; applyMomentum(); }); track.addEventListener('mouseup', () => { isDown = false; applyMomentum(); }); track.addEventListener('mousemove', (e) => { if(!isDown) return; e.preventDefault(); const x = e.pageX - track.offsetLeft; const walk = (x - startX) * 3; // faster scroll track.scrollLeft = scrollLeft - walk; velocity = walk - (scrollLeft - track.scrollLeft); }); function applyMomentum() { if (Math.abs(velocity) > 1) { track.scrollLeft += velocity; velocity *= 0.95; // friction animationFrame = requestAnimationFrame(applyMomentum); } } // Touch support track.addEventListener('touchstart', (e) => { isDown = true; startX = e.touches[0].pageX - track.offsetLeft; scrollLeft = track.scrollLeft; cancelAnimationFrame(animationFrame); }); track.addEventListener('touchend', () => { isDown = false; applyMomentum(); }); track.addEventListener('touchmove', (e) => { if(!isDown) return; const x = e.touches[0].pageX - track.offsetLeft; const walk = (x - startX) * 3; track.scrollLeft = scrollLeft - walk; velocity = walk - (scrollLeft - track.scrollLeft); }); } setupHorizontalScroll(); // Animation on scroll const animateOnScroll = function() { const elements = document.querySelectorAll('.service-card, .testimonial-card'); elements.forEach(element => { const elementPosition = element.getBoundingClientRect().top; const windowHeight = window.innerHeight; if (elementPosition < windowHeight - 100) { element.classList.add('animate-fadeInUp'); } }); }; window.addEventListener('scroll', animateOnScroll); animateOnScroll(); // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const targetId = this.getAttribute('href'); if (targetId === '#') return; const targetElement = document.querySelector(targetId); if (targetElement) { targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // Animation on scroll const animateOnScroll = function() { const elements = document.querySelectorAll('.service-card, .testimonial-card'); elements.forEach(element => { const elementPosition = element.getBoundingClientRect().top; const windowHeight = window.innerHeight; if (elementPosition < windowHeight - 100) { element.classList.add('animate-fadeInUp'); } }); }; window.addEventListener('scroll', animateOnScroll); animateOnScroll(); // Initial check });