mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-02 22:37:32 +00:00
btw, I forgot, demo is now called editor
This commit is contained in:
7
CONTRIBUTING.md
Normal file
7
CONTRIBUTING.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Contribution Rules
|
||||
There are some simple rules that everyone should follow:
|
||||
|
||||
### Do not commit files from bulid folder
|
||||
> I usually have horrible merge conflicts when I upload the build version that take me too much time to solve, but I want to keep the build version in the repo, so I guess it would be better if only one of us does the built, which would be me.
|
||||
> https://github.com/jagenjo/litegraph.js/pull/155#issuecomment-656602861
|
||||
Those files will be updated by owner.
|
||||
@@ -19,6 +19,7 @@ Try it in the [demo site](https://tamats.com/projects/litegraph/demo).
|
||||
- Graphs can be executed in NodeJS
|
||||
- Highly customizable nodes (color, shape, slots vertical or horizontal, widgets, custom rendering)
|
||||
- Easy to integrate in any JS application (one single file, no dependencies)
|
||||
- Typescript support
|
||||
|
||||
## Nodes provided
|
||||
Although it is easy to create new node types, LiteGraph comes with some default nodes that could be useful for many cases:
|
||||
@@ -180,6 +181,7 @@ You can write any feedback to javi.agenjo@gmail.com
|
||||
- InventivetalentDev
|
||||
- NateScarlet
|
||||
- coderofsalvation
|
||||
- ilyabesk
|
||||
|
||||
|
||||
|
||||
|
||||
1392
build/litegraph.js
1392
build/litegraph.js
File diff suppressed because it is too large
Load Diff
1440
build/litegraph.min.js
vendored
1440
build/litegraph.min.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -60,11 +60,14 @@ There are several settings that could be defined or modified per node:
|
||||
* **size**: ```[width,height]``` the size of the area inside the node (excluding title). Every row is LiteGraph.NODE_SLOT_HEIGHT pixels height.
|
||||
* **properties**: object containing the properties that could be configured by the user, and serialized when saving the graph
|
||||
* **shape**: the shape of the object (could be LiteGraph.BOX_SHAPE,LiteGraph.ROUND_SHAPE,LiteGraph.CARD_SHAPE)
|
||||
* **flags**: several flags
|
||||
* **resizable**: if it can be resized dragging the corner
|
||||
* **horizontal**: if the slots should be placed horizontally on the top and bottom of the node
|
||||
* **clip_area**: clips the content when rendering the node
|
||||
* **flags**: flags that can be changed by the user and will be stored when serialized
|
||||
* **collapsed**: if it is shown collapsed (small)
|
||||
* **redraw_on_mouse**: forces a redraw if the mouse passes over the widget
|
||||
* **widgets_up**: widgets do not start after the slots
|
||||
* **widgets_start_y**: widgets should start being drawn from this Y
|
||||
* **clip_area**: clips the content when rendering the node
|
||||
* **resizable**: if it can be resized dragging the corner
|
||||
* **horizontal**: if the slots should be placed horizontally on the top and bottom of the node
|
||||
|
||||
There are several callbacks that could be defined by the user:
|
||||
* **onAdded**: called when added to graph
|
||||
|
||||
52
src/litegraph.d.ts
vendored
52
src/litegraph.d.ts
vendored
@@ -11,11 +11,17 @@ export type widgetTypes =
|
||||
| "text"
|
||||
| "toggle"
|
||||
| "button";
|
||||
export type SlotShape =
|
||||
| typeof LiteGraph.BOX_SHAPE
|
||||
| typeof LiteGraph.CIRCLE_SHAPE
|
||||
| typeof LiteGraph.ARROW_SHAPE
|
||||
| typeof LiteGraph.SQUARE_SHAPE
|
||||
| number; // For custom shapes
|
||||
|
||||
/** https://github.com/jagenjo/litegraph.js/tree/master/guides#node-slots */
|
||||
export interface INodeSlot {
|
||||
name: string;
|
||||
type: string;
|
||||
type: string | -1;
|
||||
label?: string;
|
||||
dir?:
|
||||
| typeof LiteGraph.UP
|
||||
@@ -24,6 +30,7 @@ export interface INodeSlot {
|
||||
| typeof LiteGraph.LEFT;
|
||||
color_on?: string;
|
||||
color_off?: string;
|
||||
shape?: SlotShape;
|
||||
locked?: boolean;
|
||||
nameLocked?: boolean;
|
||||
}
|
||||
@@ -174,6 +181,7 @@ export const LiteGraph: {
|
||||
CIRCLE_SHAPE: 3;
|
||||
CARD_SHAPE: 4;
|
||||
ARROW_SHAPE: 5;
|
||||
SQUARE_SHAPE: 6;
|
||||
|
||||
//enums
|
||||
INPUT: 1;
|
||||
@@ -231,6 +239,8 @@ export const LiteGraph: {
|
||||
registerNodeType(type: string, base: { new (): LGraphNode }): void;
|
||||
/** removes a node type from the system */
|
||||
unregisterNodeType(type: string): void;
|
||||
/** Removes all previously registered node's types. */
|
||||
clearRegisteredTypes(): void;
|
||||
/**
|
||||
* Create a new node type by passing a function, it wraps it with a proper class and generates inputs according to the parameters of the function.
|
||||
* Useful to wrap simple methods that do not require properties, and that only process some input to generate an output.
|
||||
@@ -601,7 +611,9 @@ export declare class LGraphNode {
|
||||
properties: Record<string, any>;
|
||||
properties_info: any[];
|
||||
|
||||
flags: object;
|
||||
flags: Partial<{
|
||||
collapsed: boolean
|
||||
}>;
|
||||
|
||||
color: string;
|
||||
bgcolor: string;
|
||||
@@ -623,6 +635,17 @@ export declare class LGraphNode {
|
||||
| typeof LiteGraph.NEVER
|
||||
| typeof LiteGraph.ALWAYS;
|
||||
|
||||
/** If set to true widgets do not start after the slots */
|
||||
widgets_up: boolean;
|
||||
/** widgets start at y distance from the top of the node */
|
||||
widgets_start_y: number;
|
||||
/** if you render outside the node, it will be clipped */
|
||||
clip_area: boolean;
|
||||
/** if set to false it wont be resizable with the mouse */
|
||||
resizable: boolean;
|
||||
/** slots are distributed horizontally */
|
||||
horizontal: boolean;
|
||||
|
||||
/** configure a node from an object containing the serialized info */
|
||||
configure(info: SerializedLGraphNode): void;
|
||||
/** serialize the content */
|
||||
@@ -715,7 +738,7 @@ export declare class LGraphNode {
|
||||
*/
|
||||
addOutput(
|
||||
name: string,
|
||||
type: string,
|
||||
type: string | -1,
|
||||
extra_info?: Partial<INodeOutputSlot>
|
||||
): void;
|
||||
/**
|
||||
@@ -723,7 +746,7 @@ export declare class LGraphNode {
|
||||
* @param array of triplets like [[name,type,extra_info],[...]]
|
||||
*/
|
||||
addOutputs(
|
||||
array: [string, string, Partial<INodeOutputSlot> | undefined][]
|
||||
array: [string, string | -1, Partial<INodeOutputSlot> | undefined][]
|
||||
): void;
|
||||
/** remove an existing output slot */
|
||||
removeOutput(slot: number): void;
|
||||
@@ -735,7 +758,7 @@ export declare class LGraphNode {
|
||||
*/
|
||||
addInput(
|
||||
name: string,
|
||||
type: string,
|
||||
type: string | -1,
|
||||
extra_info?: Partial<INodeInputSlot>
|
||||
): void;
|
||||
/**
|
||||
@@ -743,7 +766,7 @@ export declare class LGraphNode {
|
||||
* @param array of triplets like [[name,type,extra_info],[...]]
|
||||
*/
|
||||
addInputs(
|
||||
array: [string, string, Partial<INodeInputSlot> | undefined][]
|
||||
array: [string, string | -1, Partial<INodeInputSlot> | undefined][]
|
||||
): void;
|
||||
/** remove an existing input slot */
|
||||
removeInput(slot: number): void;
|
||||
@@ -777,7 +800,7 @@ export declare class LGraphNode {
|
||||
type: T["type"],
|
||||
name: string,
|
||||
value: T["value"],
|
||||
callback?: WidgetCallback<T>,
|
||||
callback?: WidgetCallback<T> | string,
|
||||
options?: T["options"]
|
||||
): T;
|
||||
|
||||
@@ -938,6 +961,17 @@ export declare class LGraphNode {
|
||||
_this: this,
|
||||
slotIndex: number
|
||||
): boolean;
|
||||
|
||||
/**
|
||||
* Called just before connection (or disconnect - if input is linked).
|
||||
* A convenient place to switch to another input, or create new one.
|
||||
* This allow for ability to automatically add slots if needed
|
||||
* @param inputIndex
|
||||
* @return selected input slot index, can differ from parameter value
|
||||
*/
|
||||
onBeforeConnectInput?(
|
||||
inputIndex: number
|
||||
): number;
|
||||
|
||||
/** a connection changed (new one or removed) (LiteGraph.INPUT or LiteGraph.OUTPUT, slot, true if connected, link_info, input_info or output_info ) */
|
||||
onConnectionsChange(
|
||||
@@ -1111,7 +1145,7 @@ export declare class LGraphCanvas {
|
||||
last_mouse_position: Vector2;
|
||||
/** Timestamp of last mouse click, defaults to 0 */
|
||||
last_mouseclick: number;
|
||||
link_render_mode:
|
||||
links_render_mode:
|
||||
| typeof LiteGraph.STRAIGHT_LINK
|
||||
| typeof LiteGraph.LINEAR_LINK
|
||||
| typeof LiteGraph.SPLINE_LINK;
|
||||
@@ -1277,6 +1311,8 @@ export declare class LGraphCanvas {
|
||||
drawBackCanvas(): void;
|
||||
/** draws the given node inside the canvas */
|
||||
drawNode(node: LGraphNode, ctx: CanvasRenderingContext2D): void;
|
||||
/** draws graphic for node's slot */
|
||||
drawSlotGraphic(ctx: CanvasRenderingContext2D, pos: number[], shape: SlotShape, horizontal: boolean): void;
|
||||
/** draws the shape of the given node in the canvas */
|
||||
drawNodeShape(
|
||||
node: LGraphNode,
|
||||
|
||||
176
src/litegraph.js
176
src/litegraph.js
@@ -53,6 +53,7 @@
|
||||
CIRCLE_SHAPE: 3,
|
||||
CARD_SHAPE: 4,
|
||||
ARROW_SHAPE: 5,
|
||||
SQUARE_SHAPE: 6,
|
||||
|
||||
//enums
|
||||
INPUT: 1,
|
||||
@@ -94,6 +95,16 @@
|
||||
|
||||
searchbox_extras: {}, //used to add extra features to the search box
|
||||
|
||||
/**
|
||||
* Removes all previously registered node's types
|
||||
*/
|
||||
clearRegisteredTypes: function() {
|
||||
this.registered_node_types = {};
|
||||
this.node_types_by_file_extension = {};
|
||||
this.Nodes = {};
|
||||
this.searchbox_extras = {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Register a node class so it can be listed when the user wants to create a new one
|
||||
* @method registerNodeType
|
||||
@@ -3210,10 +3221,10 @@
|
||||
/**
|
||||
* computes the minimum size of a node according to its inputs and output slots
|
||||
* @method computeSize
|
||||
* @param {number} minHeight
|
||||
* @param {number} the optional target width
|
||||
* @return {number} the total size
|
||||
*/
|
||||
LGraphNode.prototype.computeSize = function(out) {
|
||||
LGraphNode.prototype.computeSize = function(width, out) {
|
||||
if (this.constructor.size) {
|
||||
return this.constructor.size.concat();
|
||||
}
|
||||
@@ -3265,7 +3276,7 @@
|
||||
if (this.widgets && this.widgets.length) {
|
||||
for (var i = 0, l = this.widgets.length; i < l; ++i) {
|
||||
if (this.widgets[i].computeSize)
|
||||
widgets_height += this.widgets[i].computeSize(size[0])[1] + 4;
|
||||
widgets_height += this.widgets[i].computeSize(Math.max(size[0], width || 0))[1] + 4;
|
||||
else
|
||||
widgets_height += LiteGraph.NODE_WIDGET_HEIGHT + 4;
|
||||
}
|
||||
@@ -3631,28 +3642,34 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
//if there is something already plugged there, disconnect
|
||||
if (target_node.inputs[target_slot].link != null) {
|
||||
target_node.disconnectInput(target_slot);
|
||||
}
|
||||
|
||||
//why here??
|
||||
//this.setDirtyCanvas(false,true);
|
||||
//this.graph.connectionChange( this );
|
||||
|
||||
var output = this.outputs[slot];
|
||||
|
||||
//allows nodes to block connection
|
||||
if (target_node.onConnectInput) {
|
||||
if ( target_node.onConnectInput(target_slot, output.type, output, this, slot) === false ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var input = target_node.inputs[target_slot];
|
||||
var link_info = null;
|
||||
|
||||
if (LiteGraph.isValidConnection(output.type, input.type)) {
|
||||
if (target_node.onBeforeConnectInput) {
|
||||
// This way node can choose another slot (if selected is occupied)
|
||||
target_slot = target_node.onBeforeConnectInput(target_slot);
|
||||
input = target_node.inputs[target_slot];
|
||||
}
|
||||
|
||||
//if there is something already plugged there, disconnect
|
||||
if (target_node.inputs[target_slot].link != null) {
|
||||
target_node.disconnectInput(target_slot);
|
||||
}
|
||||
|
||||
//why here??
|
||||
//this.setDirtyCanvas(false,true);
|
||||
//this.graph.connectionChange( this );
|
||||
|
||||
//allows nodes to block connection
|
||||
if (target_node.onConnectInput) {
|
||||
if ( target_node.onConnectInput(target_slot, output.type, output, this, slot) === false ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var link_info = null;
|
||||
|
||||
link_info = new LLink(
|
||||
++this.graph.last_link_id,
|
||||
input.type,
|
||||
@@ -5665,7 +5682,7 @@ LGraphNode.prototype.executeAction = function(action)
|
||||
if (this.resizing_node && !this.live_mode) {
|
||||
//convert mouse to node space
|
||||
var desired_size = [ e.canvasX - this.resizing_node.pos[0], e.canvasY - this.resizing_node.pos[1] ];
|
||||
var min_size = this.resizing_node.computeSize();
|
||||
var min_size = this.resizing_node.computeSize(desired_size[0]);
|
||||
desired_size[0] = Math.max( min_size[0], desired_size[0] );
|
||||
desired_size[1] = Math.max( min_size[1], desired_size[1] );
|
||||
this.resizing_node.setSize( desired_size );
|
||||
@@ -7212,6 +7229,44 @@ LGraphNode.prototype.executeAction = function(action)
|
||||
|
||||
var temp_vec2 = new Float32Array(2);
|
||||
|
||||
LGraphCanvas.prototype.drawSlotGraphic = function(ctx, pos, shape, horizontal) {
|
||||
ctx.beginPath();
|
||||
|
||||
switch (shape) {
|
||||
case (LiteGraph.BOX_SHAPE):
|
||||
if (horizontal) {
|
||||
ctx.rect(
|
||||
pos[0] - 5 + 0.5,
|
||||
pos[1] - 8 + 0.5,
|
||||
10,
|
||||
14
|
||||
);
|
||||
} else {
|
||||
ctx.rect(
|
||||
pos[0] - 6 + 0.5,
|
||||
pos[1] - 5 + 0.5,
|
||||
14,
|
||||
10
|
||||
);
|
||||
}
|
||||
break;
|
||||
case (LiteGraph.ARROW_SHAPE):
|
||||
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
|
||||
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
|
||||
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
|
||||
ctx.closePath();
|
||||
break;
|
||||
case (LiteGraph.SQUARE_SHAPE):
|
||||
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8); //faster
|
||||
break;
|
||||
case (LiteGraph.CIRCLE_SHAPE):
|
||||
default:
|
||||
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
|
||||
break;
|
||||
}
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
/**
|
||||
* draws the given node inside the canvas
|
||||
* @method drawNode
|
||||
@@ -7361,39 +7416,9 @@ LGraphNode.prototype.executeAction = function(action)
|
||||
max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5;
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
if (
|
||||
slot.type === LiteGraph.EVENT ||
|
||||
slot.shape === LiteGraph.BOX_SHAPE
|
||||
) {
|
||||
if (horizontal) {
|
||||
ctx.rect(
|
||||
pos[0] - 5 + 0.5,
|
||||
pos[1] - 8 + 0.5,
|
||||
10,
|
||||
14
|
||||
);
|
||||
} else {
|
||||
ctx.rect(
|
||||
pos[0] - 6 + 0.5,
|
||||
pos[1] - 5 + 0.5,
|
||||
14,
|
||||
10
|
||||
);
|
||||
}
|
||||
} else if (slot.shape === LiteGraph.ARROW_SHAPE) {
|
||||
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
|
||||
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
|
||||
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
|
||||
ctx.closePath();
|
||||
} else {
|
||||
if(low_quality)
|
||||
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 ); //faster
|
||||
else
|
||||
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
|
||||
}
|
||||
ctx.fill();
|
||||
var shape = slot.shape || (slot.type === LiteGraph.EVENT && LiteGraph.BOX_SHAPE)
|
||||
|| (low_quality && LiteGraph.SQUARE_SHAPE) || LiteGraph.CIRCLE_SHAPE;
|
||||
this.drawSlotGraphic(ctx, pos, shape, horizontal);
|
||||
|
||||
//render name
|
||||
if (render_text) {
|
||||
@@ -7434,46 +7459,11 @@ LGraphNode.prototype.executeAction = function(action)
|
||||
this.default_connection_color.output_on
|
||||
: slot.color_off ||
|
||||
this.default_connection_color.output_off;
|
||||
ctx.beginPath();
|
||||
//ctx.rect( node.size[0] - 14,i*14,10,10);
|
||||
|
||||
if (
|
||||
slot.type === LiteGraph.EVENT ||
|
||||
slot.shape === LiteGraph.BOX_SHAPE
|
||||
) {
|
||||
if (horizontal) {
|
||||
ctx.rect(
|
||||
pos[0] - 5 + 0.5,
|
||||
pos[1] - 8 + 0.5,
|
||||
10,
|
||||
14
|
||||
);
|
||||
} else {
|
||||
ctx.rect(
|
||||
pos[0] - 6 + 0.5,
|
||||
pos[1] - 5 + 0.5,
|
||||
14,
|
||||
10
|
||||
);
|
||||
}
|
||||
} else if (slot.shape === LiteGraph.ARROW_SHAPE) {
|
||||
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
|
||||
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
|
||||
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
|
||||
ctx.closePath();
|
||||
} else {
|
||||
if(low_quality)
|
||||
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 );
|
||||
else
|
||||
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
|
||||
}
|
||||
var shape = slot.shape || (slot.type === LiteGraph.EVENT && LiteGraph.BOX_SHAPE)
|
||||
|| (low_quality && LiteGraph.SQUARE_SHAPE) || LiteGraph.CIRCLE_SHAPE;
|
||||
this.drawSlotGraphic(ctx, pos, shape, horizontal);
|
||||
|
||||
//trigger
|
||||
//if(slot.node_id != null && slot.slot == -1)
|
||||
// ctx.fillStyle = "#F85";
|
||||
|
||||
//if(slot.links != null && slot.links.length)
|
||||
ctx.fill();
|
||||
if(!low_quality)
|
||||
ctx.stroke();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user