mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 11:11:53 +00:00
Fix: Vue Node Align/Distribute (#6712)
## Summary Fixes the issue of the nodes not moving when in Vue mode (but changing if switching back to litegraph) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6712-Fix-Vue-Node-Align-Distribute-2ad6d73d365081339aa6f61e18832bc4) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -49,6 +49,7 @@ import type {
|
||||
ISlotType,
|
||||
LinkNetwork,
|
||||
LinkSegment,
|
||||
NewNodePosition,
|
||||
NullableProperties,
|
||||
Point,
|
||||
Positionable,
|
||||
@@ -1011,7 +1012,8 @@ export class LGraphCanvas
|
||||
direction: Direction,
|
||||
align_to?: LGraphNode
|
||||
): void {
|
||||
alignNodes(Object.values(nodes), direction, align_to)
|
||||
const newPositions = alignNodes(Object.values(nodes), direction, align_to)
|
||||
LGraphCanvas.active_canvas.repositionNodesVueMode(newPositions)
|
||||
LGraphCanvas.active_canvas.setDirty(true, true)
|
||||
}
|
||||
|
||||
@@ -1031,11 +1033,12 @@ export class LGraphCanvas
|
||||
})
|
||||
|
||||
function inner_clicked(value: string) {
|
||||
alignNodes(
|
||||
const newPositions = alignNodes(
|
||||
Object.values(LGraphCanvas.active_canvas.selected_nodes),
|
||||
value.toLowerCase() as Direction,
|
||||
node
|
||||
)
|
||||
LGraphCanvas.active_canvas.repositionNodesVueMode(newPositions)
|
||||
LGraphCanvas.active_canvas.setDirty(true, true)
|
||||
}
|
||||
}
|
||||
@@ -1055,10 +1058,11 @@ export class LGraphCanvas
|
||||
})
|
||||
|
||||
function inner_clicked(value: string) {
|
||||
alignNodes(
|
||||
const newPositions = alignNodes(
|
||||
Object.values(LGraphCanvas.active_canvas.selected_nodes),
|
||||
value.toLowerCase() as Direction
|
||||
)
|
||||
LGraphCanvas.active_canvas.repositionNodesVueMode(newPositions)
|
||||
LGraphCanvas.active_canvas.setDirty(true, true)
|
||||
}
|
||||
}
|
||||
@@ -1079,10 +1083,11 @@ export class LGraphCanvas
|
||||
|
||||
function inner_clicked(value: string) {
|
||||
const canvas = LGraphCanvas.active_canvas
|
||||
distributeNodes(
|
||||
const newPositions = distributeNodes(
|
||||
Object.values(canvas.selected_nodes),
|
||||
value === 'Horizontally'
|
||||
)
|
||||
canvas.repositionNodesVueMode(newPositions)
|
||||
canvas.setDirty(true, true)
|
||||
}
|
||||
}
|
||||
@@ -8557,10 +8562,7 @@ export class LGraphCanvas
|
||||
) {
|
||||
const mutations = this.initLayoutMutations()
|
||||
const nodesInMovingGroups = this.collectNodesInGroups(allItems)
|
||||
const nodesToMove: Array<{
|
||||
node: LGraphNode
|
||||
newPos: { x: number; y: number }
|
||||
}> = []
|
||||
const nodesToMove: NewNodePosition[] = []
|
||||
|
||||
// First, collect all the moves we need to make
|
||||
for (const item of allItems) {
|
||||
@@ -8586,4 +8588,9 @@ export class LGraphCanvas
|
||||
// Now apply all the node moves at once
|
||||
this.applyNodePositionUpdates(nodesToMove, mutations)
|
||||
}
|
||||
|
||||
repositionNodesVueMode(nodesToReposition: NewNodePosition[]) {
|
||||
const mutations = this.initLayoutMutations()
|
||||
this.applyNodePositionUpdates(nodesToReposition, mutations)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,13 @@ type KeysOfType<T, Match> = Exclude<
|
||||
|
||||
/** The names of all (optional) methods and functions in T */
|
||||
export type MethodNames<T> = KeysOfType<T, ((...args: any) => any) | undefined>
|
||||
|
||||
export interface NewNodePosition {
|
||||
node: LGraphNode
|
||||
newPos: {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
}
|
||||
export interface IBoundaryNodes {
|
||||
top: LGraphNode
|
||||
right: LGraphNode
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { LGraphNode } from '../LGraphNode'
|
||||
import type { Direction, IBoundaryNodes } from '../interfaces'
|
||||
import type { Direction, IBoundaryNodes, NewNodePosition } from '../interfaces'
|
||||
|
||||
/**
|
||||
* Finds the nodes that are farthest in all four directions, representing the boundary of the nodes.
|
||||
@@ -43,9 +43,9 @@ export function getBoundaryNodes(nodes: LGraphNode[]): IBoundaryNodes | null {
|
||||
export function distributeNodes(
|
||||
nodes: LGraphNode[],
|
||||
horizontal?: boolean
|
||||
): void {
|
||||
): NewNodePosition[] {
|
||||
const nodeCount = nodes?.length
|
||||
if (!(nodeCount > 1)) return
|
||||
if (!(nodeCount > 1)) return []
|
||||
|
||||
const index = horizontal ? 0 : 1
|
||||
|
||||
@@ -68,6 +68,16 @@ export function distributeNodes(
|
||||
node.pos[index] = startAt + gap * i
|
||||
startAt += node.size[index]
|
||||
}
|
||||
const newPositions = sorted.map(
|
||||
(node): NewNodePosition => ({
|
||||
node,
|
||||
newPos: {
|
||||
x: node.pos[0],
|
||||
y: node.pos[1]
|
||||
}
|
||||
})
|
||||
)
|
||||
return newPositions
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,32 +90,56 @@ export function alignNodes(
|
||||
nodes: LGraphNode[],
|
||||
direction: Direction,
|
||||
align_to?: LGraphNode
|
||||
): void {
|
||||
if (!nodes) return
|
||||
): NewNodePosition[] {
|
||||
if (!nodes) return []
|
||||
|
||||
const boundary =
|
||||
align_to === undefined
|
||||
? getBoundaryNodes(nodes)
|
||||
: { top: align_to, right: align_to, bottom: align_to, left: align_to }
|
||||
|
||||
if (boundary === null) return
|
||||
if (boundary === null) return []
|
||||
|
||||
for (const node of nodes) {
|
||||
const nodePositions = nodes.map((node): NewNodePosition => {
|
||||
switch (direction) {
|
||||
case 'right':
|
||||
node.pos[0] =
|
||||
boundary.right.pos[0] + boundary.right.size[0] - node.size[0]
|
||||
break
|
||||
return {
|
||||
node,
|
||||
newPos: {
|
||||
x: boundary.right.pos[0] + boundary.right.size[0] - node.size[0],
|
||||
y: node.pos[1]
|
||||
}
|
||||
}
|
||||
case 'left':
|
||||
node.pos[0] = boundary.left.pos[0]
|
||||
break
|
||||
return {
|
||||
node,
|
||||
newPos: {
|
||||
x: boundary.left.pos[0],
|
||||
y: node.pos[1]
|
||||
}
|
||||
}
|
||||
case 'top':
|
||||
node.pos[1] = boundary.top.pos[1]
|
||||
break
|
||||
return {
|
||||
node,
|
||||
newPos: {
|
||||
x: node.pos[0],
|
||||
y: boundary.top.pos[1]
|
||||
}
|
||||
}
|
||||
case 'bottom':
|
||||
node.pos[1] =
|
||||
boundary.bottom.pos[1] + boundary.bottom.size[1] - node.size[1]
|
||||
break
|
||||
return {
|
||||
node,
|
||||
newPos: {
|
||||
x: node.pos[0],
|
||||
y: boundary.bottom.pos[1] + boundary.bottom.size[1] - node.size[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
for (const { node, newPos } of nodePositions) {
|
||||
node.pos[0] = newPos.x
|
||||
node.pos[1] = newPos.y
|
||||
}
|
||||
return nodePositions
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user