From b7428e95128ce8112049fc0b41bfe44c00244742 Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Wed, 13 Jul 2022 12:42:36 +0200 Subject: [PATCH] fix(handles): correctly calculate handle pos by using viewport zoom --- .../src/components/Nodes/NodeWrapper.vue | 5 ++- packages/vue-flow/src/store/actions.ts | 6 +++- packages/vue-flow/src/utils/graph.ts | 2 +- packages/vue-flow/src/utils/node.ts | 36 ++++++------------- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/packages/vue-flow/src/components/Nodes/NodeWrapper.vue b/packages/vue-flow/src/components/Nodes/NodeWrapper.vue index 28f3c493..59fb45dc 100644 --- a/packages/vue-flow/src/components/Nodes/NodeWrapper.vue +++ b/packages/vue-flow/src/components/Nodes/NodeWrapper.vue @@ -120,7 +120,10 @@ onMounted(() => { updatePosition(xyzPos, parentX && parentY ? { x: parentX, y: parentY, z: parentZ! } : undefined) - node.handleBounds = getHandleBounds(nodeElement.value, viewport.zoom) + node.handleBounds = { + source: getHandleBounds('.source', nodeElement.value, viewport.zoom), + target: getHandleBounds('.target', nodeElement.value, viewport.zoom), + } }, { immediate: true, flush: 'post' }, ) diff --git a/packages/vue-flow/src/store/actions.ts b/packages/vue-flow/src/store/actions.ts index e9f64d01..a0067266 100644 --- a/packages/vue-flow/src/store/actions.ts +++ b/packages/vue-flow/src/store/actions.ts @@ -80,7 +80,11 @@ export default (state: State, getters: ComputedGetters): Actions => { dimensions.height && (node.dimensions.width !== dimensions.width || node.dimensions.height !== dimensions.height || update.forceUpdate) ) - node.handleBounds = getHandleBounds(update.nodeElement, state.viewport.zoom) + + node.handleBounds = { + source: getHandleBounds('.source', update.nodeElement, state.viewport.zoom), + target: getHandleBounds('.target', update.nodeElement, state.viewport.zoom), + } if (doUpdate) { node.dimensions = dimensions diff --git a/packages/vue-flow/src/utils/graph.ts b/packages/vue-flow/src/utils/graph.ts index 60b6973b..b0cbd15d 100644 --- a/packages/vue-flow/src/utils/graph.ts +++ b/packages/vue-flow/src/utils/graph.ts @@ -113,7 +113,7 @@ export const parseEdge = (edge: Edge, defaults?: Partial): GraphEdge const getConnectedElements = (node: GraphNode, elements: Elements, dir: 'source' | 'target') => { if (!isNode(node)) return [] - const origin = (dir === 'source' ? 'target' : 'source') + const origin = dir === 'source' ? 'target' : 'source' const ids = elements.filter((e) => isEdge(e) && e[origin] === node.id).map((e) => isEdge(e) && e[dir]) return elements.filter((e) => ids.includes(e.id)) } diff --git a/packages/vue-flow/src/utils/node.ts b/packages/vue-flow/src/utils/node.ts index 503b952c..4e6b4dd2 100644 --- a/packages/vue-flow/src/utils/node.ts +++ b/packages/vue-flow/src/utils/node.ts @@ -2,43 +2,29 @@ import type { Ref } from 'vue' import { getDimensions } from './graph' import type { Actions, GraphNode, HandleElement, Position } from '~/types' -export const getHandleBoundsByHandleType = ( - selector: string, - nodeElement: HTMLDivElement, - parentBounds: ClientRect | DOMRect, - k: number, -): HandleElement[] | null => { +export const getHandleBounds = (selector: string, nodeElement: HTMLDivElement, zoom: number): HandleElement[] | undefined => { const handles = nodeElement.querySelectorAll(selector) - if (!handles || !handles.length) return null + if (!handles || !handles.length) { + return undefined + } const handlesArray = Array.from(handles) as HTMLDivElement[] + const nodeBounds = nodeElement.getBoundingClientRect() return handlesArray.map((handle): HandleElement => { - const bounds = handle.getBoundingClientRect() - const dimensions = getDimensions(handle) - const handleId = handle.getAttribute('data-handleid') ?? undefined - const handlePosition = handle.getAttribute('data-handlepos') as Position + const handleBounds = handle.getBoundingClientRect() return { - id: handleId, - position: handlePosition, - x: (bounds.left - parentBounds.left) / k, - y: (bounds.top - parentBounds.top) / k, - ...dimensions, + id: handle.getAttribute('data-handleid'), + position: handle.getAttribute('data-handlepos') as unknown as Position, + x: (handleBounds.left - nodeBounds.left) / zoom, + y: (handleBounds.top - nodeBounds.top) / zoom, + ...getDimensions(handle), } }) } -export const getHandleBounds = (nodeElement: HTMLDivElement, scale: number, id?: string) => { - const bounds = nodeElement.getBoundingClientRect() - - return { - source: getHandleBoundsByHandleType(`.source${id ? `.vue-flow__handle-${id}` : ''}`, nodeElement, bounds, scale) ?? undefined, - target: getHandleBoundsByHandleType(`.target${id ? `.vue-flow__handle-${id}` : ''}`, nodeElement, bounds, scale) ?? undefined, - } -} - export const handleNodeClick = ( node: GraphNode, multiSelectionActive: boolean,