Fix snap offset for reroutes and subgraph IO (#10229)

When snapping to grid, reroutes and subgraph IO would snap at an awful y
offset.

| Before | After |
| ------ | ----- |
| <img width="360" alt="before"
src="https://github.com/user-attachments/assets/285cfd52-2242-4242-b031-926677575542"
/> | <img width="360" alt="after"
src="https://github.com/user-attachments/assets/4920ef9b-8eb1-4330-8eea-9992ad662018"
/>|


Regretfully, the PR leaves more magic constants than I would like.
There's a hardcoded `0.7` multiplier on `NODE_SLOT_HEIGHT` that isn't
defined as a constant, and it seems circular imports prevent constants
being used to declare the subgraphIO `roundedRadius`

See #8838 (Sorry for the delay. This change wound up being real simple)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10229-Fix-snap-offset-for-reroutes-and-subgraph-IO-3276d73d365081c2866dc388898a1be4)
by [Unito](https://www.unito.io)
This commit is contained in:
AustinMroz
2026-03-23 12:59:47 -07:00
committed by GitHub
parent 2d88720d80
commit 860d049487
4 changed files with 52 additions and 6 deletions

View File

@@ -7,7 +7,8 @@ import {
LGraph,
LGraphNode,
LiteGraph,
LLink
LLink,
Reroute
} from '@/lib/litegraph/src/litegraph'
import type { SerialisableGraph } from '@/lib/litegraph/src/types/serialisation'
import type { UUID } from '@/lib/litegraph/src/utils/uuid'
@@ -17,6 +18,7 @@ import {
createTestSubgraphData,
createTestSubgraphNode
} from './subgraph/__fixtures__/subgraphHelpers'
import { subgraphTest } from './subgraph/__fixtures__/subgraphFixtures'
import {
duplicateLinksRoot,
@@ -98,6 +100,42 @@ describe('LGraph', () => {
const fromOldSchema = new LGraph(oldSchemaGraph)
expect(fromOldSchema).toMatchSnapshot('oldSchemaGraph')
})
subgraphTest('should snap slots to same y-level', ({ emptySubgraph }) => {
const node = new LGraphNode('testname')
node.addInput('test', 'IMAGE')
emptySubgraph.add(node)
emptySubgraph.inputNode.pos = [0, 0]
// Reroute needs offset of ~20y to align with first slot
const reroute = new Reroute(1, emptySubgraph, [0, 20])
node.snapToGrid(10)
reroute.snapToGrid(10)
emptySubgraph.inputNode.snapToGrid(10)
node.arrange()
emptySubgraph.inputNode.arrange()
const yPos = node.getInputPos(0)[1]
expect(reroute.pos[1]).toBe(yPos)
expect(emptySubgraph.inputNode.emptySlot.pos[1]).toBe(yPos)
// Assign non-equal positions and repeat
emptySubgraph.inputNode.pos = [0, 43]
node.pos = [0, 50]
reroute.pos = [0, 63]
node.snapToGrid(10)
reroute.snapToGrid(10)
emptySubgraph.inputNode.snapToGrid(10)
node.arrange()
emptySubgraph.inputNode.arrange()
const yPos2 = node.getInputPos(0)[1]
expect(reroute.pos[1]).toBe(yPos2)
expect(emptySubgraph.inputNode.emptySlot.pos[1]).toBe(yPos2)
})
})
describe('Floating Links / Reroutes', () => {