fix(core): use center position of handle as snapping point for connection lines (#1625)

* fix(core): calculate handle positions correctly

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* fix(core): remove handleId check

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* chore(core): cleanup

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* chore(core): cleanup click connect handlers

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* fix(core): add flow id to handle ids

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* tests: correct updateEdge test

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* fix(core): use center position of handle

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* chore(examples): cleanup easy connect example

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* refactor(tests): run actions on chrome

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* chore(workflows): correctly hash lock file

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

---------

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
Braks
2025-01-04 16:56:00 +01:00
parent 041fd871a1
commit b33da47a3a
16 changed files with 385 additions and 312 deletions
@@ -1,18 +1,11 @@
import { computed, defineComponent, h, inject } from 'vue'
import type { HandleElement } from '../../types'
import { ConnectionLineType, ConnectionMode, Position } from '../../types'
import { getHandlePosition, getMarkerId } from '../../utils'
import { getHandlePosition, getMarkerId, oppositePosition } from '../../utils'
import { useVueFlow } from '../../composables'
import { Slots } from '../../context'
import { getBezierPath, getSimpleBezierPath, getSmoothStepPath } from '../Edges/utils'
const oppositePosition = {
[Position.Left]: Position.Right,
[Position.Right]: Position.Left,
[Position.Top]: Position.Bottom,
[Position.Bottom]: Position.Top,
}
const ConnectionLine = defineComponent({
name: 'ConnectionLine',
compatConfig: { MODE: 3 },
@@ -57,7 +50,7 @@ const ConnectionLine = defineComponent({
return null
}
const startHandleId = connectionStartHandle.value.handleId
const startHandleId = connectionStartHandle.value.id
const handleType = connectionStartHandle.value.type
@@ -78,18 +71,18 @@ const ConnectionLine = defineComponent({
const { x: fromX, y: fromY } = getHandlePosition(fromNode.value, fromHandle, fromPosition)
let toHandle: HandleElement | null = null
if (toNode.value && connectionEndHandle.value?.handleId) {
if (toNode.value) {
// if connection mode is strict, we only look for handles of the opposite type
if (connectionMode.value === ConnectionMode.Strict) {
toHandle =
toNode.value.handleBounds[handleType === 'source' ? 'target' : 'source']?.find(
(d) => d.id === connectionEndHandle.value?.handleId,
(d) => d.id === connectionEndHandle.value?.id,
) || null
} else {
// if connection mode is loose, look for the handle in both source and target bounds
toHandle =
[...(toNode.value.handleBounds.source || []), ...(toNode.value.handleBounds.target || [])]?.find(
(d) => d.id === connectionEndHandle.value?.handleId,
(d) => d.id === connectionEndHandle.value?.id,
) || null
}
}
@@ -8,7 +8,7 @@ import {
ErrorCode,
VueFlowError,
elementSelectionKeys,
getHandle,
getEdgeHandle,
getHandlePosition,
getMarkerId,
} from '../../utils'
@@ -150,7 +150,7 @@ const EdgeWrapper = defineComponent({
sourceNodeHandles = [...(sourceNode.handleBounds.source || []), ...(sourceNode.handleBounds.target || [])]
}
const sourceHandle = getHandle(sourceNodeHandles, edge.value.sourceHandle)
const sourceHandle = getEdgeHandle(sourceNodeHandles, edge.value.sourceHandle)
let targetNodeHandles
if (connectionMode.value === ConnectionMode.Strict) {
@@ -159,7 +159,7 @@ const EdgeWrapper = defineComponent({
targetNodeHandles = [...(targetNode.handleBounds.target || []), ...(targetNode.handleBounds.source || [])]
}
const targetHandle = getHandle(targetNodeHandles, edge.value.targetHandle)
const targetHandle = getEdgeHandle(targetNodeHandles, edge.value.targetHandle)
const sourcePosition = sourceHandle?.position || Position.Bottom
@@ -19,6 +19,7 @@ const type = toRef(() => props.type ?? 'source')
const isValidConnection = toRef(() => props.isValidConnection ?? null)
const {
id: flowId,
connectionStartHandle,
connectionClickStartHandle,
connectionEndHandle,
@@ -39,17 +40,17 @@ const isConnectableEnd = toRef(() => (typeof connectableEnd !== 'undefined' ? co
const isConnecting = toRef(
() =>
(connectionStartHandle.value?.nodeId === nodeId &&
connectionStartHandle.value?.handleId === handleId &&
connectionStartHandle.value?.id === handleId &&
connectionStartHandle.value?.type === type.value) ||
(connectionEndHandle.value?.nodeId === nodeId &&
connectionEndHandle.value?.handleId === handleId &&
connectionEndHandle.value?.id === handleId &&
connectionEndHandle.value?.type === type.value),
)
const isClickConnecting = toRef(
() =>
connectionClickStartHandle.value?.nodeId === nodeId &&
connectionClickStartHandle.value?.handleId === handleId &&
connectionClickStartHandle.value?.id === handleId &&
connectionClickStartHandle.value?.type === type.value,
)
@@ -127,6 +128,8 @@ onMounted(() => {
position,
x: (handleBounds.left - nodeBounds.left) / zoom,
y: (handleBounds.top - nodeBounds.top) / zoom,
type: type.value,
nodeId,
...getDimensions(handle.value),
}
@@ -177,7 +180,7 @@ export default {
<template>
<div
ref="handle"
:data-id="`${nodeId}-${handleId}-${type}`"
:data-id="`${flowId}-${nodeId}-${handleId}-${type}`"
:data-handleid="handleId"
:data-nodeid="nodeId"
:data-handlepos="position"