mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 06:47:33 +00:00
## Summary Snap link preview to the nearest compatible slot while dragging in Vue Nodes mode, and complete the connection on drop using the snapped target. Mirrors LiteGraph’s first-compatible-slot logic for node-level snapping and reuses the computed candidate for performance. ## Changes - Snap preview end to compatible slot - slot under cursor via `data-slot-key` fast-path - node under cursor via `findInputByType` / `findOutputByType` - Render path - `slotLinkPreviewRenderer.ts` now renders to `state.candidate.layout.position` - Complete on drop - Prefer `state.candidate` (no re-hit-testing) - Fallbacks: DOM slot → node first-compatible → reroute - Disconnects moving input link when dropped on canvas ## Review Focus - UX feel of snapping and drop completion (both directions) - Performance on large graphs (mousemove path is O(1) with dataset + single validation) - Edge cases: reroutes, moving existing links, collapsed nodes ## Screenshots (if applicable) https://github.com/user-attachments/assets/fbed0ae2-2231-473b-a05a-9aaf68e3f820 https://github.com/Comfy-Org/ComfyUI_frontend/pull/5780 (snapping) <-- https://github.com/Comfy-Org/ComfyUI_frontend/pull/5898 (drop on canvas + linkconnectoradapter refactor) <-- https://github.com/Comfy-Org/ComfyUI_frontend/pull/5903 (fix reroute snapping) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5780-feat-vue-nodes-snap-link-preview-connect-on-drop-27a6d73d365081d89c8cf570e2049c89) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
30 lines
554 B
TypeScript
30 lines
554 B
TypeScript
export function createRafBatch(run: () => void) {
|
|
let rafId: number | null = null
|
|
|
|
const schedule = () => {
|
|
if (rafId != null) return
|
|
rafId = requestAnimationFrame(() => {
|
|
rafId = null
|
|
run()
|
|
})
|
|
}
|
|
|
|
const cancel = () => {
|
|
if (rafId != null) {
|
|
cancelAnimationFrame(rafId)
|
|
rafId = null
|
|
}
|
|
}
|
|
|
|
const flush = () => {
|
|
if (rafId == null) return
|
|
cancelAnimationFrame(rafId)
|
|
rafId = null
|
|
run()
|
|
}
|
|
|
|
const isScheduled = () => rafId != null
|
|
|
|
return { schedule, cancel, flush, isScheduled }
|
|
}
|