// Strict one-section-at-a-time scrolling document.addEventListener('DOMContentLoaded', () => { const portfolio = document.querySelector('.portfolio'); if (!portfolio) return; let isAnimating = false; let lastScrollTime = 0; let currentSection = 0; let lastTouchY = null; const sections = document.querySelectorAll('.portfolio__section'); const sectionHeight = window.innerHeight; const scrollDelay = 50; // Time between allowed scrolls (ms) const scrollThreshold = 10; // Minimum pixels to trigger scroll // Initialize scroll position window.scrollTo(0, 0); // Handle wheel/touch events portfolio.addEventListener('wheel', handleScroll, { passive: false }); portfolio.addEventListener('touchstart', (e) => { lastTouchY = e.touches[0].clientY; }, { passive: true }); portfolio.addEventListener('touchmove', handleScroll, { passive: false }); function handleScroll(e) { const now = Date.now(); e.preventDefault(); if (isAnimating || (now - lastScrollTime < scrollDelay)) { return; } // Calculate delta based on input type let delta; if (e.type === 'wheel') { delta = e.deltaY; } else if (e.type === 'touchmove') { delta = lastTouchY - e.touches[0].clientY; lastTouchY = e.touches[0].clientY; } // Determine target section let targetSection = currentSection; if (delta > scrollThreshold) { targetSection = Math.min(currentSection + 1, sections.length - 1); } else if (delta < -scrollThreshold) { targetSection = Math.max(currentSection - 1, 0); } else { return; } if (targetSection !== currentSection) { isAnimating = true; currentSection = targetSection; lastScrollTime = now; portfolio.scrollTo({ top: sectionHeight * targetSection, behavior: 'smooth' }); setTimeout(() => { isAnimating = false; }, scrollDelay); } } // Handle keyboard navigation document.addEventListener('keydown', (e) => { if (isAnimating) return; switch(e.key) { case 'ArrowDown': e.preventDefault(); currentSection = Math.min(currentSection + 1, sections.length - 1); break; case 'ArrowUp': e.preventDefault(); currentSection = Math.max(currentSection - 1, 0); break; case 'Home': e.preventDefault(); currentSection = 0; break; case 'End': e.preventDefault(); currentSection = sections.length - 1; break; default: return; } isAnimating = true; portfolio.scrollTo({ top: sectionHeight * currentSection, behavior: 'smooth' }); setTimeout(() => { isAnimating = false; }, scrollDelay); }); // Handle window resize window.addEventListener('resize', () => { portfolio.scrollTo({ top: sectionHeight * currentSection, behavior: 'auto' }); }); });