Skip to content

Instantly share code, notes, and snippets.

@goblindegook
Last active February 20, 2016 19:18
Show Gist options
  • Save goblindegook/f6e90a32f935719c0d17 to your computer and use it in GitHub Desktop.
Save goblindegook/f6e90a32f935719c0d17 to your computer and use it in GitHub Desktop.
Animated vertical scroll, no jQuery
'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