svelte-legos
svelte-legos copied to clipboard
[ Feature Request ] useSmoothScrolling
For a project I was doing I wanted all my users to have a nice scrolling experience - like macOS users have when using native hardware (magic mouse, trackpad). It's always bothered me how rough it can feel on windows or using a 3rd party mouse. So I wrote this action and thought I would see if it's something people are interested in. I'm not very familiar with Svelte-Legos, so I didn't want to just fork and open a pull request out of nowhere. Was sent here from a different library project when I asked if they were interested in the action.
/* helper */
function clamp(num: number, min: number, max: number): number {
return Math.min(Math.max(num, min), max);
}
/* useSmoothScrolling */
interface SmoothScrollOptions {
friction?: number;
maxSpeed?: number;
deadZone?: number;
}
//friction around 0.94-0.95 feels the best, imo (behaves oddly outside of 0.9 to 0.96)
//lower max speed does weird things if users mouse wheel is set to scroll a lot of lines at once
//deadZone is to prevent run away scrolling from small scroll movements
export default function useSmoothScrolling(node: HTMLElement, params: SmoothScrollOptions) {
const {friction = 0.94, maxSpeed = 60, deadZone = 0.5} = params;
//todo: map 1-100 to 0.9 to 0.96 to make friction more readable
let clampedFriction = clamp(friction, 0.9, 0.96);
let velocity = 0;
const wheelHandler = (e: WheelEvent) => {
velocity += e.deltaY * 0.1;
velocity = clamp(velocity, -maxSpeed, maxSpeed);
};
const animationHandler = () => {
if (Math.abs(velocity) > deadZone) {
velocity *= clampedFriction;
node.scrollTop += velocity;
} else {
velocity = 0;
}
frameId = window.requestAnimationFrame(animationHandler);
};
node.addEventListener('wheel', wheelHandler, { passive: true });
let frameId = window.requestAnimationFrame(animationHandler);
return {
destroy() {
node.removeEventListener('wheel', wheelHandler);
window.cancelAnimationFrame(frameId);
}
};
}
If it's something people are interested in I'm happy to refactor it and make a more robust implementation.
Hey @waffleflopper thanks for the idea. Totally if you can create a proper implementation and raise a PR it will be helpful, :).
Been without internet for a while (Army stuff for upcoming deployment), but I'll get something put together. Thanks!