diff --git a/.changeset/good-turtles-accept.md b/.changeset/good-turtles-accept.md new file mode 100644 index 00000000..dd01c763 --- /dev/null +++ b/.changeset/good-turtles-accept.md @@ -0,0 +1,5 @@ +--- +"@vue-flow/core": minor +--- + +Add `autoPanSpeed` prop. Allows specifying at what speed the pane moves when auto-panning via node-drag, selection-drag or connection-drag diff --git a/packages/core/src/composables/useDrag.ts b/packages/core/src/composables/useDrag.ts index 052e12db..89024a7f 100644 --- a/packages/core/src/composables/useDrag.ts +++ b/packages/core/src/composables/useDrag.ts @@ -46,6 +46,7 @@ export function useDrag(params: UseDragParams) { nodeDragThreshold, viewport, autoPanOnNodeDrag, + autoPanSpeed, nodesDraggable, panBy, findNode, @@ -132,7 +133,7 @@ export function useDrag(params: UseDragParams) { return } - const [xMovement, yMovement] = calcAutoPan(mousePosition, containerBounds) + const [xMovement, yMovement] = calcAutoPan(mousePosition, containerBounds, autoPanSpeed.value) if (xMovement !== 0 || yMovement !== 0) { const nextPos = { diff --git a/packages/core/src/composables/useHandle.ts b/packages/core/src/composables/useHandle.ts index 65ce20b0..e20f1ad4 100644 --- a/packages/core/src/composables/useHandle.ts +++ b/packages/core/src/composables/useHandle.ts @@ -56,6 +56,7 @@ export function useHandle({ connectionClickStartHandle, nodesConnectable, autoPanOnConnect, + autoPanSpeed, findNode, panBy, startConnection, @@ -120,7 +121,7 @@ export function useHandle({ return } - const [xMovement, yMovement] = calcAutoPan(connectionPosition, containerBounds) + const [xMovement, yMovement] = calcAutoPan(connectionPosition, containerBounds, autoPanSpeed.value) panBy({ x: xMovement, y: yMovement }) autoPanId = requestAnimationFrame(autoPan) diff --git a/packages/core/src/store/state.ts b/packages/core/src/store/state.ts index ba6068a6..4ca356f6 100644 --- a/packages/core/src/store/state.ts +++ b/packages/core/src/store/state.ts @@ -109,6 +109,7 @@ export function useState(): State { autoPanOnNodeDrag: true, autoPanOnConnect: true, + autoPanSpeed: 15, disableKeyboardA11y: false, ariaLiveMessage: '', diff --git a/packages/core/src/types/flow.ts b/packages/core/src/types/flow.ts index 7d5611bb..b6df84d4 100644 --- a/packages/core/src/types/flow.ts +++ b/packages/core/src/types/flow.ts @@ -223,6 +223,7 @@ export interface FlowProps { autoPanOnConnect?: boolean autoPanOnNodeDrag?: boolean + autoPanSpeed?: number } /** diff --git a/packages/core/src/types/store.ts b/packages/core/src/types/store.ts index 1da82be4..ce2053d7 100644 --- a/packages/core/src/types/store.ts +++ b/packages/core/src/types/store.ts @@ -149,6 +149,11 @@ export interface State extends Omit { autoPanOnConnect: boolean autoPanOnNodeDrag: boolean + /** + * The speed at which the viewport pans while dragging a node or a selection box. + * @default 15 + */ + autoPanSpeed: number disableKeyboardA11y: boolean diff --git a/packages/core/src/utils/autopan.ts b/packages/core/src/utils/autopan.ts index f5a7e042..140d698b 100644 --- a/packages/core/src/utils/autopan.ts +++ b/packages/core/src/utils/autopan.ts @@ -5,17 +5,24 @@ import { clamp } from './graph' // when the mouse is close to the edge of the canvas function calcAutoPanVelocity(value: number, min: number, max: number) { if (value < min) { - return clamp(Math.abs(value - min), 1, 50) / 50 - } else if (value > max) { - return -clamp(Math.abs(value - max), 1, 50) / 50 + return clamp(Math.abs(value - min), 1, min) / min + } + + if (value > max) { + return -clamp(Math.abs(value - max), 1, min) / min } return 0 } -export function calcAutoPan(pos: XYPosition, bounds: Dimensions) { - const xMovement = calcAutoPanVelocity(pos.x, 35, bounds.width - 35) * 20 - const yMovement = calcAutoPanVelocity(pos.y, 35, bounds.height - 35) * 20 +export function calcAutoPan( + pos: XYPosition, + bounds: Dimensions, + speed = 15, + distance = 40, +): [xMovement: number, yMovement: number] { + const xMovement = calcAutoPanVelocity(pos.x, distance, bounds.width - distance) * speed + const yMovement = calcAutoPanVelocity(pos.y, distance, bounds.height - distance) * speed return [xMovement, yMovement] }