Skip to content

Instantly share code, notes, and snippets.

@orlandovallejos
Created November 12, 2019 17:37
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save orlandovallejos/ed9c79dd67e96c25cfcc8f1008df9489 to your computer and use it in GitHub Desktop.
Save orlandovallejos/ed9c79dd67e96c25cfcc8f1008df9489 to your computer and use it in GitHub Desktop.
scrolling helper for react-dnd ^9.4.0
/*------------------------------------------------*/
/* LIBRARIES
/*------------------------------------------------*/
import throttle from 'lodash/throttle';
/*------------------------------------------------*/
/* INTERNAL DEPENDENCIES
/*------------------------------------------------*/
import { MAIN_APP_SIDEBAR_ID } from '../../constants/global';
/*------------------------------------------------*/
/* CONSTANTS
/*------------------------------------------------*/
const OFFSET = 50;
const PX_DIFF = 3;
/*------------------------------------------------*/
/* GLOBAL VARIABLES
/*------------------------------------------------*/
let scrollIncrement = 0;
let isScrolling = false;
let sidebarElement = null;
/*------------------------------------------------*/
/* METHODS
/*------------------------------------------------*/
/**
* Scroll up in the sidebar.
*/
const goUp = () => {
scrollIncrement -= PX_DIFF;
sidebarElement.scrollTop = scrollIncrement;
if (isScrolling && scrollIncrement >= 0) {
window.requestAnimationFrame(goUp);
}
};
/**
* Scroll down in the sidebar.
*/
const goDown = () => {
scrollIncrement += PX_DIFF;
sidebarElement.scrollTop = scrollIncrement;
if (isScrolling && scrollIncrement <= sidebarElement.scrollHeight) {
window.requestAnimationFrame(goDown);
}
};
const onDragOver = (event) => {
const clientRect = sidebarElement.getBoundingClientRect();
const isMouseOnTop = (
scrollIncrement >= 0 && event.clientY > clientRect.top
&& event.clientY < (clientRect.top + OFFSET)
);
const isMouseOnBottom = (
scrollIncrement <= sidebarElement.scrollHeight
&& event.clientY > (window.innerHeight - OFFSET)
&& event.clientY <= window.innerHeight
);
if (!isScrolling && (isMouseOnTop || isMouseOnBottom)) {
isScrolling = true;
scrollIncrement = sidebarElement.scrollTop;
if (isMouseOnTop) {
window.requestAnimationFrame(goUp);
}
else {
window.requestAnimationFrame(goDown);
}
}
else if (!isMouseOnTop && !isMouseOnBottom) {
isScrolling = false;
}
};
/**
* The "throttle" method prevents executing the same function SO MANY times.
*/
const throttleOnDragOver = throttle(onDragOver, 300);
// IMPORTANT: CALL THIS METHOD IN: beginDrag!!!
const addEventListenerForSidebar = () => {
sidebarElement = document.getElementById(MAIN_APP_SIDEBAR_ID);
sidebarElement.addEventListener('dragover', throttleOnDragOver);
};
// IMPORTANT: CALL THIS METHOD IN: endDrag!!!
const removeEventListenerForSidebar = () => {
sidebarElement.removeEventListener('dragover', throttleOnDragOver);
isScrolling = false;
};
/*------------------------------------------------*/
/* EXPORTS
/*------------------------------------------------*/
export default {
addEventListenerForSidebar,
removeEventListenerForSidebar
};
@alfonmga
Copy link

God bless you, you are the man!

@yaswanthmaddula-sureify

It doesn't work now for chrome as well

@paul-mesnilgrente
Copy link

Is it possible to have this working on the view port edges?

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