refactor(core): pick target handle if handles are on top of each other
Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
@@ -65,7 +65,7 @@ export default function useHandle({
|
|||||||
isValidConnectionHandler = (!isTarget ? node.isValidTargetPos : node.isValidSourcePos) || alwaysValid
|
isValidConnectionHandler = (!isTarget ? node.isValidTargetPos : node.isValidSourcePos) || alwaysValid
|
||||||
}
|
}
|
||||||
|
|
||||||
let prevClosestHandle: ConnectionHandle | null
|
let closestHandle: ConnectionHandle | null
|
||||||
|
|
||||||
let autoPanId = 0
|
let autoPanId = 0
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ export default function useHandle({
|
|||||||
function onPointerMove(event: MouseTouchEvent) {
|
function onPointerMove(event: MouseTouchEvent) {
|
||||||
connectionPosition = getEventPosition(event, containerBounds)
|
connectionPosition = getEventPosition(event, containerBounds)
|
||||||
|
|
||||||
prevClosestHandle = getClosestHandle(
|
closestHandle = getClosestHandle(
|
||||||
pointToRendererPoint(connectionPosition, viewport.value, false, [1, 1]),
|
pointToRendererPoint(connectionPosition, viewport.value, false, [1, 1]),
|
||||||
connectionRadius.value,
|
connectionRadius.value,
|
||||||
handleLookup,
|
handleLookup,
|
||||||
@@ -132,7 +132,7 @@ export default function useHandle({
|
|||||||
|
|
||||||
const result = isValidHandle(
|
const result = isValidHandle(
|
||||||
event,
|
event,
|
||||||
prevClosestHandle,
|
closestHandle,
|
||||||
connectionMode.value,
|
connectionMode.value,
|
||||||
resolveUnref(nodeId),
|
resolveUnref(nodeId),
|
||||||
resolveUnref(handleId),
|
resolveUnref(handleId),
|
||||||
@@ -148,20 +148,20 @@ export default function useHandle({
|
|||||||
handleDomNode = result.handleDomNode
|
handleDomNode = result.handleDomNode
|
||||||
|
|
||||||
updateConnection(
|
updateConnection(
|
||||||
prevClosestHandle && isValid
|
closestHandle && isValid
|
||||||
? rendererPointToPoint(
|
? rendererPointToPoint(
|
||||||
{
|
{
|
||||||
x: prevClosestHandle.x,
|
x: closestHandle.x,
|
||||||
y: prevClosestHandle.y,
|
y: closestHandle.y,
|
||||||
},
|
},
|
||||||
viewport.value,
|
viewport.value,
|
||||||
)
|
)
|
||||||
: connectionPosition,
|
: connectionPosition,
|
||||||
result.endHandle,
|
result.endHandle,
|
||||||
getConnectionStatus(!!prevClosestHandle, isValid),
|
getConnectionStatus(!!closestHandle, isValid),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!prevClosestHandle && !isValid && !handleDomNode) {
|
if (!closestHandle && !isValid && !handleDomNode) {
|
||||||
return resetRecentHandle(prevActiveHandle)
|
return resetRecentHandle(prevActiveHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ export default function useHandle({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onPointerUp(event: MouseTouchEvent) {
|
function onPointerUp(event: MouseTouchEvent) {
|
||||||
if ((prevClosestHandle || handleDomNode) && connection && isValid) {
|
if ((closestHandle || handleDomNode) && connection && isValid) {
|
||||||
if (!onEdgeUpdate) {
|
if (!onEdgeUpdate) {
|
||||||
emits.connect(connection)
|
emits.connect(connection)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -57,18 +57,31 @@ export function getClosestHandle(
|
|||||||
connectionRadius: number,
|
connectionRadius: number,
|
||||||
handles: ConnectionHandle[],
|
handles: ConnectionHandle[],
|
||||||
): ConnectionHandle | null {
|
): ConnectionHandle | null {
|
||||||
let closestHandle: ConnectionHandle | null = null
|
let closestHandles: ConnectionHandle[] = []
|
||||||
let minDistance = Infinity
|
let minDistance = Infinity
|
||||||
|
|
||||||
handles.forEach((handle) => {
|
handles.forEach((handle) => {
|
||||||
const distance = Math.sqrt((handle.x - pos.x) ** 2 + (handle.y - pos.y) ** 2)
|
const distance = Math.sqrt((handle.x - pos.x) ** 2 + (handle.y - pos.y) ** 2)
|
||||||
if (distance <= connectionRadius && distance < minDistance) {
|
if (distance <= connectionRadius) {
|
||||||
|
if (distance < minDistance) {
|
||||||
|
closestHandles = [handle]
|
||||||
|
} else if (distance === minDistance) {
|
||||||
|
// when multiple handles are on the same distance we collect all of them
|
||||||
|
closestHandles.push(handle)
|
||||||
|
}
|
||||||
|
|
||||||
minDistance = distance
|
minDistance = distance
|
||||||
closestHandle = handle
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return closestHandle
|
if (!closestHandles.length) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return closestHandles.length === 1
|
||||||
|
? closestHandles[0]
|
||||||
|
: // if multiple handles are layout on top of each other we take the one with type = target because it's more likely that the user wants to connect to this one
|
||||||
|
closestHandles.find((handle) => handle.type === 'target') || closestHandles[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if and returns connection in fom of an object { source: 123, target: 312 }
|
// checks if and returns connection in fom of an object { source: 123, target: 312 }
|
||||||
@@ -89,6 +102,9 @@ export function isValidHandle(
|
|||||||
const handleDomNode = doc.querySelector(`.vue-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]`)
|
const handleDomNode = doc.querySelector(`.vue-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]`)
|
||||||
const { x, y } = getEventPosition(event)
|
const { x, y } = getEventPosition(event)
|
||||||
const handleBelow = doc.elementFromPoint(x, y)
|
const handleBelow = doc.elementFromPoint(x, y)
|
||||||
|
|
||||||
|
// we always want to prioritize the handle below the mouse cursor over the closest distance handle,
|
||||||
|
// because it could be that the center of another handle is closer to the mouse pointer than the handle below the cursor
|
||||||
const handleToCheck = handleBelow?.classList.contains('vue-flow__handle') ? handleBelow : handleDomNode
|
const handleToCheck = handleBelow?.classList.contains('vue-flow__handle') ? handleBelow : handleDomNode
|
||||||
|
|
||||||
const result: ValidHandleResult = {
|
const result: ValidHandleResult = {
|
||||||
|
|||||||
Reference in New Issue
Block a user