refactor(nodes): use-d3drag

This commit is contained in:
moklick
2022-04-13 11:19:17 +02:00
parent 3bd756d8a6
commit f2004fe45a
11 changed files with 154 additions and 181 deletions
+56
View File
@@ -0,0 +1,56 @@
import { RefObject, useEffect } from 'react';
import { D3DragEvent, drag, SubjectPosition } from 'd3-drag';
import { select } from 'd3-selection';
import { useStoreApi } from '../../store';
export type UseDragEvent = D3DragEvent<HTMLDivElement, null, SubjectPosition>;
export type UseDragData = { dx: number; dy: number };
type UseDragParams = {
onStart: (event: UseDragEvent) => void;
onDrag: (event: UseDragEvent, data: UseDragData) => void;
onStop: (event: UseDragEvent) => void;
nodeRef: RefObject<Element>;
disabled?: boolean;
noDragClassName?: string;
// @TODO: implement handleSelector functionality
handleSelector?: string;
};
function useDrag({ onStart, onDrag, onStop, nodeRef, disabled = false, noDragClassName }: UseDragParams) {
const store = useStoreApi();
useEffect(() => {
if (nodeRef?.current) {
const selection = select(nodeRef.current);
if (disabled) {
selection.on('.drag', null);
} else {
const dragHandler = drag()
.on('start', onStart)
.on('drag', (event: UseDragEvent) => {
const [, , scale] = store.getState().transform;
// @TODO: we need to use snapGrid and snapToGrid from the store here
// @TODO: don't use event.dx but work with event.x somehow in order to prevent lagging / slower node movement than mouse movement
onDrag(event, { dx: event.dx / scale, dy: event.dy / scale });
})
.on('end', onStop)
.filter((event: any) => !event.ctrlKey && !event.button && !event.target.className.includes(noDragClassName));
selection.call(dragHandler);
return () => {
selection.on('.drag', null);
};
}
}
}, [disabled, noDragClassName]);
return null;
}
export default useDrag;