Fix vue node slot position calculation (#7877)

## Summary

Fix slot position for Vue nodes using LiteGraph calculation

Fixes #7446

## Changes
- Updated getInput/OutputPos to call getSlotPosition which handles
positions for both LiteGraph & Vue nodes correctly
- Add regression test

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7877-Fix-vue-node-slot-position-calculation-2e16d73d365081219afef0e4ebfb0620)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
pythongosssss
2026-01-14 03:40:21 +00:00
committed by GitHub
parent b1b2fd8a4f
commit ebca0cb1e0
7 changed files with 115 additions and 45 deletions

View File

@@ -1,8 +1,6 @@
import { LGraphNodeProperties } from '@/lib/litegraph/src/LGraphNodeProperties'
import {
calculateInputSlotPos,
calculateInputSlotPosFromSlot,
calculateOutputSlotPos,
getSlotPosition
} from '@/renderer/core/canvas/litegraph/slotCalculations'
import type { SlotPositionContext } from '@/renderer/core/canvas/litegraph/slotCalculations'
@@ -3349,7 +3347,7 @@ export class LGraphNode
* @returns Position of the input slot
*/
getInputPos(slot: number): Point {
return calculateInputSlotPos(this.#getSlotPositionContext(), slot)
return getSlotPosition(this, slot, true)
}
/**
@@ -3369,10 +3367,7 @@ export class LGraphNode
* @returns Position of the output slot
*/
getOutputPos(outputSlotIndex: number): Point {
return calculateOutputSlotPos(
this.#getSlotPositionContext(),
outputSlotIndex
)
return getSlotPosition(this, outputSlotIndex, false)
}
/**

View File

@@ -45,7 +45,7 @@ export interface SlotPositionContext {
* @param slot The input slot index
* @returns Position of the input slot center in graph coordinates
*/
export function calculateInputSlotPos(
function calculateInputSlotPos(
context: SlotPositionContext,
slot: number
): Point {
@@ -93,7 +93,7 @@ export function calculateInputSlotPosFromSlot(
* @param slot The output slot index
* @returns Position of the output slot center in graph coordinates
*/
export function calculateOutputSlotPos(
function calculateOutputSlotPos(
context: SlotPositionContext,
slot: number
): Point {
@@ -138,38 +138,41 @@ export function getSlotPosition(
slotIndex: number,
isInput: boolean
): Point {
// Try to get precise position from slot layout (DOM-registered)
const slotKey = getSlotKey(String(node.id), slotIndex, isInput)
const slotLayout = layoutStore.getSlotLayout(slotKey)
if (slotLayout) {
return [slotLayout.position.x, slotLayout.position.y]
}
// Fallback: derive position from node layout tree and slot model
const nodeLayout = layoutStore.getNodeLayoutRef(String(node.id)).value
if (nodeLayout) {
// Create context from layout tree data
const context: SlotPositionContext = {
nodeX: nodeLayout.position.x,
nodeY: nodeLayout.position.y,
nodeWidth: nodeLayout.size.width,
nodeHeight: nodeLayout.size.height,
collapsed: node.flags.collapsed || false,
collapsedWidth: node._collapsed_width,
slotStartY: node.constructor.slot_start_y,
inputs: node.inputs,
outputs: node.outputs,
widgets: node.widgets
// Only use DOM-registered slot positions when Vue nodes mode is enabled
if (LiteGraph.vueNodesMode) {
// Try to get precise position from slot layout (DOM-registered)
const slotKey = getSlotKey(String(node.id), slotIndex, isInput)
const slotLayout = layoutStore.getSlotLayout(slotKey)
if (slotLayout) {
return [slotLayout.position.x, slotLayout.position.y]
}
// Use helper to calculate position
return isInput
? calculateInputSlotPos(context, slotIndex)
: calculateOutputSlotPos(context, slotIndex)
// Fallback: derive position from node layout tree and slot model
const nodeLayout = layoutStore.getNodeLayoutRef(String(node.id)).value
if (nodeLayout) {
// Create context from layout tree data
const context: SlotPositionContext = {
nodeX: nodeLayout.position.x,
nodeY: nodeLayout.position.y,
nodeWidth: nodeLayout.size.width,
nodeHeight: nodeLayout.size.height,
collapsed: node.flags.collapsed || false,
collapsedWidth: node._collapsed_width,
slotStartY: node.constructor.slot_start_y,
inputs: node.inputs,
outputs: node.outputs,
widgets: node.widgets
}
// Use helper to calculate position
return isInput
? calculateInputSlotPos(context, slotIndex)
: calculateOutputSlotPos(context, slotIndex)
}
}
// Fallback: calculate directly from node properties if layout not available
// Fallback: calculate directly from node properties (legacy litegraph behavior)
const context: SlotPositionContext = {
nodeX: node.pos[0],
nodeY: node.pos[1],