refactor(core): cleanup connection line component (#1470)
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import type { DefineComponent } from 'vue'
|
import { computed, defineComponent, h, inject } from 'vue'
|
||||||
import { defineComponent, h, inject } from 'vue'
|
import type { HandleElement } from '../../types'
|
||||||
import type { ConnectionLineProps } from '../../types'
|
|
||||||
import { ConnectionLineType, ConnectionMode, Position } from '../../types'
|
import { ConnectionLineType, ConnectionMode, Position } from '../../types'
|
||||||
import { getHandlePosition, getMarkerId } from '../../utils'
|
import { getHandlePosition, getMarkerId } from '../../utils'
|
||||||
import { useVueFlow } from '../../composables'
|
import { useVueFlow } from '../../composables'
|
||||||
@@ -32,16 +31,29 @@ const ConnectionLine = defineComponent({
|
|||||||
findNode,
|
findNode,
|
||||||
} = useVueFlow()
|
} = useVueFlow()
|
||||||
|
|
||||||
const connectionLineComponent = inject(Slots)?.['connection-line'] as DefineComponent<ConnectionLineProps> | undefined
|
const connectionLineComponent = inject(Slots)?.['connection-line']
|
||||||
|
|
||||||
|
const fromNode = computed(() => findNode(connectionStartHandle.value?.nodeId))
|
||||||
|
|
||||||
|
const toNode = computed(() => findNode(connectionEndHandle.value?.nodeId) ?? null)
|
||||||
|
|
||||||
|
const toXY = computed(() => {
|
||||||
|
return {
|
||||||
|
x: (connectionPosition.value.x - viewport.value.x) / viewport.value.zoom,
|
||||||
|
y: (connectionPosition.value.y - viewport.value.y) / viewport.value.zoom,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const markerStart = computed(() =>
|
||||||
|
connectionLineOptions.value.markerStart ? `url(#${getMarkerId(connectionLineOptions.value.markerStart, id)})` : '',
|
||||||
|
)
|
||||||
|
|
||||||
|
const markerEnd = computed(() =>
|
||||||
|
connectionLineOptions.value.markerEnd ? `url(#${getMarkerId(connectionLineOptions.value.markerEnd, id)})` : '',
|
||||||
|
)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (!connectionStartHandle.value) {
|
if (!fromNode.value || !connectionStartHandle.value) {
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const fromNode = findNode(connectionStartHandle.value.nodeId)
|
|
||||||
|
|
||||||
if (!fromNode) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,12 +61,7 @@ const ConnectionLine = defineComponent({
|
|||||||
|
|
||||||
const handleType = connectionStartHandle.value.type
|
const handleType = connectionStartHandle.value.type
|
||||||
|
|
||||||
const targetNode = (connectionEndHandle.value && findNode(connectionEndHandle.value.nodeId)) || null
|
const fromHandleBounds = fromNode.value.handleBounds
|
||||||
|
|
||||||
const toX = (connectionPosition.value.x - viewport.value.x) / viewport.value.zoom
|
|
||||||
const toY = (connectionPosition.value.y - viewport.value.y) / viewport.value.zoom
|
|
||||||
|
|
||||||
const fromHandleBounds = fromNode.handleBounds
|
|
||||||
let handleBounds = fromHandleBounds?.[handleType]
|
let handleBounds = fromHandleBounds?.[handleType]
|
||||||
|
|
||||||
if (connectionMode.value === ConnectionMode.Loose) {
|
if (connectionMode.value === ConnectionMode.Loose) {
|
||||||
@@ -69,24 +76,28 @@ const ConnectionLine = defineComponent({
|
|||||||
const fromPosition = fromHandle?.position || Position.Top
|
const fromPosition = fromHandle?.position || Position.Top
|
||||||
const { x: fromX, y: fromY } = getHandlePosition(
|
const { x: fromX, y: fromY } = getHandlePosition(
|
||||||
fromPosition,
|
fromPosition,
|
||||||
{ ...fromNode.dimensions, ...fromNode.computedPosition },
|
{ ...fromNode.value.dimensions, ...fromNode.value.computedPosition },
|
||||||
fromHandle,
|
fromHandle,
|
||||||
)
|
)
|
||||||
|
|
||||||
// todo: this is a bit of a mess, we should refactor this
|
let toHandle: HandleElement | null = null
|
||||||
const toHandle =
|
if (toNode.value && connectionEndHandle.value?.handleId) {
|
||||||
(targetNode &&
|
// if connection mode is strict, we only look for handles of the opposite type
|
||||||
connectionEndHandle.value?.handleId &&
|
if (connectionMode.value === ConnectionMode.Strict) {
|
||||||
((connectionMode.value === ConnectionMode.Strict
|
toHandle =
|
||||||
? targetNode.handleBounds[handleType === 'source' ? 'target' : 'source']?.find(
|
toNode.value.handleBounds[handleType === 'source' ? 'target' : 'source']?.find(
|
||||||
(d) => d.id === connectionEndHandle.value?.handleId,
|
(d) => d.id === connectionEndHandle.value?.handleId,
|
||||||
)
|
) || null
|
||||||
: [...(targetNode.handleBounds.source || []), ...(targetNode.handleBounds.target || [])]?.find(
|
} else {
|
||||||
(d) => d.id === connectionEndHandle.value?.handleId,
|
// if connection mode is loose, look for the handle in both source and target bounds
|
||||||
)) ||
|
toHandle =
|
||||||
targetNode.handleBounds[handleType ?? 'target']?.[0])) ||
|
[...(toNode.value.handleBounds.source || []), ...(toNode.value.handleBounds.target || [])]?.find(
|
||||||
null
|
(d) => d.id === connectionEndHandle.value?.handleId,
|
||||||
|
) || null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we assume the target position is opposite to the source position
|
||||||
const toPosition = fromPosition ? oppositePosition[fromPosition] : null
|
const toPosition = fromPosition ? oppositePosition[fromPosition] : null
|
||||||
|
|
||||||
if (!fromPosition || !toPosition) {
|
if (!fromPosition || !toPosition) {
|
||||||
@@ -101,13 +112,12 @@ const ConnectionLine = defineComponent({
|
|||||||
sourceX: fromX,
|
sourceX: fromX,
|
||||||
sourceY: fromY,
|
sourceY: fromY,
|
||||||
sourcePosition: fromPosition,
|
sourcePosition: fromPosition,
|
||||||
targetX: toX,
|
targetX: toXY.value.x,
|
||||||
targetY: toY,
|
targetY: toXY.value.y,
|
||||||
targetPosition: toPosition,
|
targetPosition: toPosition,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === ConnectionLineType.Bezier) {
|
if (type === ConnectionLineType.Bezier) {
|
||||||
// we assume the destination position is opposite to the source position
|
|
||||||
;[dAttr] = getBezierPath(pathParams)
|
;[dAttr] = getBezierPath(pathParams)
|
||||||
} else if (type === ConnectionLineType.Step) {
|
} else if (type === ConnectionLineType.Step) {
|
||||||
;[dAttr] = getSmoothStepPath({
|
;[dAttr] = getSmoothStepPath({
|
||||||
@@ -119,7 +129,7 @@ const ConnectionLine = defineComponent({
|
|||||||
} else if (type === ConnectionLineType.SimpleBezier) {
|
} else if (type === ConnectionLineType.SimpleBezier) {
|
||||||
;[dAttr] = getSimpleBezierPath(pathParams)
|
;[dAttr] = getSimpleBezierPath(pathParams)
|
||||||
} else {
|
} else {
|
||||||
dAttr = `M${fromX},${fromY} ${toX},${toY}`
|
dAttr = `M${fromX},${fromY} ${toXY.value.x},${toXY.value.y}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return h(
|
return h(
|
||||||
@@ -133,15 +143,15 @@ const ConnectionLine = defineComponent({
|
|||||||
sourceX: fromX,
|
sourceX: fromX,
|
||||||
sourceY: fromY,
|
sourceY: fromY,
|
||||||
sourcePosition: fromPosition,
|
sourcePosition: fromPosition,
|
||||||
targetX: toX,
|
targetX: toXY.value.x,
|
||||||
targetY: toY,
|
targetY: toXY.value.y,
|
||||||
targetPosition: toPosition,
|
targetPosition: toPosition,
|
||||||
sourceNode: fromNode,
|
sourceNode: fromNode.value,
|
||||||
sourceHandle: fromHandle,
|
sourceHandle: fromHandle,
|
||||||
targetNode,
|
targetNode: toNode.value,
|
||||||
targetHandle: toHandle,
|
targetHandle: toHandle,
|
||||||
markerEnd: `url(#${getMarkerId(connectionLineOptions.value.markerEnd, id)})`,
|
markerEnd: markerEnd.value,
|
||||||
markerStart: `url(#${getMarkerId(connectionLineOptions.value.markerStart, id)})`,
|
markerStart: markerStart.value,
|
||||||
connectionStatus: connectionStatus.value,
|
connectionStatus: connectionStatus.value,
|
||||||
})
|
})
|
||||||
: h('path', {
|
: h('path', {
|
||||||
@@ -151,8 +161,8 @@ const ConnectionLine = defineComponent({
|
|||||||
...connectionLineStyle.value,
|
...connectionLineStyle.value,
|
||||||
...connectionLineOptions.value.style,
|
...connectionLineOptions.value.style,
|
||||||
},
|
},
|
||||||
'marker-end': `url(#${getMarkerId(connectionLineOptions.value.markerEnd, id)})`,
|
'marker-end': markerEnd.value,
|
||||||
'marker-start': `url(#${getMarkerId(connectionLineOptions.value.markerStart, id)})`,
|
'marker-start': markerStart.value,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user