mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-05 07:30:11 +00:00
Snap everything to grid (#315)
* Implement snap to grid - Moves positioning logic to LGraph - Simplifies code - Adds Pointer API to alt-clone node - Removes always_round_positions, replaced by always snap to grid (default size is 1 when always snapping) Fix refator error * Fix group items snapped without group * Allow snapping of all items - Add snapToGrid to Positionable - Impl. on all types - Deprecated: alignToGrid is now a wrapper * Fix test import alias, update expectations * Prevent desync of before / after change events Adds ability to perform late binding of finally() during drag start. * nit - Refactor * Fix unwanted snap on node/group add * nit - Doc * Add shift key state tracking for snap to grid Private impl., no state API as yet. * Add snap guides rendering Nodes, reroutes * Optimisation - reroute rendering Fixes exponential redraw * Add snap guidelines for groups
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { Dictionary, IContextMenuValue, LinkNetwork, ISlotType, MethodNames, Point, LinkSegment } from "./interfaces"
|
||||
import type { Dictionary, IContextMenuValue, LinkNetwork, ISlotType, MethodNames, Point, LinkSegment, Positionable } from "./interfaces"
|
||||
import type { ISerialisedGraph, Serialisable, SerialisableGraph, SerialisableReroute } from "./types/serialisation"
|
||||
import { Reroute, RerouteId } from "./Reroute"
|
||||
import { LGraphEventMode } from "./types/globalEnums"
|
||||
@@ -9,6 +9,7 @@ import { type NodeId, LGraphNode } from "./LGraphNode"
|
||||
import { type LinkId, LLink } from "./LLink"
|
||||
import { MapProxyHandler } from "./MapProxyHandler"
|
||||
import { isSortaInsideOctagon } from "./measure"
|
||||
import { getAllNestedItems } from "./utils/collections"
|
||||
|
||||
interface IGraphInput {
|
||||
name: string
|
||||
@@ -25,6 +26,26 @@ export interface LGraphState {
|
||||
|
||||
type ParamsArray<T extends Record<any, any>, K extends MethodNames<T>> = Parameters<T[K]>[1] extends undefined ? Parameters<T[K]> | Parameters<T[K]>[0] : Parameters<T[K]>
|
||||
|
||||
/** Configuration used by {@link LGraph} `config`. */
|
||||
export interface LGraphConfig {
|
||||
/** @deprecated Legacy config - unused */
|
||||
align_to_grid?: any
|
||||
/**
|
||||
* When set to a positive number, when nodes are moved their positions will
|
||||
* be rounded to the nearest multiple of this value. Half up.
|
||||
* Default: `undefined`
|
||||
* @todo Not implemented - see {@link LiteGraph.CANVAS_GRID_SIZE}
|
||||
*/
|
||||
snapToGrid?: number
|
||||
/**
|
||||
* If `true`, items always snap to the grid - modifier keys are ignored.
|
||||
* When {@link snapToGrid} is falsy, a value of `1` is used.
|
||||
* Default: `false`
|
||||
*/
|
||||
alwaysSnapToGrid?: boolean
|
||||
links_ontop?: any
|
||||
}
|
||||
|
||||
/**
|
||||
* LGraph is the class that contain a full graph. We instantiate one and add nodes to it, and then we can run the execution loop.
|
||||
* supported callbacks:
|
||||
@@ -81,7 +102,7 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
|
||||
filter?: string
|
||||
_subgraph_node?: LGraphNode
|
||||
/** Must contain serialisable values, e.g. primitive types */
|
||||
config: { align_to_grid?: any; links_ontop?: any }
|
||||
config: LGraphConfig
|
||||
vars: Dictionary<unknown>
|
||||
nodes_executing: boolean[]
|
||||
nodes_actioning: (string | boolean)[]
|
||||
@@ -710,6 +731,12 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
|
||||
if (!node) return
|
||||
const { state } = this
|
||||
|
||||
// Ensure created items are snapped
|
||||
if (this.config.alwaysSnapToGrid) {
|
||||
const snapTo = this.getSnapToGridSize()
|
||||
if (snapTo) node.snapToGrid(snapTo)
|
||||
}
|
||||
|
||||
// LEGACY: This was changed from constructor === LGraphGroup
|
||||
//groups
|
||||
if (node instanceof LGraphGroup) {
|
||||
@@ -961,6 +988,36 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Snaps the provided items to a grid.
|
||||
*
|
||||
* Item positions are reounded to the nearest multiple of {@link LiteGraph.CANVAS_GRID_SIZE}.
|
||||
*
|
||||
* When {@link config}.{@link LGraphConfig.alwaysSnapToGrid alwaysSnapToGrid} is enabled
|
||||
* and the grid size is falsy, a default of 1 is used.
|
||||
* @param items The items to snap to the grid
|
||||
* @todo Currently only snaps nodes.
|
||||
*/
|
||||
snapToGrid(items: Set<Positionable>): void {
|
||||
const snapTo = this.getSnapToGridSize()
|
||||
if (!snapTo) return
|
||||
|
||||
getAllNestedItems(items).forEach(item => {
|
||||
if (!item.pinned) item.snapToGrid(snapTo)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the size of the grid that items should be snapped to when moved.
|
||||
* @returns The size of the grid that items should be snapped to
|
||||
*/
|
||||
getSnapToGridSize(): number {
|
||||
// Default to 1 when always snapping
|
||||
return this.config.alwaysSnapToGrid
|
||||
? LiteGraph.CANVAS_GRID_SIZE || 1
|
||||
: LiteGraph.CANVAS_GRID_SIZE
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the node type matches the node type registered, used when replacing a nodetype by a newer version during execution
|
||||
* this replaces the ones using the old version with the new version
|
||||
|
||||
Reference in New Issue
Block a user