refactor(autopan): cleanup
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, calcAutoPanVelocity } from '../../utils';
|
import { getHostForElement, calcAutoPan } from '../../utils';
|
||||||
import type { OnConnect, HandleType, ReactFlowState } from '../../types';
|
import type { OnConnect, HandleType, ReactFlowState } from '../../types';
|
||||||
import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph';
|
import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph';
|
||||||
import {
|
import {
|
||||||
@@ -60,6 +60,7 @@ export function handleMouseDown({
|
|||||||
const containerBounds = domNode.getBoundingClientRect();
|
const containerBounds = domNode.getBoundingClientRect();
|
||||||
let prevActiveHandle: Element;
|
let prevActiveHandle: Element;
|
||||||
let connectionPosition = getConnectionPosition(event, containerBounds);
|
let connectionPosition = getConnectionPosition(event, containerBounds);
|
||||||
|
let autoPanStarted = false;
|
||||||
|
|
||||||
const handleLookup = getHandleLookup({
|
const handleLookup = getHandleLookup({
|
||||||
nodes: getNodes(),
|
nodes: getNodes(),
|
||||||
@@ -73,15 +74,12 @@ export function handleMouseDown({
|
|||||||
if (!autoPanOnConnect) {
|
if (!autoPanOnConnect) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const xMovement = calcAutoPanVelocity(connectionPosition.x, 35, containerBounds.width - 35) * 20;
|
const [xMovement, yMovement] = calcAutoPan(connectionPosition, containerBounds);
|
||||||
const yMovement = calcAutoPanVelocity(connectionPosition.y, 35, containerBounds.height - 35) * 20;
|
|
||||||
|
|
||||||
panBy({ x: xMovement, y: yMovement });
|
panBy({ x: xMovement, y: yMovement });
|
||||||
autoPanId = requestAnimationFrame(autoPan);
|
autoPanId = requestAnimationFrame(autoPan);
|
||||||
};
|
};
|
||||||
|
|
||||||
autoPan();
|
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
connectionPosition,
|
connectionPosition,
|
||||||
connectionNodeId: nodeId,
|
connectionNodeId: nodeId,
|
||||||
@@ -95,13 +93,17 @@ export function handleMouseDown({
|
|||||||
const { transform } = getState();
|
const { transform } = getState();
|
||||||
|
|
||||||
connectionPosition = getConnectionPosition(event, containerBounds);
|
connectionPosition = getConnectionPosition(event, containerBounds);
|
||||||
|
|
||||||
prevClosestHandle = getClosestHandle(
|
prevClosestHandle = getClosestHandle(
|
||||||
pointToRendererPoint(connectionPosition, transform, false, [1, 1]),
|
pointToRendererPoint(connectionPosition, transform, false, [1, 1]),
|
||||||
connectionRadius,
|
connectionRadius,
|
||||||
handleLookup
|
handleLookup
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!autoPanStarted) {
|
||||||
|
autoPan();
|
||||||
|
autoPanStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
connectionPosition: prevClosestHandle
|
connectionPosition: prevClosestHandle
|
||||||
? rendererPointToPoint(
|
? rendererPointToPoint(
|
||||||
@@ -138,6 +140,7 @@ export function handleMouseDown({
|
|||||||
|
|
||||||
function onMouseUp(event: MouseEvent) {
|
function onMouseUp(event: MouseEvent) {
|
||||||
cancelAnimationFrame(autoPanId);
|
cancelAnimationFrame(autoPanId);
|
||||||
|
autoPanStarted = false;
|
||||||
|
|
||||||
if (prevClosestHandle) {
|
if (prevClosestHandle) {
|
||||||
const { connection, isValid } = isValidHandle(
|
const { connection, isValid } = isValidHandle(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ 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 { calcAutoPan } from '../../utils';
|
||||||
import type { NodeDragItem, Node, SelectionDragHandler, UseDragEvent, XYPosition } from '../../types';
|
import type { NodeDragItem, Node, SelectionDragHandler, UseDragEvent, XYPosition } from '../../types';
|
||||||
|
|
||||||
export type UseDragData = { dx: number; dy: number };
|
export type UseDragData = { dx: number; dy: number };
|
||||||
@@ -110,8 +110,7 @@ function useDrag({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const xMovement = calcAutoPanVelocity(mousePosition.current.x, 35, containerBounds.current.width - 35) * 20;
|
const [xMovement, yMovement] = calcAutoPan(mousePosition.current, containerBounds.current);
|
||||||
const yMovement = calcAutoPanVelocity(mousePosition.current.y, 35, containerBounds.current.height - 35) * 20;
|
|
||||||
|
|
||||||
if (xMovement !== 0 || yMovement !== 0) {
|
if (xMovement !== 0 || yMovement !== 0) {
|
||||||
const { transform, panBy } = store.getState();
|
const { transform, panBy } = store.getState();
|
||||||
|
|||||||
@@ -16,16 +16,23 @@ 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 calcAutoPanVelocity = (value: number, min: number, max: number): number => {
|
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, 50) / 50;
|
||||||
} else if (value > max) {
|
} else if (value > max) {
|
||||||
return -clamp(Math.abs(value - max), 1, 100) / 100;
|
return -clamp(Math.abs(value - max), 1, 50) / 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const calcAutoPan = (pos: XYPosition, bounds: Dimensions): number[] => {
|
||||||
|
const xMovement = calcAutoPanVelocity(pos.x, 35, bounds.width - 35) * 20;
|
||||||
|
const yMovement = calcAutoPanVelocity(pos.y, 35, bounds.height - 35) * 20;
|
||||||
|
|
||||||
|
return [xMovement, yMovement];
|
||||||
|
};
|
||||||
|
|
||||||
export const getHostForElement = (element: HTMLElement): Document | ShadowRoot =>
|
export const getHostForElement = (element: HTMLElement): Document | ShadowRoot =>
|
||||||
(element.getRootNode?.() as Document | ShadowRoot) || window?.document;
|
(element.getRootNode?.() as Document | ShadowRoot) || window?.document;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user