mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-10 23:50:00 +00:00
added remove slot option
This commit is contained in:
0
src/litegraph-editor.js
Normal file → Executable file
0
src/litegraph-editor.js
Normal file → Executable file
183
src/litegraph.js
Normal file → Executable file
183
src/litegraph.js
Normal file → Executable file
@@ -784,7 +784,7 @@ LGraph.prototype.getNodeOnPos = function(x,y, nodes_list)
|
||||
for (var i = nodes_list.length - 1; i >= 0; i--)
|
||||
{
|
||||
var n = nodes_list[i];
|
||||
if(n.isPointInsideNode(x,y))
|
||||
if(n.isPointInsideNode( x, y, 2 ))
|
||||
return n;
|
||||
}
|
||||
return null;
|
||||
@@ -1125,7 +1125,15 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
|
||||
// Node CLASS *******
|
||||
// *************************************************************
|
||||
|
||||
/* flags:
|
||||
/*
|
||||
title: string
|
||||
pos: [x,y]
|
||||
size: [x,y]
|
||||
|
||||
input|output: every connection
|
||||
+ { name:string, type:string, pos: [x,y]=Optional, direction: "input"|"output", links: Array });
|
||||
|
||||
flags:
|
||||
+ skip_title_render
|
||||
+ clip_area
|
||||
+ unsafe_execution: not allowed for safe execution
|
||||
@@ -1351,7 +1359,7 @@ LGraphNode.prototype.setOutputData = function(slot,data)
|
||||
* retrieves the input data (data traveling through the connection) from one slot
|
||||
* @method getInputData
|
||||
* @param {number} slot
|
||||
* @return {*} data
|
||||
* @return {*} data or if it is not connected returns undefined
|
||||
*/
|
||||
LGraphNode.prototype.getInputData = function(slot)
|
||||
{
|
||||
@@ -1379,11 +1387,12 @@ LGraphNode.prototype.isInputConnected = function(slot)
|
||||
* tells you info about an input connection (which node, type, etc)
|
||||
* @method getInputInfo
|
||||
* @param {number} slot
|
||||
* @return {Object}
|
||||
* @return {Object} object or null
|
||||
*/
|
||||
LGraphNode.prototype.getInputInfo = function(slot)
|
||||
{
|
||||
if(!this.inputs) return null;
|
||||
if(!this.inputs)
|
||||
return null;
|
||||
if(slot < this.inputs.length)
|
||||
return this.inputs[slot];
|
||||
return null;
|
||||
@@ -1394,11 +1403,12 @@ LGraphNode.prototype.getInputInfo = function(slot)
|
||||
* tells you info about an output connection (which node, type, etc)
|
||||
* @method getOutputInfo
|
||||
* @param {number} slot
|
||||
* @return {Object}
|
||||
* @return {Object} object or null
|
||||
*/
|
||||
LGraphNode.prototype.getOutputInfo = function(slot)
|
||||
{
|
||||
if(!this.outputs) return null;
|
||||
if(!this.outputs)
|
||||
return null;
|
||||
if(slot < this.outputs.length)
|
||||
return this.outputs[slot];
|
||||
return null;
|
||||
@@ -1413,7 +1423,8 @@ LGraphNode.prototype.getOutputInfo = function(slot)
|
||||
*/
|
||||
LGraphNode.prototype.isOutputConnected = function(slot)
|
||||
{
|
||||
if(!this.outputs) return null;
|
||||
if(!this.outputs)
|
||||
return null;
|
||||
return (slot < this.outputs.length && this.outputs[slot].links && this.outputs[slot].links.length);
|
||||
}
|
||||
|
||||
@@ -1521,7 +1532,8 @@ LGraphNode.prototype.addInput = function(name,type,extra_info)
|
||||
for(var i in extra_info)
|
||||
o[i] = extra_info[i];
|
||||
|
||||
if(!this.inputs) this.inputs = [];
|
||||
if(!this.inputs)
|
||||
this.inputs = [];
|
||||
this.inputs.push(o);
|
||||
this.size = this.computeSize();
|
||||
if(this.onInputAdded)
|
||||
@@ -1590,11 +1602,44 @@ LGraphNode.prototype.computeSize = function(minHeight)
|
||||
{
|
||||
var rows = Math.max( this.inputs ? this.inputs.length : 1, this.outputs ? this.outputs.length : 1);
|
||||
var size = new Float32Array([0,0]);
|
||||
rows = Math.max(rows, 1);
|
||||
size[1] = rows * 14 + 6;
|
||||
if(!this.inputs || this.inputs.length == 0 || !this.outputs || this.outputs.length == 0)
|
||||
size[0] = LiteGraph.NODE_WIDTH * 0.5;
|
||||
else
|
||||
size[0] = LiteGraph.NODE_WIDTH;
|
||||
|
||||
var font_size = 14;
|
||||
var title_width = compute_text_size( this.title );
|
||||
var input_width = 0;
|
||||
var output_width = 0;
|
||||
|
||||
if(this.inputs)
|
||||
for(var i = 0, l = this.inputs.length; i < l; ++i)
|
||||
{
|
||||
var input = this.inputs[i];
|
||||
var text = input.label || input.name || "";
|
||||
var text_width = compute_text_size( text );
|
||||
if(input_width < text_width)
|
||||
input_width = text_width;
|
||||
}
|
||||
|
||||
if(this.outputs)
|
||||
for(var i = 0, l = this.outputs.length; i < l; ++i)
|
||||
{
|
||||
var output = this.outputs[i];
|
||||
var text = output.label || output.name || "";
|
||||
var text_width = compute_text_size( text );
|
||||
if(output_width < text_width)
|
||||
output_width = text_width;
|
||||
}
|
||||
|
||||
size[0] = Math.max( input_width + output_width + 10, title_width );
|
||||
size[0] = Math.max( size[0], LiteGraph.NODE_WIDTH );
|
||||
|
||||
function compute_text_size( text )
|
||||
{
|
||||
if(!text)
|
||||
return 0;
|
||||
return font_size * text.length * 0.6;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -1615,21 +1660,54 @@ LGraphNode.prototype.getBounding = function()
|
||||
* @param {number} y
|
||||
* @return {boolean}
|
||||
*/
|
||||
LGraphNode.prototype.isPointInsideNode = function(x,y)
|
||||
LGraphNode.prototype.isPointInsideNode = function(x,y, margin)
|
||||
{
|
||||
margin = margin || 0;
|
||||
|
||||
var margin_top = this.graph && this.graph.isLive() ? 0 : 20;
|
||||
if(this.flags.collapsed)
|
||||
{
|
||||
//if ( distance([x,y], [this.pos[0] + this.size[0]*0.5, this.pos[1] + this.size[1]*0.5]) < LiteGraph.NODE_COLLAPSED_RADIUS)
|
||||
if( isInsideRectangle(x,y, this.pos[0], this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_COLLAPSED_WIDTH, LiteGraph.NODE_TITLE_HEIGHT) )
|
||||
if( isInsideRectangle( x, y, this.pos[0] - margin, this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT - margin, LiteGraph.NODE_COLLAPSED_WIDTH + 2 * margin, LiteGraph.NODE_TITLE_HEIGHT + 2 * margin ) )
|
||||
return true;
|
||||
}
|
||||
else if (this.pos[0] - 4 < x && (this.pos[0] + this.size[0] + 4) > x
|
||||
&& (this.pos[1] - margin_top) < y && (this.pos[1] + this.size[1]) > y)
|
||||
else if ( (this.pos[0] - 4 - margin) < x && (this.pos[0] + this.size[0] + 4 + margin) > x
|
||||
&& (this.pos[1] - margin_top - margin) < y && (this.pos[1] + this.size[1] + margin) > y)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if a point is inside a node slot, and returns info about which slot
|
||||
* @method getSlotInPosition
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @return {Object} if found the object contains { input|output: slot object, slot: number, link_pos: [x,y] }
|
||||
*/
|
||||
LGraphNode.prototype.getSlotInPosition = function( x, y )
|
||||
{
|
||||
//search for inputs
|
||||
if(this.inputs)
|
||||
for(var i = 0, l = this.inputs.length; i < l; ++i)
|
||||
{
|
||||
var input = this.inputs[i];
|
||||
var link_pos = this.getConnectionPos( true,i );
|
||||
if( isInsideRectangle(x, y, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
|
||||
return { input: input, slot: i, link_pos: link_pos, locked: input.locked };
|
||||
}
|
||||
|
||||
if(this.outputs)
|
||||
for(var i = 0, l = this.outputs.length; i < l; ++i)
|
||||
{
|
||||
var output = this.outputs[i];
|
||||
var link_pos = this.getConnectionPos(false,i);
|
||||
if( isInsideRectangle(x, y, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
|
||||
return { output: output, slot: i, link_pos: link_pos, locked: output.locked };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the input slot with a given name (used for dynamic slots), -1 if not found
|
||||
* @method findInputSlot
|
||||
@@ -1837,28 +1915,33 @@ LGraphNode.prototype.disconnectInput = function(slot)
|
||||
}
|
||||
|
||||
var input = this.inputs[slot];
|
||||
if(!input) return false;
|
||||
if(!input)
|
||||
return false;
|
||||
var link_id = this.inputs[slot].link;
|
||||
this.inputs[slot].link = null;
|
||||
|
||||
//remove other side
|
||||
var link_info = this.graph.links[ link_id ];
|
||||
var node = this.graph.getNodeById( link_info.origin_id );
|
||||
if(!node) return false;
|
||||
|
||||
var output = node.outputs[ link_info.origin_slot ];
|
||||
if(!output || !output.links || output.links.length == 0)
|
||||
return false;
|
||||
|
||||
//check outputs
|
||||
for(var i = 0, l = output.links.length; i < l; i++)
|
||||
if( link_info )
|
||||
{
|
||||
var link_id = output.links[i];
|
||||
var link_info = this.graph.links[ link_id ];
|
||||
if( link_info.target_id == this.id )
|
||||
var node = this.graph.getNodeById( link_info.origin_id );
|
||||
if(!node)
|
||||
return false;
|
||||
|
||||
var output = node.outputs[ link_info.origin_slot ];
|
||||
if(!output || !output.links || output.links.length == 0)
|
||||
return false;
|
||||
|
||||
//check outputs
|
||||
for(var i = 0, l = output.links.length; i < l; i++)
|
||||
{
|
||||
output.links.splice(i,1);
|
||||
break;
|
||||
var link_id = output.links[i];
|
||||
var link_info = this.graph.links[ link_id ];
|
||||
if( link_info.target_id == this.id )
|
||||
{
|
||||
output.links.splice(i,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1874,7 +1957,7 @@ LGraphNode.prototype.disconnectInput = function(slot)
|
||||
* @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot)
|
||||
* @return {[x,y]} the position
|
||||
**/
|
||||
LGraphNode.prototype.getConnectionPos = function(is_input,slot_number)
|
||||
LGraphNode.prototype.getConnectionPos = function(is_input, slot_number)
|
||||
{
|
||||
if(this.flags.collapsed)
|
||||
{
|
||||
@@ -2511,7 +2594,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
|
||||
ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
|
||||
ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
|
||||
|
||||
var n = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes);
|
||||
var n = this.graph.getNodeOnPos( e.canvasX, e.canvasY, this.visible_nodes );
|
||||
var skip_dragging = false;
|
||||
|
||||
if(e.which == 1) //left button mouse
|
||||
@@ -4386,16 +4469,42 @@ LGraphCanvas.prototype.getNodeMenuOptions = function(node)
|
||||
return options;
|
||||
}
|
||||
|
||||
LGraphCanvas.prototype.processContextualMenu = function(node,event)
|
||||
LGraphCanvas.prototype.processContextualMenu = function(node, event)
|
||||
{
|
||||
var that = this;
|
||||
var win = this.getCanvasWindow();
|
||||
|
||||
var menu = LiteGraph.createContextualMenu(node ? this.getNodeMenuOptions(node) : this.getCanvasMenuOptions(), {event: event, callback: inner_option_clicked}, win);
|
||||
var menu_info = null;
|
||||
|
||||
//check if mouse is in input
|
||||
var slot = null;
|
||||
if(node)
|
||||
slot = node.getSlotInPosition( event.canvasX, event.canvasY );
|
||||
|
||||
if(slot)
|
||||
menu_info = slot.locked ? [ "Cannot remove" ] : { "Remove Slot": slot };
|
||||
else
|
||||
menu_info = node ? this.getNodeMenuOptions(node) : this.getCanvasMenuOptions();
|
||||
|
||||
//show menu
|
||||
if(!menu_info)
|
||||
return;
|
||||
|
||||
var menu = LiteGraph.createContextualMenu( menu_info, {event: event, callback: inner_option_clicked}, win);
|
||||
|
||||
function inner_option_clicked(v,e)
|
||||
{
|
||||
if(!v) return;
|
||||
if(!v)
|
||||
return;
|
||||
|
||||
if(v == slot)
|
||||
{
|
||||
if(v.input)
|
||||
node.removeInput( slot.slot );
|
||||
else if(v.output)
|
||||
node.removeOutput( slot.slot );
|
||||
return;
|
||||
}
|
||||
|
||||
if(v.callback)
|
||||
return v.callback(node, e, menu, that, event );
|
||||
|
||||
0
src/nodes/base.js
Normal file → Executable file
0
src/nodes/base.js
Normal file → Executable file
0
src/nodes/glfx.js
Normal file → Executable file
0
src/nodes/glfx.js
Normal file → Executable file
48
src/nodes/gltextures.js
Normal file → Executable file
48
src/nodes/gltextures.js
Normal file → Executable file
@@ -383,6 +383,9 @@ if(typeof(LiteGraph) != "undefined")
|
||||
{
|
||||
var tex = this.getInputData(0);
|
||||
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
if(this.properties.precision === LGraphTexture.PASS_THROUGH)
|
||||
{
|
||||
this.setOutputData(0, tex);
|
||||
@@ -523,12 +526,15 @@ if(typeof(LiteGraph) != "undefined")
|
||||
LGraphTextureShader.title = "Shader";
|
||||
LGraphTextureShader.desc = "Texture shader";
|
||||
LGraphTextureShader.widgets_info = {
|
||||
"code": { widget:"code" },
|
||||
"code": { type:"code" },
|
||||
"precision": { widget:"combo", values: LGraphTexture.MODE_VALUES }
|
||||
};
|
||||
|
||||
LGraphTextureShader.prototype.onExecute = function()
|
||||
{
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
//replug
|
||||
if(this._shader_code != this.properties.code)
|
||||
{
|
||||
@@ -724,6 +730,9 @@ if(typeof(LiteGraph) != "undefined")
|
||||
if(!tex && !this._temp_texture)
|
||||
return;
|
||||
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
//copy the texture
|
||||
if(tex)
|
||||
{
|
||||
@@ -782,7 +791,11 @@ if(typeof(LiteGraph) != "undefined")
|
||||
LGraphTextureAverage.prototype.onExecute = function()
|
||||
{
|
||||
var tex = this.getInputData(0);
|
||||
if(!tex) return;
|
||||
if(!tex)
|
||||
return;
|
||||
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
if(!LGraphTextureAverage._shader)
|
||||
{
|
||||
@@ -842,7 +855,8 @@ if(typeof(LiteGraph) != "undefined")
|
||||
LGraphImageToTexture.prototype.onExecute = function()
|
||||
{
|
||||
var img = this.getInputData(0);
|
||||
if(!img) return;
|
||||
if(!img)
|
||||
return;
|
||||
|
||||
var width = img.videoWidth || img.width;
|
||||
var height = img.videoHeight || img.height;
|
||||
@@ -898,6 +912,9 @@ if(typeof(LiteGraph) != "undefined")
|
||||
|
||||
LGraphTextureLUT.prototype.onExecute = function()
|
||||
{
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
var tex = this.getInputData(0);
|
||||
|
||||
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
|
||||
@@ -1229,6 +1246,9 @@ if(typeof(LiteGraph) != "undefined")
|
||||
LGraphTextureMix.prototype.onExecute = function()
|
||||
{
|
||||
var texA = this.getInputData(0);
|
||||
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
|
||||
{
|
||||
@@ -1278,7 +1298,7 @@ if(typeof(LiteGraph) != "undefined")
|
||||
this.addInput("Tex.","Texture");
|
||||
|
||||
this.addOutput("Edges","Texture");
|
||||
this.properties = { invert: true, precision: LGraphTexture.DEFAULT };
|
||||
this.properties = { invert: true, factor: 1, precision: LGraphTexture.DEFAULT };
|
||||
|
||||
if(!LGraphTextureEdges._shader)
|
||||
LGraphTextureEdges._shader = new GL.Shader( Shader.SCREEN_VERTEX_SHADER, LGraphTextureEdges.pixel_shader );
|
||||
@@ -1293,6 +1313,9 @@ if(typeof(LiteGraph) != "undefined")
|
||||
|
||||
LGraphTextureEdges.prototype.onExecute = function()
|
||||
{
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
var tex = this.getInputData(0);
|
||||
|
||||
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
|
||||
@@ -1311,10 +1334,11 @@ if(typeof(LiteGraph) != "undefined")
|
||||
var mesh = Mesh.getScreenQuad();
|
||||
var shader = LGraphTextureEdges._shader;
|
||||
var invert = this.properties.invert;
|
||||
var factor = this.properties.factor;
|
||||
|
||||
this._tex.drawTo( function() {
|
||||
tex.bind(0);
|
||||
shader.uniforms({u_texture:0, u_isize:[1/tex.width,1/tex.height], u_invert: invert ? 1 : 0}).draw(mesh);
|
||||
shader.uniforms({u_texture:0, u_isize:[1/tex.width,1/tex.height], u_factor: factor, u_invert: invert ? 1 : 0}).draw(mesh);
|
||||
});
|
||||
|
||||
this.setOutputData(0, this._tex);
|
||||
@@ -1326,6 +1350,7 @@ if(typeof(LiteGraph) != "undefined")
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform vec2 u_isize;\n\
|
||||
uniform int u_invert;\n\
|
||||
uniform float u_factor;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec4 center = texture2D(u_texture, v_coord);\n\
|
||||
@@ -1334,6 +1359,7 @@ if(typeof(LiteGraph) != "undefined")
|
||||
vec4 left = texture2D(u_texture, v_coord + u_isize * vec2(1.0,0.0) );\n\
|
||||
vec4 right = texture2D(u_texture, v_coord + u_isize * vec2(-1.0,0.0) );\n\
|
||||
vec4 diff = abs(center - up) + abs(center - down) + abs(center - left) + abs(center - right);\n\
|
||||
diff *= u_factor;\n\
|
||||
if(u_invert == 1)\n\
|
||||
diff.xyz = vec3(1.0) - diff.xyz;\n\
|
||||
gl_FragColor = vec4( diff.xyz, center.a );\n\
|
||||
@@ -1360,6 +1386,9 @@ if(typeof(LiteGraph) != "undefined")
|
||||
|
||||
LGraphTextureDepthRange.prototype.onExecute = function()
|
||||
{
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
var tex = this.getInputData(0);
|
||||
if(!tex) return;
|
||||
|
||||
@@ -1451,7 +1480,11 @@ if(typeof(LiteGraph) != "undefined")
|
||||
LGraphTextureBlur.prototype.onExecute = function()
|
||||
{
|
||||
var tex = this.getInputData(0);
|
||||
if(!tex) return;
|
||||
if(!tex)
|
||||
return;
|
||||
|
||||
if(!this.isOutputConnected(0))
|
||||
return; //saves work
|
||||
|
||||
var temp = this._temp_texture;
|
||||
|
||||
@@ -1638,7 +1671,8 @@ if(typeof(LiteGraph) != "undefined")
|
||||
if(this._webcam_stream == null && !this._waiting_confirmation)
|
||||
this.openStream();
|
||||
|
||||
if(!this._video || !this._video.videoWidth) return;
|
||||
if(!this._video || !this._video.videoWidth)
|
||||
return;
|
||||
|
||||
var width = this._video.videoWidth;
|
||||
var height = this._video.videoHeight;
|
||||
|
||||
0
src/nodes/image.js
Normal file → Executable file
0
src/nodes/image.js
Normal file → Executable file
0
src/nodes/input.js
Normal file → Executable file
0
src/nodes/input.js
Normal file → Executable file
0
src/nodes/interface.js
Normal file → Executable file
0
src/nodes/interface.js
Normal file → Executable file
0
src/nodes/logic.js
Normal file → Executable file
0
src/nodes/logic.js
Normal file → Executable file
31
src/nodes/math.js
Normal file → Executable file
31
src/nodes/math.js
Normal file → Executable file
@@ -141,6 +141,37 @@ MathFrac.prototype.onExecute = function()
|
||||
LiteGraph.registerNodeType("math/frac",MathFrac);
|
||||
|
||||
|
||||
//Math Floor
|
||||
function MathSmoothStep()
|
||||
{
|
||||
this.addInput("in","number");
|
||||
this.addOutput("out","number");
|
||||
this.size = [60,20];
|
||||
this.properties = { A: 0, B: 1 };
|
||||
}
|
||||
|
||||
MathSmoothStep.title = "Smoothstep";
|
||||
MathSmoothStep.desc = "Smoothstep";
|
||||
|
||||
MathSmoothStep.prototype.onExecute = function()
|
||||
{
|
||||
var v = this.getInputData(0);
|
||||
if(v === undefined)
|
||||
return;
|
||||
|
||||
var edge0 = this.properties.A;
|
||||
var edge1 = this.properties.B;
|
||||
|
||||
// Scale, bias and saturate x to 0..1 range
|
||||
v = Math.clamp((v - edge0)/(edge1 - edge0), 0.0, 1.0);
|
||||
// Evaluate polynomial
|
||||
v = v*v*(3 - 2*v);
|
||||
|
||||
this.setOutputData(0, v );
|
||||
}
|
||||
|
||||
LiteGraph.registerNodeType("math/smoothstep", MathSmoothStep );
|
||||
|
||||
//Math scale
|
||||
function MathScale()
|
||||
{
|
||||
|
||||
0
src/nodes/others.js
Normal file → Executable file
0
src/nodes/others.js
Normal file → Executable file
Reference in New Issue
Block a user