Last active
February 20, 2016 19:18
-
-
Save goblindegook/f6e90a32f935719c0d17 to your computer and use it in GitHub Desktop.
Animated vertical scroll, no jQuery
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
'use strict'; | |
/** | |
* Create requestAnimationFrame() polyfill function. | |
* | |
* Creates a requestAnimationFrame()-compatible function based on setTimeout(). | |
* | |
* @param {Number} fps Frames per second (defaults to 60). | |
* @return {Function} requestAnimationFrame() polyfill. | |
*/ | |
function createRequestFrame(fps) { | |
var tick; | |
var progress = 0; | |
fps = fps || 60; | |
tick = 1000 / fps; | |
/** | |
* requestAnimationFrame() polyfill. | |
* | |
* @param {Function} cb Callback to invoke on every tick. | |
* @return {Number} Timeout ID. | |
*/ | |
return function (cb) { | |
var now = new Date().getTime(); | |
var wait = Math.max(0, progress + tick - now); | |
var id = global.setTimeout(function () { return cb(now + wait); }, wait); | |
progress = now + wait; | |
return id; | |
}; | |
} | |
var requestFrame = global.requestAnimationFrame | |
|| global.msRequestAnimationFrame | |
|| global.mozRequestAnimationFrame | |
|| global.webkitRequestAnimationFrame | |
|| global.oRequestAnimationFrame | |
|| createRequestFrame(); | |
/** | |
* Get vertical scroll position. | |
* @return {Number} Vertical scroll position. | |
*/ | |
function getScrollTop() { | |
return document.documentElement.scrollTop | |
|| document.body.parentNode.scrollTop | |
|| document.body.scrollTop; | |
} | |
/** | |
* Set vertical scroll position. | |
* @param {Number} scrollTop Vertical scroll position. | |
*/ | |
function setScrollTop(scrollTop) { | |
document.documentElement.scrollTop = scrollTop; | |
document.body.parentNode.scrollTop = scrollTop; | |
document.body.scrollTop = scrollTop; | |
} | |
// A variety of easing functions, take your pick or use something else... | |
var easeInCubic = function easeInCubic(t) { | |
return Math.pow(t, 3); | |
}; | |
var easeOutCubic = function easeOutCubic(t) { | |
return Math.pow(t - 1, 3) + 1; | |
}; | |
var easeInOutCubic = function easeInOutCubic(t) { | |
return t < 0.5 ? Math.pow(t, 3) * 4 : Math.pow(t - 1, 3) * 4 + 1; | |
}; | |
/** | |
* Scroll to vertical position. | |
* | |
* @param {Number} targetPosition Scroll to vertical position. | |
* @param {Number} duration Animation duration, in milliseconds (optional, defaults to 1000) | |
* @param {Function} completion Completion callback (optional). | |
* @param {Function} easing Easing function (optional, defaults to easeInOutCubic). | |
*/ | |
function scrollTo(targetPosition, duration, completion, easing) { | |
var offset = getScrollTop(); | |
var change = targetPosition - offset; | |
var start = 0; | |
duration = duration || 1000; | |
easing = easing || easeInOutCubic; | |
var animateScroll = function animateScroll(timestamp) { | |
var progress; | |
if (!start) { | |
start = timestamp; | |
} | |
progress = timestamp - start; | |
setScrollTop(offset + change * easing(progress / duration)); | |
if (progress <= duration) { | |
requestFrame(animateScroll); | |
} else if (completion && typeof completion === 'function') { | |
completion(); | |
} | |
}; | |
requestFrame(animateScroll); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment