Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Use requestAnimationFrame to handle scrolling smoothly
const createScrollManager = function() {
let callbacks = [];
let scrollPosition = -1;
let animatedKilled = false;
const animate = () => {
requestAnimationFrame(onScroll);
}
function onScroll(){
if(animatedKilled) return;
if (scrollPosition !== window.pageYOffset) {
window.removeEventListener('scroll', animate);
scrollPosition = window.pageYOffset;
callbacks.forEach(cb => cb(scrollPosition));
animate();
} else {
window.addEventListener('scroll', animate);
}
}
animate();
return {
add: function(cb) {
callbacks = [...callbacks, cb];
},
remove: function(cb) {
callbacks = callbacks.filter(value => value != cb);
},
destroy: function() {
animatedKilled = true;
window.removeEventListener('scroll', animate);
}
}
}
export default createScrollManager;
@tylerchilds

This comment has been minimized.

Copy link
Owner Author

@tylerchilds tylerchilds commented Jun 4, 2019

About

To achieve smooth scrolling, we use request animation frame. To avoid calling this unnecessarily, we use scroll event listeners to start the animation loop if the user hasn't scrolled or has stopped scrolling.

Codepen Demo

Basic Usage

Create a Scroll Manager, ideally one per page, using createScrollManager().

  • add(callback: function(scrollPosition) - Add a callback function to be fired every animation loop.
  • remove(callback: function) - Remove a callback function from the Scroll Manager
  • destroy() - Kill the Scroll Manager
const log1 = console.log.bind(null, 1);
const log2 = console.log.bind(null, 2);
const log3 = console.log.bind(null, 3);

const scrollManager = createScrollManager();

scrollManager.add(log1);
scrollManager.add(log2);
scrollManager.add(log3);

scrollManager.remove(log1);

setTimeout(scrollManager.destroy, 5000);
@tylerchilds

This comment has been minimized.

Copy link
Owner Author

@tylerchilds tylerchilds commented Jun 4, 2019

Inspired from this gist: https://gist.github.com/Warry/4254579

@drewbaker

This comment has been minimized.

Copy link

@drewbaker drewbaker commented Apr 26, 2021

Would be nice if this could work with resize too, like scrollManager.add("resize", log1) and scrollManager.add("scroll", log1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment