Skip to content

Instantly share code, notes, and snippets.

@jossmac
Last active February 23, 2018 00:02
Show Gist options
  • Save jossmac/d207e7fa25c57fdf287a9992322fadef to your computer and use it in GitHub Desktop.
Save jossmac/d207e7fa25c57fdf287a9992322fadef to your computer and use it in GitHub Desktop.
Scroll Utilities
import raf from 'raf';
/**
@param t: time (elapsed)
@param b: initial value
@param c: amount of change
@param d: duration
*/
function easeOutCubic(t: number, b: number, c: number, d: number): number {
return c * ((t = t / d - 1) * t * t + 1) + b;
};
function animatedScrollTo(
element: Element,
to: number,
duration: number = 200
) {
const start = getScrollTop(element);
const change = to - start;
const increment = 10;
let currentTime = 0;
function animateScroll() {
currentTime += increment;
const val = easeOutCubic(currentTime, start, change, duration);
normalizedScrollTo(element, val);
if (currentTime < duration) {
raf(animateScroll);
}
}
animateScroll();
}
function getScrollParent(element: Element): Element {
let style = getComputedStyle(element);
const excludeStaticParent = style.position === 'absolute';
const overflowRx = /(auto|scroll)/;
const docEl = ((document.documentElement: any): Element); // suck it, flow...
if (style.position === 'fixed') return docEl;
for (let parent = element; (parent = parent.parentElement); ) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === 'static') {
continue;
}
if (overflowRx.test(style.overflow + style.overflowY + style.overflowX)) {
return parent;
}
}
return docEl;
}
function getScrollTop(el: Element): number {
if (isDocumentElement(el)) {
return window.pageYOffset;
}
return el.scrollTop;
}
function isDocumentElement(el: Element) {
return [document.documentElement, document.body, window].includes(el);
}
function normalizedHeight(el: Element): number {
if (isDocumentElement(el)) {
return window.innerHeight;
}
return el.clientHeight;
}
function normalizedScrollTo(el: Element, top: number): void {
if (isDocumentElement(el)) {
window.scrollTo(0, top);
return;
}
el.scrollTop = top;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment