fix(core): correct calculation of nodes inside selection (#1509)

* fix(core): correct calculation of nodes inside selection

* chore(changeset): add
This commit is contained in:
Braks
2024-07-01 10:34:54 +02:00
parent 3ed281b261
commit c8b55223b9
2 changed files with 30 additions and 21 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@vue-flow/core": patch
---
Correct calculation of nodes inside selection rect
+25 -21
View File
@@ -298,8 +298,8 @@ export function rendererPointToPoint({ x, y }: XYPosition, { x: tx, y: ty, zoom:
export function pointToRendererPoint( export function pointToRendererPoint(
{ x, y }: XYPosition, { x, y }: XYPosition,
{ x: tx, y: ty, zoom: tScale }: ViewportTransform, { x: tx, y: ty, zoom: tScale }: ViewportTransform,
snapToGrid: boolean, snapToGrid: boolean = false,
[snapX, snapY]: [snapX: number, snapY: number], [snapX, snapY]: [snapX: number, snapY: number] = [1, 1],
): XYPosition { ): XYPosition {
const position: XYPosition = { const position: XYPosition = {
x: (x - tx) / tScale, x: (x - tx) / tScale,
@@ -373,37 +373,41 @@ export function getRectOfNodes(nodes: GraphNode[]) {
export function getNodesInside( export function getNodesInside(
nodes: GraphNode[], nodes: GraphNode[],
rect: Rect, rect: Rect,
{ x: tx, y: ty, zoom: tScale }: ViewportTransform = { x: 0, y: 0, zoom: 1 }, viewport: ViewportTransform = { x: 0, y: 0, zoom: 1 },
partially = false, partially = false,
// set excludeNonSelectableNodes if you want to pay attention to the nodes "selectable" attribute // set excludeNonSelectableNodes if you want to pay attention to the nodes "selectable" attribute
excludeNonSelectableNodes = false, excludeNonSelectableNodes = false,
) { ) {
const paneRect = { const paneRect = {
x: (rect.x - tx) / tScale, ...pointToRendererPoint(rect, viewport),
y: (rect.y - ty) / tScale, width: rect.width / viewport.zoom,
width: rect.width / tScale, height: rect.height / viewport.zoom,
height: rect.height / tScale,
} }
return nodes.filter((node) => { const visibleNodes: GraphNode[] = []
const { computedPosition = { x: 0, y: 0 }, dimensions = { width: 0, height: 0 }, selectable } = node
if (excludeNonSelectableNodes && !selectable) { for (const node of nodes) {
return false const { dimensions, selectable = true, hidden = false } = node
const width = dimensions.width ?? node.width ?? null
const height = dimensions.height ?? node.height ?? null
if ((excludeNonSelectableNodes && !selectable) || hidden) {
continue
} }
const nodeRect = { ...computedPosition, width: dimensions.width || 0, height: dimensions.height || 0 } const overlappingArea = getOverlappingArea(paneRect, nodeToRect(node))
const overlappingArea = getOverlappingArea(paneRect, nodeRect) const notInitialized = width === null || height === null
const notInitialized =
typeof dimensions.width === 'undefined' ||
typeof dimensions.height === 'undefined' ||
dimensions.width === 0 ||
dimensions.height === 0
const partiallyVisible = partially && overlappingArea > 0 const partiallyVisible = partially && overlappingArea > 0
const area = dimensions.width * dimensions.height const area = (width ?? 0) * (height ?? 0)
return notInitialized || partiallyVisible || overlappingArea >= area const isVisible = notInitialized || partiallyVisible || overlappingArea >= area
})
if (isVisible || node.dragging) {
visibleNodes.push(node)
}
}
return visibleNodes
} }
export function getConnectedEdges<E extends Edge>(nodesOrId: Node[] | string, edges: E[]) { export function getConnectedEdges<E extends Edge>(nodesOrId: Node[] | string, edges: E[]) {