refactor(autoPan): naming things
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user