-
-
Save disrupted/936206a2171c3985524055cc9ff8ff14 to your computer and use it in GitHub Desktop.
Animated scrollTo for specific element or top of page
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
// | |
// Smooth scroll-to inspired by: | |
// http://stackoverflow.com/a/24559613/728480 | |
// | |
module.exports = function (scrollTo, scrollDuration) { | |
// | |
// Set a default for where we're scrolling to | |
// | |
if (typeof scrollTo === 'string') { | |
// Assuming this is a selector we can use to find an element | |
var scrollToObj = document.querySelector(scrollTo); | |
if (scrollToObj && typeof scrollToObj.getBoundingClientRect === 'function') { | |
scrollTo = window.pageYOffset + scrollToObj.getBoundingClientRect().top; | |
} else { | |
throw 'error: No element found with the selector "' + scrollTo + '"'; | |
} | |
} else if (typeof scrollTo !== 'number') { | |
// If it's nothing above and not an integer, we assume top of the window | |
scrollTo = 0; | |
} | |
// Set this a bit higher | |
var anchorHeightAdjust = 30; | |
if (scrollTo > anchorHeightAdjust) { | |
scrollTo = scrollTo - anchorHeightAdjust; | |
} | |
// | |
// Set a default for the duration | |
// | |
if ( typeof scrollDuration !== 'number' || scrollDuration < 0 ) { | |
scrollDuration = 1000; | |
} | |
// Declarations | |
var cosParameter = (window.pageYOffset - scrollTo) / 2, | |
scrollCount = 0, | |
oldTimestamp = window.performance.now(); | |
function step(newTimestamp) { | |
var tsDiff = newTimestamp - oldTimestamp; | |
// Performance.now() polyfill loads late so passed-in timestamp is a larger offset | |
// on the first go-through than we want so I'm adjusting the difference down here. | |
// Regardless, we would rather have a slightly slower animation than a big jump so a good | |
// safeguard, even if we're not using the polyfill. | |
if (tsDiff > 100) { | |
tsDiff = 30; | |
} | |
scrollCount += Math.PI / (scrollDuration / tsDiff); | |
// As soon as we cross over Pi, we're about where we need to be | |
if (scrollCount >= Math.PI) { | |
return; | |
} | |
var moveStep = Math.round(scrollTo + cosParameter + cosParameter * Math.cos(scrollCount)); | |
window.scrollTo(0, moveStep); | |
oldTimestamp = newTimestamp; | |
window.requestAnimationFrame(step); | |
} | |
window.requestAnimationFrame(step); | |
}; | |
// | |
// Performance.now() polyfill from: | |
// https://gist.github.com/paulirish/5438650 | |
// | |
(function () { | |
if ("performance" in window == false) { | |
window.performance = {}; | |
} | |
Date.now = (Date.now || function () { // thanks IE8 | |
return new Date().getTime(); | |
}); | |
if ("now" in window.performance == false) { | |
var nowOffset = Date.now(); | |
if (performance.timing && performance.timing.navigationStart) { | |
nowOffset = performance.timing.navigationStart | |
} | |
window.performance.now = function now() { | |
return Date.now() - nowOffset; | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment