mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Feat/vue noes arrange alg improved (#6357)
## Summary
Improve the previous [vue node arrange
alg](5a1284660c/src/renderer/extensions/vueNodes/layout/scaleLayoutForVueNodes.ts)
to match Litegraph much closer visually.
- In addition to the scaling of the LG node's x,y and then setting the
vue nodes position to that, we can also scale the width and height of
the LG node and set that for the Vue node wxh.
- Change from scaling from the center to the top left
- Change the zoom offset to account for the scale for seamless
transition
## Screenshots (if applicable)
<img width="1868" height="1646" alt="image"
src="https://github.com/user-attachments/assets/bc816819-211f-4619-a02a-8d167b5dc1fd"
/>
<img width="1868" height="1648" alt="image (1)"
src="https://github.com/user-attachments/assets/61faf530-1994-4cf9-bca9-a7ab6f9740c2"
/>
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6357-Feat-vue-noes-arrange-alg-improved-29b6d73d365081e7813bd6f19ce1202a)
by [Unito](https://www.unito.io)
---------
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: JakeSchroeder <jake@axiom.co>
This commit is contained in:
@@ -9,7 +9,7 @@ import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
import { useLayoutSync } from '@/renderer/core/layout/sync/useLayoutSync'
|
||||
import { scaleLayoutForVueNodes } from '@/renderer/extensions/vueNodes/layout/scaleLayoutForVueNodes'
|
||||
import { ensureCorrectLayoutScale } from '@/renderer/extensions/vueNodes/layout/ensureCorrectLayoutScale'
|
||||
import { app as comfyApp } from '@/scripts/app'
|
||||
|
||||
function useVueNodeLifecycleIndividual() {
|
||||
@@ -78,15 +78,7 @@ function useVueNodeLifecycleIndividual() {
|
||||
(enabled) => {
|
||||
if (enabled) {
|
||||
initializeNodeManager()
|
||||
|
||||
const graph = comfyApp.canvas.graph
|
||||
if (graph && !graph.extra) {
|
||||
graph.extra = {}
|
||||
}
|
||||
if (graph && !graph.extra.vueNodesScaled) {
|
||||
scaleLayoutForVueNodes()
|
||||
graph.extra.vueNodesScaled = true
|
||||
}
|
||||
ensureCorrectLayoutScale()
|
||||
} else {
|
||||
disposeNodeManagerAndSyncs()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Rect } from '@/lib/litegraph/src/interfaces'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { createBounds } from '@/lib/litegraph/src/measure'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
@@ -7,7 +7,7 @@ import { app as comfyApp } from '@/scripts/app'
|
||||
|
||||
const SCALE_FACTOR = 1.75
|
||||
|
||||
export function scaleLayoutForVueNodes() {
|
||||
export function ensureCorrectLayoutScale() {
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
const autoScaleLayoutSetting = settingStore.get(
|
||||
@@ -19,68 +19,76 @@ export function scaleLayoutForVueNodes() {
|
||||
}
|
||||
|
||||
const canvas = comfyApp.canvas
|
||||
const graph = canvas.graph
|
||||
const graph = canvas?.graph
|
||||
|
||||
if (!graph || !graph.nodes) return
|
||||
|
||||
if (graph.extra?.vueNodesScaled === true) {
|
||||
return
|
||||
}
|
||||
|
||||
const vueNodesEnabled = settingStore.get('Comfy.VueNodes.Enabled')
|
||||
if (!vueNodesEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
const lgBounds = createBounds(graph.nodes)
|
||||
|
||||
if (!lgBounds) return
|
||||
|
||||
const allVueNodes = layoutStore.getAllNodes().value
|
||||
|
||||
const lgBoundsCenterX = lgBounds![0] + lgBounds![2] / 2
|
||||
const lgBoundsCenterY = lgBounds![1] + lgBounds![3] / 2
|
||||
const originX = lgBounds[0]
|
||||
const originY = lgBounds[1]
|
||||
|
||||
const lgNodesById = new Map(
|
||||
graph.nodes.map((node) => [String(node.id), node])
|
||||
)
|
||||
|
||||
const yjsMoveNodeUpdates: NodeBoundsUpdate[] = []
|
||||
const scaledNodesForBounds: Array<{ boundingRect: Rect }> = []
|
||||
|
||||
for (const vueNode of allVueNodes.values()) {
|
||||
const lgNode = lgNodesById.get(String(vueNode.id))
|
||||
if (!lgNode) continue
|
||||
|
||||
const vectorX = lgNode.pos[0] - lgBoundsCenterX
|
||||
const vectorY = lgNode.pos[1] - lgBoundsCenterY
|
||||
const newX = lgBoundsCenterX + vectorX * SCALE_FACTOR
|
||||
const newY = lgBoundsCenterY + vectorY * SCALE_FACTOR
|
||||
const lgBodyY = lgNode.pos[1] - LiteGraph.NODE_TITLE_HEIGHT
|
||||
|
||||
const relativeX = lgNode.pos[0] - originX
|
||||
const relativeY = lgBodyY - originY
|
||||
const newX = originX + relativeX * SCALE_FACTOR
|
||||
const newY = originY + relativeY * SCALE_FACTOR
|
||||
const newWidth = lgNode.width * SCALE_FACTOR
|
||||
const newHeight = lgNode.height * SCALE_FACTOR
|
||||
|
||||
yjsMoveNodeUpdates.push({
|
||||
nodeId: vueNode.id,
|
||||
bounds: {
|
||||
x: newX,
|
||||
y: newY,
|
||||
width: vueNode.bounds.width,
|
||||
height: vueNode.bounds.height
|
||||
width: newWidth,
|
||||
height: newHeight
|
||||
}
|
||||
})
|
||||
|
||||
scaledNodesForBounds.push({
|
||||
boundingRect: [newX, newY, vueNode.bounds.width, vueNode.bounds.height]
|
||||
})
|
||||
}
|
||||
|
||||
layoutStore.batchUpdateNodeBounds(yjsMoveNodeUpdates)
|
||||
|
||||
const scaledLgBounds = createBounds(scaledNodesForBounds)
|
||||
|
||||
graph.groups.forEach((group) => {
|
||||
const vectorX = group.pos[0] - lgBoundsCenterX
|
||||
const vectorY = group.pos[1] - lgBoundsCenterY
|
||||
const groupBodyY = group.pos[1] - LiteGraph.NODE_TITLE_HEIGHT
|
||||
|
||||
group.pos = [
|
||||
lgBoundsCenterX + vectorX * SCALE_FACTOR,
|
||||
lgBoundsCenterY + vectorY * SCALE_FACTOR
|
||||
]
|
||||
const relativeX = group.pos[0] - originX
|
||||
const relativeY = groupBodyY - originY
|
||||
|
||||
const newPosY =
|
||||
originY + relativeY * SCALE_FACTOR + LiteGraph.NODE_TITLE_HEIGHT
|
||||
|
||||
group.pos = [originX + relativeX * SCALE_FACTOR, newPosY]
|
||||
group.size = [group.size[0] * SCALE_FACTOR, group.size[1] * SCALE_FACTOR]
|
||||
})
|
||||
|
||||
if (scaledLgBounds) {
|
||||
canvas.ds.fitToBounds(scaledLgBounds, {
|
||||
zoom: 0.5 //Makes it so the fit to view is slightly zoomed out and not edge to edge.
|
||||
})
|
||||
}
|
||||
const originScreen = canvas.ds.convertOffsetToCanvas([originX, originY])
|
||||
canvas.ds.changeScale(canvas.ds.scale / SCALE_FACTOR, originScreen)
|
||||
|
||||
if (!graph.extra) graph.extra = {}
|
||||
graph.extra.vueNodesScaled = true
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import { reactive, unref } from 'vue'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
import { useCanvasPositionConversion } from '@/composables/element/useCanvasPositionConversion'
|
||||
import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags'
|
||||
import { registerProxyWidgets } from '@/core/graph/subgraph/proxyWidget'
|
||||
import { st, t } from '@/i18n'
|
||||
import type { IContextMenuValue } from '@/lib/litegraph/src/interfaces'
|
||||
@@ -99,7 +98,7 @@ import { $el, ComfyUI } from './ui'
|
||||
import { ComfyAppMenu } from './ui/menu/index'
|
||||
import { clone } from './utils'
|
||||
import { type ComfyWidgetConstructor } from './widgets'
|
||||
import { scaleLayoutForVueNodes } from '@/renderer/extensions/vueNodes/layout/scaleLayoutForVueNodes'
|
||||
import { ensureCorrectLayoutScale } from '@/renderer/extensions/vueNodes/layout/ensureCorrectLayoutScale'
|
||||
|
||||
export const ANIM_PREVIEW_WIDGET = '$$comfy_animation_preview'
|
||||
|
||||
@@ -1184,16 +1183,7 @@ export class ComfyApp {
|
||||
// @ts-expect-error Discrepancies between zod and litegraph - in progress
|
||||
this.graph.configure(graphData)
|
||||
|
||||
const vueMode = useVueFeatureFlags().shouldRenderVueNodes.value
|
||||
|
||||
if (!this.graph.extra) {
|
||||
this.graph.extra = {}
|
||||
}
|
||||
|
||||
if (vueMode && !this.graph.extra.vueNodesScaled) {
|
||||
scaleLayoutForVueNodes()
|
||||
this.graph.extra.vueNodesScaled = true
|
||||
}
|
||||
ensureCorrectLayoutScale()
|
||||
|
||||
if (
|
||||
restore_view &&
|
||||
|
||||
Reference in New Issue
Block a user