Skip to content

Instantly share code, notes, and snippets.

@codler
Last active June 25, 2020 09:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codler/9e802849c527b756848eef8ef220e103 to your computer and use it in GitHub Desktop.
Save codler/9e802849c527b756848eef8ef220e103 to your computer and use it in GitHub Desktop.
Smooth scrollToElement
function scrollTo(targetPosition: number, scrollDistance: number, duration: number, easing: Function) {
let time = 0;
const minTime = 0;
const diff = Math.max(Math.min(scrollDistance, 100), -100);
if (diff === 0) {
return;
}
for (let i = 0, len = Math.abs(diff); i <= len; i++) {
// eslint-disable-next-line no-loop-func
(s => {
setTimeout(() => {
// eslint-disable-next-line no-mixed-operators
const y = targetPosition - (scrollDistance - (scrollDistance / Math.abs(diff)) * s);
window.scrollTo(0, y);
}, time);
})(i);
time = easing(i, minTime, duration, Math.abs(diff));
}
}
function scrollToElement(node: HTMLElement, duration: number, easing: Function, offsetTop: number = 0) {
const targetPosition = node.getBoundingClientRect().top + (window.pageYOffset || window.scrollY) + offsetTop;
const scrollDistance = node.getBoundingClientRect().top + offsetTop;
scrollTo(targetPosition, scrollDistance, duration, easing);
}
// http://stackoverflow.com/questions/12081547/applying-easing-to-settimeout-delays-within-a-loop
// eslint-disable-next-line
function easeInQuad(t: number, b: number, c: number, d: number) {
return c * (t /= d) * t + b;
}
const easing = {
easeInQuad
};
export { scrollTo, scrollToElement, easing };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment