64 lines
1.9 KiB
JavaScript
64 lines
1.9 KiB
JavaScript
// modules/inertia-scroll/index.js
|
|
import { registerFrameTask, unregisterFrameTask } from '../../core/frameloop.js';
|
|
|
|
let taskId = 'inertia-scroll';
|
|
let velocity = 0;
|
|
let lastY = window.scrollY;
|
|
let active = false;
|
|
let scrollEndTimer;
|
|
let damping = 0.9;
|
|
let minVelocity = 0.2;
|
|
|
|
export function init(config = {}) {
|
|
damping = typeof config.damping === 'number' ? config.damping : 0.9;
|
|
|
|
minVelocity = typeof config.minVelocity === 'number' ? contig.minVelocity : 0.1;
|
|
|
|
window.addEventListener('scroll', onScroll, { passive: true });
|
|
|
|
registerFrameTask(taskId, () => {
|
|
const root = document.documentElement;
|
|
const scrollY = window.scrollY;
|
|
const delta = scrollY - lastY;
|
|
const direction = delta > 0 ? 'down' : delta < 0 ? 'up' : 'none';
|
|
const speed = Math.abs(delta);
|
|
|
|
if (!active && Math.abs(velocity) > minVelocity) {
|
|
window.scrollTo(0, scrollY + velocity);
|
|
velocity *= damping; // Trägheit / Dämpfung
|
|
root.dataset.scrollState = 'inertia';
|
|
} else if (active) {
|
|
velocity = delta;
|
|
lastY = scrollY;
|
|
root.dataset.scrollState = 'active';
|
|
} else {
|
|
delete root.dataset.scrollState;
|
|
}
|
|
|
|
root.dataset.scrollDirection = direction;
|
|
root.dataset.scrollSpeed = speed.toFixed(2);
|
|
}, { autoStart: true });
|
|
}
|
|
|
|
function onScroll() {
|
|
active = true;
|
|
clearTimeout(scrollEndTimer);
|
|
scrollEndTimer = setTimeout(() => {
|
|
active = false;
|
|
}, 50);
|
|
}
|
|
|
|
export function destroy() {
|
|
window.removeEventListener('scroll', onScroll);
|
|
unregisterFrameTask(taskId);
|
|
velocity = 0;
|
|
lastY = window.scrollY;
|
|
active = false;
|
|
clearTimeout(scrollEndTimer);
|
|
|
|
const root = document.documentElement;
|
|
delete root.dataset.scrollState;
|
|
delete root.dataset.scrollDirection;
|
|
delete root.dataset.scrollSpeed;
|
|
}
|