fix(handles): reconnect for connectionMode=loose #4459

This commit is contained in:
moklick
2024-07-18 13:08:41 +02:00
parent f032638de3
commit 2693a735f0
3 changed files with 35 additions and 18 deletions
+5 -9
View File
@@ -282,16 +282,12 @@ function isValidHandle(
result.isValid = isValid && isValidConnection(connection); result.isValid = isValid && isValidConnection(connection);
if (handleLookup) { const toHandle = handleLookup?.get(`${handleNodeId}-${handleType}-${handleId}`);
const toHandle = handleLookup.find(
(h) => h.id === handleId && h.nodeId === handleNodeId && h.type === handleType
);
if (toHandle) { if (toHandle) {
result.toHandle = { result.toHandle = {
...toHandle, ...toHandle,
}; };
}
} }
} }
+1 -1
View File
@@ -48,7 +48,7 @@ export type IsValidParams = {
doc: Document | ShadowRoot; doc: Document | ShadowRoot;
lib: string; lib: string;
flowId: string | null; flowId: string | null;
handleLookup?: Handle[]; handleLookup?: Map<string, Handle>;
}; };
export type XYHandleInstance = { export type XYHandleInstance = {
+29 -8
View File
@@ -29,11 +29,15 @@ function getHandles(
return [handles, excludedHandle]; return [handles, excludedHandle];
} }
export function getClosestHandle(pos: XYPosition, connectionRadius: number, handles: Handle[]): Handle | null { export function getClosestHandle(
pos: XYPosition,
connectionRadius: number,
handleLookup: Map<string, Handle>
): Handle | null {
let closestHandles: Handle[] = []; let closestHandles: Handle[] = [];
let minDistance = Infinity; let minDistance = Infinity;
for (const handle of handles) { for (const handle of handleLookup.values()) {
const distance = Math.sqrt(Math.pow(handle.x - pos.x, 2) + Math.pow(handle.y - pos.y, 2)); const distance = Math.sqrt(Math.pow(handle.x - pos.x, 2) + Math.pow(handle.y - pos.y, 2));
if (distance <= connectionRadius) { if (distance <= connectionRadius) {
if (distance < minDistance) { if (distance < minDistance) {
@@ -68,21 +72,38 @@ export function getHandleLookup({
nodeId, nodeId,
handleId, handleId,
handleType, handleType,
}: GetHandleLookupParams): [Handle[], Handle] { }: GetHandleLookupParams): [Map<string, Handle>, Handle] {
const connectionHandles: Handle[] = []; const connectionHandles: Map<string, Handle> = new Map();
const currentHandle = { nodeId, handleId, handleType }; const currentHandle = { nodeId, handleId, handleType };
let excludedHandle: Handle | null = null; let matchingHandle: Handle | null = null;
for (const node of nodeLookup.values()) { for (const node of nodeLookup.values()) {
if (node.internals.handleBounds) { if (node.internals.handleBounds) {
const [sourceHandles, excludedSource] = getHandles(node, node.internals.handleBounds, 'source', currentHandle); const [sourceHandles, excludedSource] = getHandles(node, node.internals.handleBounds, 'source', currentHandle);
const [targetHandles, excludedTarget] = getHandles(node, node.internals.handleBounds, 'target', currentHandle); const [targetHandles, excludedTarget] = getHandles(node, node.internals.handleBounds, 'target', currentHandle);
excludedHandle = excludedHandle ? excludedHandle : excludedSource ?? excludedTarget;
connectionHandles.push(...sourceHandles, ...targetHandles); matchingHandle = matchingHandle ? matchingHandle : excludedSource ?? excludedTarget;
[...sourceHandles, ...targetHandles].forEach((handle) =>
connectionHandles.set(`${handle.nodeId}-${handle.type}-${handle.id}`, handle)
);
} }
} }
return [connectionHandles, excludedHandle!]; // if the user only works with handles that are type="source" + connectionMode="loose"
// it happens that we can't find a matching handle. The reason for this is, that the
// edge don't know about the handles and always assumes that there is source and a target.
// In this case we need to find the matching handle by switching the handleType
if (!matchingHandle) {
const node = nodeLookup.get(nodeId);
if (node?.internals.handleBounds) {
currentHandle.handleType = handleType === 'source' ? 'target' : 'source';
const [, excluded] = getHandles(node, node.internals.handleBounds, currentHandle.handleType, currentHandle);
matchingHandle = excluded;
}
}
return [connectionHandles, matchingHandle!];
} }
export function getHandleType( export function getHandleType(