first commit
This commit is contained in:
72
src/component/FileManager/Dnd/useDndScrolling.ts
Executable file
72
src/component/FileManager/Dnd/useDndScrolling.ts
Executable file
@@ -0,0 +1,72 @@
|
||||
import { useRef } from "react";
|
||||
import { throttle } from "lodash";
|
||||
|
||||
const threshold = 0.1;
|
||||
|
||||
const useDragScrolling = (containers: string[]) => {
|
||||
const isScrolling = useRef(false);
|
||||
const targets = containers.map((id) => document.querySelector(id) as HTMLElement);
|
||||
const rects = useRef<DOMRect[]>([]);
|
||||
|
||||
const goDown = (target: HTMLElement) => {
|
||||
return () => {
|
||||
target.scrollTop += 5;
|
||||
|
||||
const { offsetHeight, scrollTop, scrollHeight } = target;
|
||||
const isScrollEnd = offsetHeight + scrollTop >= scrollHeight;
|
||||
|
||||
if (isScrolling.current && !isScrollEnd) {
|
||||
window.requestAnimationFrame(goDown(target));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const goUp = (target: HTMLElement) => {
|
||||
return () => {
|
||||
target.scrollTop -= 5;
|
||||
if (isScrolling.current && target.scrollTop > 0) {
|
||||
window.requestAnimationFrame(goUp(target));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const onDragOver = (event: MouseEvent) => {
|
||||
// detect if mouse is in any rect
|
||||
rects.current.forEach((rect, index) => {
|
||||
if (event.clientX < rect.left || event.clientX > rect.right) {
|
||||
isScrolling.current = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const height = rect.bottom - rect.top;
|
||||
if (event.clientY > rect.top && event.clientY < rect.top + threshold * height) {
|
||||
isScrolling.current = true;
|
||||
window.requestAnimationFrame(goUp(targets[index]));
|
||||
} else if (event.clientY < rect.bottom && event.clientY > rect.bottom - threshold * height) {
|
||||
isScrolling.current = true;
|
||||
window.requestAnimationFrame(goDown(targets[index]));
|
||||
} else {
|
||||
isScrolling.current = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const throttleOnDragOver = throttle(onDragOver, 300);
|
||||
|
||||
const addEventListenerForWindow = () => {
|
||||
rects.current = targets.map((t) => t.getBoundingClientRect());
|
||||
window.addEventListener("dragover", throttleOnDragOver, false);
|
||||
};
|
||||
|
||||
const removeEventListenerForWindow = () => {
|
||||
window.removeEventListener("dragover", throttleOnDragOver, false);
|
||||
isScrolling.current = false;
|
||||
};
|
||||
|
||||
return {
|
||||
addEventListenerForWindow,
|
||||
removeEventListenerForWindow,
|
||||
};
|
||||
};
|
||||
|
||||
export default useDragScrolling;
|
||||
Reference in New Issue
Block a user