Comfy-Org / Comfy-Org/ComfyUI_frontend

Vue nodes can't snap to grid

Open
#5,684 0 comments 0 reactions 0 assignees View on GitHub
area:nodes area:ui area:vue-migration
Dominant language
TypeScript
Stars
2k
Forks
699
Avg merge
1d 7h
Merged PRs (30d)
490

Description

https://github.com/user-attachments/assets/e3f9a942-8b07-4ada-ad8e-1a5de60c366d

## Problem Statement

**Current Behavior:**
- ✅ LiteGraph nodes: Snap to grid works with Shift+drag or "Always snap" setting
- ❌ Vue nodes: No snap to grid functionality - move freely without grid alignment

**Expected Behavior:**
- Vue nodes should snap to grid when Shift is held during drag
- "Always snap to grid" setting should affect Vue nodes
- Consistent snap behavior between LiteGraph and Vue rendering modes

## Technical Root Cause

Vue nodes use a completely separate positioning system (`useNodeLayout.ts`) that bypasses LiteGraph snap logic entirely.

**LiteGraph Implementation** (Working):
- Uses `snapPoint()` utility to round coordinates to grid multiples
- Detects Shift key or "Always snap" setting during drag
- Applies snapping via `graph.snapToGrid()` on drag completion

**Vue Node Implementation** (Missing Integration):
```typescript
// In useNodeLayout.ts handleDrag() - NO SNAPPING
const newPosition = {
x: dragStartPos.x + canvasDelta.x, // Direct calculation
y: dragStartPos.y + canvasDelta.y // No snap applied
}
mutations.moveNode(nodeId, newPosition)
```

**Missing Components:**
- No access to snap settings (`gridSize`, `alwaysSnap`)
- No shift key detection in Vue drag handlers
- No `snapPoint()` application in positioning logic

## Proposed Solution

**Integrate snap logic into Vue node drag handling:**

```typescript
// In useNodeLayout.ts
import { snapPoint } from @/lib/litegraph/src/measure
import { useSettingStore } from @/platform/settings/settingStore

const handleDrag = (nodeId: string, event: PointerEvent) => {
const newPosition = {
x: dragStartPos.x + canvasDelta.x,
y: dragStartPos.y + canvasDelta.y
}

// Add snap logic
const settingStore = useSettingStore()
const gridSize = settingStore.get(Comfy.SnapToGrid.GridSize)
const alwaysSnap = settingStore.get(pysssss.SnapToGrid)

if ((event.shiftKey || alwaysSnap) && gridSize > 0) {
snapPoint([newPosition.x, newPosition.y], gridSize)
}

mutations.moveNode(nodeId, newPosition)
}
```

## Steps to Reproduce

1. Enable Vue node rendering (`area:vue-migration`)
2. Set grid size > 1 and enable "Always snap to grid"
3. Drag a Vue node - observe no snapping occurs
4. Compare with LiteGraph mode - snapping works correctly

## Key Files

- **Primary fix**: `src/renderer/extensions/vueNodes/layout/useNodeLayout.ts:96-137`
- **Snap utility**: `src/lib/litegraph/src/measure.ts`
- **Settings**: `src/platform/settings/constants/coreSettings.ts`

┆Issue is synchronized with this [Notion page](https://www.notion.so/Issue-5684-VUE-nodes-can-t-snap-to-grid-2746d73d365081c0ad19da32fd5e5d3d) by [Unito](https://www.unito.io)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.