111 lines
2.9 KiB
JavaScript
111 lines
2.9 KiB
JavaScript
// 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'
|
|
});
|
|
});
|
|
}); |