119 lines
3.3 KiB
JavaScript
119 lines
3.3 KiB
JavaScript
// modules/smooth-scroll/index.js
|
|
import { Logger } from '../../core/logger.js';
|
|
import { registerFrameTask } from '../../core/frameloop.js';
|
|
|
|
/*
|
|
export function init(config = {}) {
|
|
Logger.info('SmoothScroll init');
|
|
|
|
const defaultConfig = {
|
|
speed: 0.12,
|
|
scrollTarget: window,
|
|
interceptWheel: true,
|
|
interceptTouch: true,
|
|
interceptKeys: true
|
|
};
|
|
|
|
const settings = { ...defaultConfig, ...config };
|
|
const scrollElement = settings.scrollTarget === window ? document.scrollingElement : settings.scrollTarget;
|
|
|
|
let current = scrollElement.scrollTop;
|
|
let target = current;
|
|
|
|
function clampTarget() {
|
|
const maxScroll = scrollElement.scrollHeight - window.innerHeight;
|
|
target = Math.max(0, Math.min(target, maxScroll));
|
|
}
|
|
|
|
function update() {
|
|
const delta = target - current;
|
|
current += delta * settings.speed;
|
|
|
|
const maxScroll = scrollElement.scrollHeight - window.innerHeight;
|
|
current = Math.max(0, Math.min(current, maxScroll));
|
|
|
|
scrollElement.scrollTop = current;
|
|
}
|
|
|
|
registerFrameTask('smooth-scroll', update, { autoStart: true });
|
|
|
|
function triggerScroll(immediate = false) {
|
|
clampTarget();
|
|
if (immediate) scrollElement.scrollTop = target;
|
|
}
|
|
|
|
function onWheel(e) {
|
|
if (!settings.interceptWheel) return;
|
|
e.preventDefault();
|
|
target += e.deltaY;
|
|
triggerScroll(true);
|
|
}
|
|
|
|
let lastTouchY = 0;
|
|
|
|
function onTouchStart(e) {
|
|
if (!settings.interceptTouch) return;
|
|
lastTouchY = e.touches[0].clientY;
|
|
}
|
|
|
|
function onTouchMove(e) {
|
|
if (!settings.interceptTouch) return;
|
|
e.preventDefault();
|
|
const touch = e.changedTouches[0];
|
|
const dy = lastTouchY - touch.clientY;
|
|
target += dy;
|
|
lastTouchY = touch.clientY;
|
|
triggerScroll(true);
|
|
}
|
|
|
|
function onKeyDown(e) {
|
|
if (!settings.interceptKeys) return;
|
|
const keyScrollAmount = 60;
|
|
switch (e.key) {
|
|
case 'ArrowDown':
|
|
e.preventDefault();
|
|
target += keyScrollAmount;
|
|
break;
|
|
case 'ArrowUp':
|
|
e.preventDefault();
|
|
target -= keyScrollAmount;
|
|
break;
|
|
case 'PageDown':
|
|
e.preventDefault();
|
|
target += window.innerHeight * 0.9;
|
|
break;
|
|
case 'PageUp':
|
|
e.preventDefault();
|
|
target -= window.innerHeight * 0.9;
|
|
break;
|
|
case 'Home':
|
|
e.preventDefault();
|
|
target = 0;
|
|
break;
|
|
case 'End':
|
|
e.preventDefault();
|
|
target = scrollElement.scrollHeight;
|
|
break;
|
|
}
|
|
triggerScroll(true);
|
|
}
|
|
|
|
if (settings.interceptWheel) {
|
|
window.addEventListener('wheel', onWheel, { passive: false });
|
|
}
|
|
|
|
if (settings.interceptTouch) {
|
|
window.addEventListener('touchstart', onTouchStart, { passive: false });
|
|
window.addEventListener('touchmove', onTouchMove, { passive: false });
|
|
}
|
|
|
|
if (settings.interceptKeys) {
|
|
window.addEventListener('keydown', onKeyDown);
|
|
}
|
|
|
|
// initial scroll alignment
|
|
target = scrollElement.scrollTop;
|
|
current = target;
|
|
}
|
|
*/
|