From 1d036b2575f566b388ceb152d999ac6efabf31c3 Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 17 Jan 2023 17:38:21 +0100 Subject: [PATCH] refactor(autoPan): naming things --- .../core/src/components/Handle/handler.ts | 24 +++++----- packages/core/src/hooks/useDrag/index.ts | 45 +++++++++---------- packages/core/src/utils/index.ts | 2 +- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/packages/core/src/components/Handle/handler.ts b/packages/core/src/components/Handle/handler.ts index b8493a8b..e5cafd21 100644 --- a/packages/core/src/components/Handle/handler.ts +++ b/packages/core/src/components/Handle/handler.ts @@ -1,7 +1,7 @@ import type { MouseEvent as ReactMouseEvent } from 'react'; import { StoreApi } from 'zustand'; -import { getHostForElement, getVelocity } from '../../utils'; +import { getHostForElement, calcAutoPanVelocity } from '../../utils'; import { ConnectionMode } from '../../types'; import type { OnConnect, Connection, HandleType, ReactFlowState, XYPosition } from '../../types'; @@ -100,21 +100,21 @@ export function handleMouseDown({ }): void { // when react-flow is used inside a shadow root we can't use document const doc = getHostForElement(event.target as HTMLElement); - const { onConnectStart, connectionMode, domNode, autoPanOnConnect } = getState(); - let connectionPosition: XYPosition | null = null; - let requestAnimationFrameId = 0; + const { onConnectStart, movePane, connectionMode, domNode, autoPanOnConnect } = getState(); + let connectionPosition: XYPosition = { x: 0, y: 0 }; + let autoPanId = 0; // when the user is moving the mouse close to the edge of the canvas while connecting we move the canvas - const updateViewport = (): void => { - if (!connectionPosition || !containerBounds || !autoPanOnConnect) { + const autoPan = (): void => { + if (!containerBounds || !autoPanOnConnect) { return; } - const xMovement = getVelocity(connectionPosition.x, 35, containerBounds.width - 35) * 20; - const yMovement = getVelocity(connectionPosition.y, 35, containerBounds.height - 35) * 20; + const xMovement = calcAutoPanVelocity(connectionPosition.x, 35, containerBounds.width - 35) * 20; + const yMovement = calcAutoPanVelocity(connectionPosition.y, 35, containerBounds.height - 35) * 20; - getState().movePane({ x: xMovement, y: yMovement }); - requestAnimationFrameId = requestAnimationFrame(updateViewport); + movePane({ x: xMovement, y: yMovement }); + autoPanId = requestAnimationFrame(autoPan); }; if (!doc || !domNode) { @@ -138,7 +138,7 @@ export function handleMouseDown({ y: event.clientY - containerBounds.top, }; - updateViewport(); + autoPan(); setState({ connectionPosition, @@ -181,7 +181,7 @@ export function handleMouseDown({ } function onMouseUp(event: MouseEvent) { - cancelAnimationFrame(requestAnimationFrameId); + cancelAnimationFrame(autoPanId); const { connection, isValid } = checkElementBelowIsValid( event, diff --git a/packages/core/src/hooks/useDrag/index.ts b/packages/core/src/hooks/useDrag/index.ts index 1333666d..56fece93 100644 --- a/packages/core/src/hooks/useDrag/index.ts +++ b/packages/core/src/hooks/useDrag/index.ts @@ -7,8 +7,8 @@ import { useStoreApi } from '../../hooks/useStore'; import { getDragItems, getEventHandlerParams, hasSelector, calcNextPosition } from './utils'; import { handleNodeClick } from '../../components/Nodes/utils'; import useGetPointerPosition from '../useGetPointerPosition'; +import { calcAutoPanVelocity } from '../../utils'; import type { NodeDragItem, Node, SelectionDragHandler, UseDragEvent, XYPosition } from '../../types'; -import { getVelocity } from '../../utils'; export type UseDragData = { dx: number; dy: number }; @@ -35,15 +35,15 @@ function useDrag({ isSelectable, selectNodesOnDrag, }: UseDragParams) { - const [dragging, setDragging] = useState(false); const store = useStoreApi(); - const dragItems = useRef(); + const [dragging, setDragging] = useState(false); + const dragItems = useRef([]); const lastPos = useRef<{ x: number | null; y: number | null }>({ x: null, y: null }); - const requestAnimationFrameId = useRef(0); + const autoPanId = useRef(0); const containerBounds = useRef(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(null); - const animationFrameStarted = useRef(false); + const autoPanStarted = useRef(false); const getPointerPosition = useGetPointerPosition(); @@ -67,7 +67,7 @@ function useDrag({ 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 }; if (snapToGrid) { @@ -105,25 +105,24 @@ function useDrag({ } }; - const updateViewport = (): void => { + const autoPan = (): void => { if (!containerBounds.current) { return; } - const xMovement = getVelocity(centerPosition.current.x, 35, containerBounds.current.width - 35) * 20; - const yMovement = getVelocity(centerPosition.current.y, 35, containerBounds.current.height - 35) * 20; + const xMovement = calcAutoPanVelocity(mousePosition.current.x, 35, containerBounds.current.width - 35) * 20; + const yMovement = calcAutoPanVelocity(mousePosition.current.y, 35, containerBounds.current.height - 35) * 20; 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.y = (lastPos.current.y ?? 0) - yMovement / scale; + lastPos.current.x = (lastPos.current.x ?? 0) - xMovement / transform[2]; + lastPos.current.y = (lastPos.current.y ?? 0) - yMovement / transform[2]; updateNodes(lastPos.current as XYPosition); - - store.getState().movePane({ x: xMovement, y: yMovement }); + movePane({ x: xMovement, y: yMovement }); } - requestAnimationFrameId.current = requestAnimationFrame(updateViewport); + autoPanId.current = requestAnimationFrame(autoPan); }; if (disabled) { @@ -170,7 +169,7 @@ function useDrag({ } containerBounds.current = domNode?.getBoundingClientRect() || null; - centerPosition.current = { + mousePosition.current = { x: event.sourceEvent.clientX - (containerBounds.current?.left ?? 0), y: event.sourceEvent.clientY - (containerBounds.current?.top ?? 0), }; @@ -179,9 +178,9 @@ function useDrag({ const pointerPos = getPointerPosition(event); const { autoPanOnNodeDrag } = store.getState(); - if (!animationFrameStarted.current && autoPanOnNodeDrag) { - animationFrameStarted.current = true; - updateViewport(); + if (!autoPanStarted.current && autoPanOnNodeDrag) { + autoPanStarted.current = true; + autoPan(); } // skip events without movement @@ -190,7 +189,7 @@ function useDrag({ dragItems.current ) { dragEvent.current = event.sourceEvent as MouseEvent; - centerPosition.current = { + mousePosition.current = { x: event.sourceEvent.clientX - (containerBounds.current?.left ?? 0), y: event.sourceEvent.clientY - (containerBounds.current?.top ?? 0), }; @@ -200,8 +199,8 @@ function useDrag({ }) .on('end', (event: UseDragEvent) => { setDragging(false); - animationFrameStarted.current = false; - cancelAnimationFrame(requestAnimationFrameId.current); + autoPanStarted.current = false; + cancelAnimationFrame(autoPanId.current); if (dragItems.current) { const { updateNodePositions, nodeInternals, onNodeDragStop, onSelectionDragStop } = store.getState(); diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 7a2b6203..2364f352 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -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 // 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) { return clamp(Math.abs(value - min), 1, 100) / 100; } else if (value > max) {