diff --git a/packages/core/src/composables/useHandle.ts b/packages/core/src/composables/useHandle.ts index 6c0f1fe7..b4a6c90d 100644 --- a/packages/core/src/composables/useHandle.ts +++ b/packages/core/src/composables/useHandle.ts @@ -35,7 +35,9 @@ export default function useHandle({ connectionClickStartHandle, nodesConnectable, defaultEdgeOptions, + autoPanOnConnect, findNode, + panBy, getNodes, startConnection, updateConnection, @@ -61,6 +63,8 @@ export default function useHandle({ let prevClosestHandle: ConnectionHandle | null + let autoPanId = 0 + const { x, y } = getEventPosition(event) const clickedHandle = doc?.elementFromPoint(x, y) const handleType = getHandleType(unref(edgeUpdaterType), clickedHandle) @@ -72,6 +76,7 @@ export default function useHandle({ let prevActiveHandle: Element let connectionPosition = getEventPosition(event, containerBounds) + let autoPanStarted = false const handleLookup = getHandleLookup({ nodes: getNodes.value, @@ -80,6 +85,17 @@ export default function useHandle({ handleType, }) + // when the user is moving the mouse close to the edge of the canvas while connecting we move the canvas + const autoPan = () => { + if (!autoPanOnConnect) { + return + } + const [xMovement, yMovement] = calcAutoPan(connectionPosition, containerBounds) + + panBy({ x: xMovement, y: yMovement }) + autoPanId = requestAnimationFrame(autoPan) + } + startConnection( { nodeId: unref(nodeId), @@ -104,6 +120,11 @@ export default function useHandle({ handleLookup, ) + if (!autoPanStarted) { + autoPan() + autoPanStarted = true + } + const { connection, handleDomNode, isValid } = isValidHandle( event, prevClosestHandle, @@ -140,6 +161,9 @@ export default function useHandle({ } function onPointerUp(event: MouseEvent | TouchEvent) { + cancelAnimationFrame(autoPanId) + autoPanStarted = false + if (prevClosestHandle) { const { connection, isValid } = isValidHandle( event,