Open AminRafaey opened 2 years ago
Hi @prevwong! I think you will directly have an idea what the solution could be. Can you give us a hint? Thanks in advance :)
There is nothing I can see to tell to scroll, looking into the code it seems one would need to replicate a drag handler, check scrolling conditions, and scroll the window (or dom element).
I implement my own scroll behavior while dragging.
Viewport.ts
import { throttle } from '../../helper/throttle';
import useWindowDimensions from '../../hooks/useWindowDimensions';
export const Viewport: React.FC = ({ children }) => {
const step = 1;
const scrollRef = useRef<Element | null>(null);
const isScrollRef = useRef<boolean>(false);
const { height } = useWindowDimensions();
const setMove = (state: boolean) => {
isScrollRef.current = state;
};
const moveToTop = () => {
if (scrollRef.current?.scrollTop && isScrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollTop - step;
requestAnimationFrame(moveToTop);
}
};
const moveToBottom = () => {
if (
(scrollRef.current?.scrollTop === 0 || scrollRef.current?.scrollTop) &&
isScrollRef.current
) {
scrollRef.current.scrollTop = scrollRef.current.scrollTop + step;
requestAnimationFrame(moveToBottom);
}
};
const throttledMoveToTop = useRef(throttle(moveToTop, 100)).current;
const throttledMoveToBottom = useRef(throttle(moveToBottom, 100)).current;
useEffect(() => {
scrollRef.current = document.getElementsByClassName('builder__content')[0];
document.addEventListener(
'drag',
function(e) {
e = e || window.event;
const dragY = e.pageY;
//Distance from bottom less then 50px
if (dragY > height - 50) {
setMove(true);
throttledMoveToBottom();
} else if (dragY < 100) {
setMove(true);
throttledMoveToTop();
} else {
setMove(false);
}
},
false
);
document.addEventListener(
'dragend',
function(e) {
setMove(false);
},
false
);
}, []);
return (
<div className="page-container">
<div className={'craftjs-renderer'}>{children}</div>
</div>
);
};
throttle.ts
let inThrottle: boolean;
return function(this: any) {
const args: any = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
};
useWindowDimensions.ts
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowDimensions;
}
Thanks for sharing this @AminRafaey !
Describe the bug Auto scroll to the top of the page does not work while dragging an element.
To Reproduce Steps to reproduce the behavior:
Expected behavior In this video below I would expect an auto-scroll to the top of the page.
Video Demonstration See the video (see expected behavior above) https://www.loom.com/share/984feca6f62448d6b051653aa3b6a375