From 4c429ec2748566f1223bdab70bd8f8ab10d6ee12 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:20:15 +0100 Subject: [PATCH 1/2] feat(core): add clampPositionToParent util Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --- packages/core/src/utils/general.ts | 16 ++++++++++++++++ packages/core/src/utils/graph.ts | 6 +++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/core/src/utils/general.ts b/packages/core/src/utils/general.ts index 5bc728af9..07b634a5f 100644 --- a/packages/core/src/utils/general.ts +++ b/packages/core/src/utils/general.ts @@ -1,5 +1,7 @@ import type { GraphNode, SnapGrid, XYPosition } from '../types' import type { UseDragEvent } from '../composables' +import type { Dimensions, GraphNode, XYPosition } from '../types' +import { clampPosition } from './graph' export function isMouseEvent(event: MouseEvent | TouchEvent): event is MouseEvent { return 'clientX' in event @@ -36,3 +38,17 @@ export function snapPosition(position: XYPosition, snapGrid: SnapGrid = [1, 1]): y: snapGrid[1] * Math.round(position.y / snapGrid[1]), } } + +export function clampPositionToParent(childPosition: XYPosition, childDimensions: Dimensions, parent: GraphNode) { + const { width: parentWidth, height: parentHeight } = getNodeDimensions(parent) + const { x: parentX, y: parentY } = parent.computedPosition + + return clampPosition( + childPosition, + [ + [parentX, parentY], + [parentX + parentWidth, parentY + parentHeight], + ], + childDimensions, + ) +} diff --git a/packages/core/src/utils/graph.ts b/packages/core/src/utils/graph.ts index 209709b76..1e5753289 100644 --- a/packages/core/src/utils/graph.ts +++ b/packages/core/src/utils/graph.ts @@ -49,10 +49,10 @@ export function clamp(val: number, min = 0, max = 1) { return Math.min(Math.max(val, min), max) } -export function clampPosition(position: XYPosition, extent: CoordinateExtent): XYPosition { +export function clampPosition(position: XYPosition = { x: 0, y: 0 }, extent: CoordinateExtent, dimensions: Partial) { return { - x: clamp(position.x, extent[0][0], extent[1][0]), - y: clamp(position.y, extent[0][1], extent[1][1]), + x: clamp(position.x, extent[0][0], extent[1][0] - (dimensions?.width ?? 0)), + y: clamp(position.y, extent[0][1], extent[1][1] - (dimensions?.height ?? 0)), } } From 90a913fe4f8756e092cb30a6b370b6cad73454cb Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Tue, 7 Jan 2025 12:18:12 +0100 Subject: [PATCH 2/2] fix(core): clamp child pos to parent Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --- packages/core/src/components/Nodes/NodeWrapper.ts | 2 ++ packages/core/src/utils/drag.ts | 12 ++++++++++-- packages/core/src/utils/general.ts | 3 +-- packages/core/src/utils/graph.ts | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/core/src/components/Nodes/NodeWrapper.ts b/packages/core/src/components/Nodes/NodeWrapper.ts index 546ec96d2..b57c12a1e 100644 --- a/packages/core/src/components/Nodes/NodeWrapper.ts +++ b/packages/core/src/components/Nodes/NodeWrapper.ts @@ -226,6 +226,8 @@ const NodeWrapper = defineComponent({ } else { node.computedPosition = xyzPos } + + clampPosition() }, { flush: 'post', immediate: true }, ) diff --git a/packages/core/src/utils/drag.ts b/packages/core/src/utils/drag.ts index ccc107f2f..9af230d8e 100644 --- a/packages/core/src/utils/drag.ts +++ b/packages/core/src/utils/drag.ts @@ -9,7 +9,7 @@ import type { State, XYPosition, } from '../types' -import { ErrorCode, VueFlowError, clampPosition, isParentSelected } from '.' +import { ErrorCode, VueFlowError, clampPosition, clampPositionToParent, isParentSelected } from '.' export function hasSelector(target: Element, selector: string, node: Element): boolean { let current = target @@ -192,15 +192,23 @@ export function calcNextPosition( nodeExtent?: State['nodeExtent'], parentNode?: GraphNode, ) { + const currentExtent = node.extent || nodeExtent const extent = clampNodeExtent(node.dimensions, getExtent(node, triggerError, nodeExtent, parentNode)) const clampedPos = clampPosition(nextPosition, extent) + let computedPos = clampedPos + + if (parentNode && (currentExtent === 'parent' || (!Array.isArray(currentExtent) && currentExtent?.range === 'parent'))) { + console.log('clamp to parent') + computedPos = clampPositionToParent(clampedPos, node.dimensions, parentNode) + } + return { position: { x: clampedPos.x - (parentNode?.computedPosition.x || 0), y: clampedPos.y - (parentNode?.computedPosition.y || 0), }, - computedPosition: clampedPos, + computedPosition: computedPos, } } diff --git a/packages/core/src/utils/general.ts b/packages/core/src/utils/general.ts index 07b634a5f..4f920f5be 100644 --- a/packages/core/src/utils/general.ts +++ b/packages/core/src/utils/general.ts @@ -1,6 +1,5 @@ -import type { GraphNode, SnapGrid, XYPosition } from '../types' import type { UseDragEvent } from '../composables' -import type { Dimensions, GraphNode, XYPosition } from '../types' +import type { Dimensions, GraphNode, SnapGrid, XYPosition } from '../types' import { clampPosition } from './graph' export function isMouseEvent(event: MouseEvent | TouchEvent): event is MouseEvent { diff --git a/packages/core/src/utils/graph.ts b/packages/core/src/utils/graph.ts index 1e5753289..8a559b909 100644 --- a/packages/core/src/utils/graph.ts +++ b/packages/core/src/utils/graph.ts @@ -49,7 +49,7 @@ export function clamp(val: number, min = 0, max = 1) { return Math.min(Math.max(val, min), max) } -export function clampPosition(position: XYPosition = { x: 0, y: 0 }, extent: CoordinateExtent, dimensions: Partial) { +export function clampPosition(position: XYPosition = { x: 0, y: 0 }, extent: CoordinateExtent, dimensions?: Partial) { return { x: clamp(position.x, extent[0][0], extent[1][0] - (dimensions?.width ?? 0)), y: clamp(position.y, extent[0][1], extent[1][1] - (dimensions?.height ?? 0)),