smooth-scrollbar
Version:
Customize scrollbar in modern browsers with smooth scrolling experience.
63 lines (50 loc) • 1.34 kB
text/typescript
import clamp from 'lodash.clamp';
import * as I from '../interfaces/';
const animationIDStorage = new WeakMap<I.Scrollbar, number>();
export function scrollTo(
scrollbar: I.Scrollbar,
x: number,
y: number,
duration = 0,
{ easing = defaultEasing, callback }: Partial<I.ScrollToOptions> = {},
) {
const {
options,
offset,
limit,
} = scrollbar;
if (options.renderByPixels) {
// ensure resolved with integer
x = Math.round(x);
y = Math.round(y);
}
const startX = offset.x;
const startY = offset.y;
const disX = clamp(x, 0, limit.x) - startX;
const disY = clamp(y, 0, limit.y) - startY;
const start = Date.now();
function scroll() {
const elapse = Date.now() - start;
const progress = duration ? easing(Math.min(elapse / duration, 1)) : 1;
scrollbar.setPosition(
startX + disX * progress,
startY + disY * progress,
);
if (elapse >= duration) {
if (typeof callback === 'function') {
callback.call(scrollbar);
}
} else {
const animationID = requestAnimationFrame(scroll);
animationIDStorage.set(scrollbar, animationID);
}
}
cancelAnimationFrame(animationIDStorage.get(scrollbar) as number);
scroll();
}
/**
* easeOutCubic
*/
function defaultEasing(t: number): number {
return (t - 1) ** 3 + 1;
}