refactor(autoPan): naming things

This commit is contained in:
moklick
2023-01-17 17:38:21 +01:00
parent f2a4260ac9
commit 1d036b2575
3 changed files with 35 additions and 36 deletions
+12 -12
View File
@@ -1,7 +1,7 @@
import type { MouseEvent as ReactMouseEvent } from 'react'; import type { MouseEvent as ReactMouseEvent } from 'react';
import { StoreApi } from 'zustand'; import { StoreApi } from 'zustand';
import { getHostForElement, getVelocity } from '../../utils'; import { getHostForElement, calcAutoPanVelocity } from '../../utils';
import { ConnectionMode } from '../../types'; import { ConnectionMode } from '../../types';
import type { OnConnect, Connection, HandleType, ReactFlowState, XYPosition } from '../../types'; import type { OnConnect, Connection, HandleType, ReactFlowState, XYPosition } from '../../types';
@@ -100,21 +100,21 @@ export function handleMouseDown({
}): void { }): void {
// when react-flow is used inside a shadow root we can't use document // when react-flow is used inside a shadow root we can't use document
const doc = getHostForElement(event.target as HTMLElement); const doc = getHostForElement(event.target as HTMLElement);
const { onConnectStart, connectionMode, domNode, autoPanOnConnect } = getState(); const { onConnectStart, movePane, connectionMode, domNode, autoPanOnConnect } = getState();
let connectionPosition: XYPosition | null = null; let connectionPosition: XYPosition = { x: 0, y: 0 };
let requestAnimationFrameId = 0; let autoPanId = 0;
// when the user is moving the mouse close to the edge of the canvas while connecting we move the canvas // when the user is moving the mouse close to the edge of the canvas while connecting we move the canvas
const updateViewport = (): void => { const autoPan = (): void => {
if (!connectionPosition || !containerBounds || !autoPanOnConnect) { if (!containerBounds || !autoPanOnConnect) {
return; return;
} }
const xMovement = getVelocity(connectionPosition.x, 35, containerBounds.width - 35) * 20; const xMovement = calcAutoPanVelocity(connectionPosition.x, 35, containerBounds.width - 35) * 20;
const yMovement = getVelocity(connectionPosition.y, 35, containerBounds.height - 35) * 20; const yMovement = calcAutoPanVelocity(connectionPosition.y, 35, containerBounds.height - 35) * 20;
getState().movePane({ x: xMovement, y: yMovement }); movePane({ x: xMovement, y: yMovement });
requestAnimationFrameId = requestAnimationFrame(updateViewport); autoPanId = requestAnimationFrame(autoPan);
}; };
if (!doc || !domNode) { if (!doc || !domNode) {
@@ -138,7 +138,7 @@ export function handleMouseDown({
y: event.clientY - containerBounds.top, y: event.clientY - containerBounds.top,
}; };
updateViewport(); autoPan();
setState({ setState({
connectionPosition, connectionPosition,
@@ -181,7 +181,7 @@ export function handleMouseDown({
} }
function onMouseUp(event: MouseEvent) { function onMouseUp(event: MouseEvent) {
cancelAnimationFrame(requestAnimationFrameId); cancelAnimationFrame(autoPanId);
const { connection, isValid } = checkElementBelowIsValid( const { connection, isValid } = checkElementBelowIsValid(
event, event,
+22 -23
View File
@@ -7,8 +7,8 @@ import { useStoreApi } from '../../hooks/useStore';
import { getDragItems, getEventHandlerParams, hasSelector, calcNextPosition } from './utils'; import { getDragItems, getEventHandlerParams, hasSelector, calcNextPosition } from './utils';
import { handleNodeClick } from '../../components/Nodes/utils'; import { handleNodeClick } from '../../components/Nodes/utils';
import useGetPointerPosition from '../useGetPointerPosition'; import useGetPointerPosition from '../useGetPointerPosition';
import { calcAutoPanVelocity } from '../../utils';
import type { NodeDragItem, Node, SelectionDragHandler, UseDragEvent, XYPosition } from '../../types'; import type { NodeDragItem, Node, SelectionDragHandler, UseDragEvent, XYPosition } from '../../types';
import { getVelocity } from '../../utils';
export type UseDragData = { dx: number; dy: number }; export type UseDragData = { dx: number; dy: number };
@@ -35,15 +35,15 @@ function useDrag({
isSelectable, isSelectable,
selectNodesOnDrag, selectNodesOnDrag,
}: UseDragParams) { }: UseDragParams) {
const [dragging, setDragging] = useState<boolean>(false);
const store = useStoreApi(); const store = useStoreApi();
const dragItems = useRef<NodeDragItem[]>(); const [dragging, setDragging] = useState<boolean>(false);
const dragItems = useRef<NodeDragItem[]>([]);
const lastPos = useRef<{ x: number | null; y: number | null }>({ x: null, y: null }); const lastPos = useRef<{ x: number | null; y: number | null }>({ x: null, y: null });
const requestAnimationFrameId = useRef(0); const autoPanId = useRef(0);
const containerBounds = useRef<DOMRect | null>(null); const containerBounds = useRef<DOMRect | null>(null);
const centerPosition = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); const mousePosition = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
const dragEvent = useRef<MouseEvent | null>(null); const dragEvent = useRef<MouseEvent | null>(null);
const animationFrameStarted = useRef(false); const autoPanStarted = useRef(false);
const getPointerPosition = useGetPointerPosition(); const getPointerPosition = useGetPointerPosition();
@@ -67,7 +67,7 @@ function useDrag({
let hasChange = false; let hasChange = false;
dragItems.current = dragItems.current!.map((n) => { dragItems.current = dragItems.current.map((n) => {
const nextPosition = { x: x - n.distance.x, y: y - n.distance.y }; const nextPosition = { x: x - n.distance.x, y: y - n.distance.y };
if (snapToGrid) { if (snapToGrid) {
@@ -105,25 +105,24 @@ function useDrag({
} }
}; };
const updateViewport = (): void => { const autoPan = (): void => {
if (!containerBounds.current) { if (!containerBounds.current) {
return; return;
} }
const xMovement = getVelocity(centerPosition.current.x, 35, containerBounds.current.width - 35) * 20; const xMovement = calcAutoPanVelocity(mousePosition.current.x, 35, containerBounds.current.width - 35) * 20;
const yMovement = getVelocity(centerPosition.current.y, 35, containerBounds.current.height - 35) * 20; const yMovement = calcAutoPanVelocity(mousePosition.current.y, 35, containerBounds.current.height - 35) * 20;
if (xMovement !== 0 || yMovement !== 0) { if (xMovement !== 0 || yMovement !== 0) {
const scale = store.getState().transform[2]; const { transform, movePane } = store.getState();
lastPos.current.x = (lastPos.current.x ?? 0) - xMovement / scale; lastPos.current.x = (lastPos.current.x ?? 0) - xMovement / transform[2];
lastPos.current.y = (lastPos.current.y ?? 0) - yMovement / scale; lastPos.current.y = (lastPos.current.y ?? 0) - yMovement / transform[2];
updateNodes(lastPos.current as XYPosition); updateNodes(lastPos.current as XYPosition);
movePane({ x: xMovement, y: yMovement });
store.getState().movePane({ x: xMovement, y: yMovement });
} }
requestAnimationFrameId.current = requestAnimationFrame(updateViewport); autoPanId.current = requestAnimationFrame(autoPan);
}; };
if (disabled) { if (disabled) {
@@ -170,7 +169,7 @@ function useDrag({
} }
containerBounds.current = domNode?.getBoundingClientRect() || null; containerBounds.current = domNode?.getBoundingClientRect() || null;
centerPosition.current = { mousePosition.current = {
x: event.sourceEvent.clientX - (containerBounds.current?.left ?? 0), x: event.sourceEvent.clientX - (containerBounds.current?.left ?? 0),
y: event.sourceEvent.clientY - (containerBounds.current?.top ?? 0), y: event.sourceEvent.clientY - (containerBounds.current?.top ?? 0),
}; };
@@ -179,9 +178,9 @@ function useDrag({
const pointerPos = getPointerPosition(event); const pointerPos = getPointerPosition(event);
const { autoPanOnNodeDrag } = store.getState(); const { autoPanOnNodeDrag } = store.getState();
if (!animationFrameStarted.current && autoPanOnNodeDrag) { if (!autoPanStarted.current && autoPanOnNodeDrag) {
animationFrameStarted.current = true; autoPanStarted.current = true;
updateViewport(); autoPan();
} }
// skip events without movement // skip events without movement
@@ -190,7 +189,7 @@ function useDrag({
dragItems.current dragItems.current
) { ) {
dragEvent.current = event.sourceEvent as MouseEvent; dragEvent.current = event.sourceEvent as MouseEvent;
centerPosition.current = { mousePosition.current = {
x: event.sourceEvent.clientX - (containerBounds.current?.left ?? 0), x: event.sourceEvent.clientX - (containerBounds.current?.left ?? 0),
y: event.sourceEvent.clientY - (containerBounds.current?.top ?? 0), y: event.sourceEvent.clientY - (containerBounds.current?.top ?? 0),
}; };
@@ -200,8 +199,8 @@ function useDrag({
}) })
.on('end', (event: UseDragEvent) => { .on('end', (event: UseDragEvent) => {
setDragging(false); setDragging(false);
animationFrameStarted.current = false; autoPanStarted.current = false;
cancelAnimationFrame(requestAnimationFrameId.current); cancelAnimationFrame(autoPanId.current);
if (dragItems.current) { if (dragItems.current) {
const { updateNodePositions, nodeInternals, onNodeDragStop, onSelectionDragStop } = store.getState(); const { updateNodePositions, nodeInternals, onNodeDragStop, onSelectionDragStop } = store.getState();
+1 -1
View File
@@ -16,7 +16,7 @@ export const clampPosition = (position: XYPosition = { x: 0, y: 0 }, extent: Coo
// returns a number between 0 and 1 that represents the velocity of the movement // returns a number between 0 and 1 that represents the velocity of the movement
// when the mouse is close to the edge of the canvas // when the mouse is close to the edge of the canvas
export const getVelocity = (value: number, min: number, max: number): number => { export const calcAutoPanVelocity = (value: number, min: number, max: number): number => {
if (value < min) { if (value < min) {
return clamp(Math.abs(value - min), 1, 100) / 100; return clamp(Math.abs(value - min), 1, 100) / 100;
} else if (value > max) { } else if (value > max) {