Last active
November 28, 2018 09:22
-
-
Save joshuacerbito/ed1e03dae325aac9b39493fb2323d1a4 to your computer and use it in GitHub Desktop.
Scroll Animator using requestAnimationFrame
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Add requestAnimationFrame shim | |
// http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ | |
window._animate = (function() { | |
return ( | |
window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
function(callback) { | |
window.setTimeout(callback, 1000 / 60); | |
} | |
); | |
})(); | |
// The main function | |
export function animateScrollTo({ | |
context = window, // what you're trying to scroll, defaults to "window" | |
scrollTo = 0, // where you want to scroll to | |
speed = 2000, // how fast you want to scroll | |
easing = "easeInOutSine" // the animation easing | |
}) { | |
const scrollY = context.scrollY || context.scrollTop; | |
let currentTime = 0; | |
const scrollTargetY = scrollTo || 0; | |
// min time .1, max time .8 seconds | |
let time = Math.max( | |
0.1, | |
Math.min(Math.abs(scrollY - scrollTargetY) / speed, 0.8) | |
); | |
// easing equations from https://github.com/danro/easing-js/blob/master/easing.js | |
const easingEquations = { | |
easeOutSine(pos) { | |
return Math.sin(pos * (Math.PI / 2)); | |
}, | |
easeInOutSine(pos) { | |
return -0.5 * (Math.cos(Math.PI * pos) - 1); | |
}, | |
easeInOutQuint(pos) { | |
if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 5); | |
return 0.5 * (Math.pow(pos - 2, 5) + 2); | |
} | |
}; | |
// add animation loop | |
function tick() { | |
currentTime += 1 / 60; | |
let p = currentTime / time; | |
let t = easingEquations[easing](p); | |
if (p < 1) { | |
_animate(tick); | |
context.scrollTo(0, scrollY + (scrollTargetY - scrollY) * t); | |
} else { | |
context.scrollTo(0, scrollTargetY); | |
} | |
} | |
// call it once to get started | |
tick(); | |
} | |
export default animateScrollTo; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment