1 line
4.1 KiB
JavaScript
1 line
4.1 KiB
JavaScript
document.addEventListener("DOMContentLoaded", function(){const topBanner = document.querySelector('.top-banner');const slideMenu = document.querySelector('.slide-menu');if (!topBanner) return;// Configuration for ultra-smooth performance const scrollThreshold = 50;const rafDelay = 8;// 120fps for ultra-smooth const transitionDuration = 400;// Slightly longer for smoother feel // State tracking with performance optimization let isScrolled = false;let lastScrollY = 0;let scrollDirection = 'down';let rafId = null;let lastUpdateTime = 0;let scrollVelocity = 0;let lastScrollTime = 0;// Calculate scroll velocity for smoother transitions function calculateVelocity(currentScrollY, currentTime){if (lastScrollTime === 0){lastScrollTime = currentTime;return 0;}const timeDelta = currentTime - lastScrollTime;const scrollDelta = Math.abs(currentScrollY - lastScrollY);const velocity = scrollDelta / timeDelta;lastScrollTime = currentTime;return velocity;}// Ultra-smooth header state update with velocity-based easing function updateHeaderState(scrolled, velocity = 0){if (scrolled === isScrolled) return;// Add velocity-based class for different transition speeds if (velocity > 5){topBanner.classList.add('fast-scroll');}else{topBanner.classList.remove('fast-scroll');}// Use requestAnimationFrame for smooth DOM updates requestAnimationFrame(() =>{if (scrolled){topBanner.classList.add('scrolled');if (slideMenu){slideMenu.style.transition = 'top 0.3s cubic-bezier(0.4, 0, 0.2, 1)';slideMenu.style.top = '80px';}}else{topBanner.classList.remove('scrolled');if (slideMenu){slideMenu.style.transition = 'top 0.3s cubic-bezier(0.4, 0, 0.2, 1)';slideMenu.style.top = '110px';}}});isScrolled = scrolled;}// Advanced scroll handler with velocity detection function handleScroll(currentTime){// Ultra-high frequency throttling if (currentTime - lastUpdateTime < rafDelay){rafId = requestAnimationFrame(handleScroll);return;}const currentScrollY = window.pageYOffset || document.documentElement.scrollTop;const velocity = calculateVelocity(currentScrollY, currentTime);// Detect scroll direction with hysteresis for stability const scrollDelta = currentScrollY - lastScrollY;if (Math.abs(scrollDelta) > 1){scrollDirection = scrollDelta > 0 ? 'down' : 'up';}// Apply hysteresis to prevent flickering let shouldScroll;if (scrollDirection === 'down'){shouldScroll = currentScrollY > scrollThreshold + 10;}else{shouldScroll = currentScrollY > scrollThreshold - 10;}updateHeaderState(shouldScroll, velocity);lastScrollY = currentScrollY;lastUpdateTime = currentTime;rafId = null;}// Optimized scroll listener with passive event function onScroll(){if (!rafId){rafId = requestAnimationFrame(handleScroll);}}// Add scroll listener with maximum performance window.addEventListener('scroll', onScroll,{passive: true, capture: false});// Handle resize with debouncing let resizeTimeout;function onResize(){clearTimeout(resizeTimeout);resizeTimeout = setTimeout(() =>{lastScrollY = window.pageYOffset || document.documentElement.scrollTop;updateHeaderState(lastScrollY > scrollThreshold);}, 100);}window.addEventListener('resize', onResize,{passive: true});// Handle visibility change to pause/resume animations function onVisibilityChange(){if (document.hidden){if (rafId){cancelAnimationFrame(rafId);rafId = null;}}else{lastScrollY = window.pageYOffset || document.documentElement.scrollTop;updateHeaderState(lastScrollY > scrollThreshold);}}document.addEventListener('visibilitychange', onVisibilityChange);// Initialize with smooth transition requestAnimationFrame(() =>{updateHeaderState(window.pageYOffset > scrollThreshold);});// Add smooth scroll behavior to internal links document.querySelectorAll('a[href^="#"]').forEach(link =>{link.addEventListener('click', function(e){const targetId = this.getAttribute('href');if (targetId === '#') return;const targetElement = document.querySelector(targetId);if (targetElement){e.preventDefault();// Smooth scroll with header offset const headerHeight = topBanner.offsetHeight;const targetPosition = targetElement.offsetTop - headerHeight - 20;window.scrollTo({top: targetPosition, behavior: 'smooth'});}});});});
|