diff --git a/build/litegraph.js b/build/litegraph.js index 714e7d2e0..e26094570 100644 --- a/build/litegraph.js +++ b/build/litegraph.js @@ -1446,6 +1446,12 @@ LGraphNode.prototype.isPointInsideNode = function(x,y) return false; } +/** +* returns the input slot with a given name (used for dynamic slots), -1 if not found +* @method findInputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findInputSlot = function(name) { if(!this.inputs) return -1; @@ -1455,6 +1461,12 @@ LGraphNode.prototype.findInputSlot = function(name) return -1; } +/** +* returns the output slot with a given name (used for dynamic slots), -1 if not found +* @method findOutputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findOutputSlot = function(name) { if(!this.outputs) return -1; @@ -1871,8 +1883,8 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas) * * @class LGraphCanvas * @constructor -* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format) -* @param {LGraph} graph +* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format or the canvas itself) +* @param {LGraph} graph [optional] */ function LGraphCanvas(canvas, graph) { @@ -1897,6 +1909,12 @@ function LGraphCanvas(canvas, graph) LGraphCanvas.link_type_colors = {'number':"#AAC",'node':"#DCA"}; + +/** +* clears all the data inside +* +* @method clear +*/ LGraphCanvas.prototype.clear = function() { this.frame = 0; @@ -1946,6 +1964,12 @@ LGraphCanvas.prototype.clear = function() //this.UIinit(); } +/** +* assigns a graph, you can reasign graphs to the same canvas +* +* @method setGraph +* @param {LGraph} assigns a graph +*/ LGraphCanvas.prototype.setGraph = function(graph) { if(this.graph == graph) return; @@ -1968,6 +1992,12 @@ LGraphCanvas.prototype.setGraph = function(graph) this.setDirty(true,true); } +/** +* assigns a canvas +* +* @method setCanvas +* @param {Canvas} assigns a canvas +*/ LGraphCanvas.prototype.setCanvas = function(canvas) { var that = this; @@ -2006,7 +2036,7 @@ LGraphCanvas.prototype.setCanvas = function(canvas) this._mousemove_callback = this.processMouseMove.bind(this); this._mouseup_callback = this.processMouseUp.bind(this); - this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this) ); //down do not need to store the binded + this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded this.canvas.addEventListener("mousemove", this._mousemove_callback); this.canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; }); @@ -2084,6 +2114,14 @@ LGraphCanvas.prototype.UIinit = function() } */ +/** +* marks as dirty the canvas, this way it will be rendered again +* +* @class LGraphCanvas +* @method setDirty +* @param {bool} fgcanvas if the foreground canvas is dirty (the one containing the nodes) +* @param {bool} bgcanvas if the background canvas is dirty (the one containing the wires) +*/ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) { if(fgcanvas) @@ -2092,13 +2130,23 @@ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) this.dirty_bgcanvas = true; } -//Used to attach the canvas in a popup +/** +* Used to attach the canvas in a popup +* +* @method getCanvasWindow +* @return {window} returns the window where the canvas is attached (the DOM root node) +*/ LGraphCanvas.prototype.getCanvasWindow = function() { var doc = this.canvas.ownerDocument; return doc.defaultView || doc.parentWindow; } +/** +* starts rendering the content of the canvas when needed +* +* @method startRendering +*/ LGraphCanvas.prototype.startRendering = function() { if(this.is_rendering) return; //already rendering @@ -2125,6 +2173,11 @@ LGraphCanvas.prototype.startRendering = function() */ } +/** +* stops rendering the content of the canvas (to save resources) +* +* @method stopRendering +*/ LGraphCanvas.prototype.stopRendering = function() { this.is_rendering = false; @@ -2149,8 +2202,8 @@ LGraphCanvas.prototype.processMouseDown = function(e) var document = ref_window.document; this.canvas.removeEventListener("mousemove", this._mousemove_callback ); - ref_window.document.addEventListener("mousemove", this._mousemove_callback ); //catch for the entire window - ref_window.document.addEventListener("mouseup", this._mouseup_callback ); + 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 skip_dragging = false; @@ -5429,7 +5482,6 @@ function MathOperation() this.addInput("A","number"); this.addInput("B","number"); this.addOutput("A+B","number"); - this.size = [80,20]; this.properties = {A:1.0, B:1.0}; } @@ -5535,12 +5587,34 @@ MathCompare.prototype.onGetOutputs = function() LiteGraph.registerNodeType("math/compare",MathCompare); +function MathAccumulate() +{ + this.addInput("inc","number"); + this.addOutput("total","number"); + this.properties = { increment: 0, value: 0 }; +} + +MathAccumulate.title = "Accumulate"; +MathAccumulate.desc = "Increments a value every time"; + +MathAccumulate.prototype.onExecute = function() +{ + var inc = this.getInputData(0); + if(inc !== null) + this.properties.value += inc; + else + this.properties.value += this.properties.increment; + this.setOutputData(0, this.properties.value ); +} + +LiteGraph.registerNodeType("math/accumulate", MathAccumulate); + //Math Trigonometry function MathTrigonometry() { this.addInput("v","number"); this.addOutput("sin","number"); - this.properties = {amplitude:1.0}; + this.properties = {amplitude:1.0, offset: 0}; this.bgImageUrl = "nodes/imgs/icon-sin.png"; } @@ -5550,7 +5624,15 @@ MathTrigonometry.desc = "Sin Cos Tan"; MathTrigonometry.prototype.onExecute = function() { var v = this.getInputData(0); - var amp = this.properties["amplitude"]; + var amplitude = this.properties["amplitude"]; + var slot = this.findInputSlot("amplitude"); + if(slot != -1) + amplitude = this.getInputData(slot); + var offset = this.properties["offset"]; + slot = this.findInputSlot("offset"); + if(slot != -1) + offset = this.getInputData(slot); + for(var i = 0, l = this.outputs.length; i < l; ++i) { var output = this.outputs[i]; @@ -5563,10 +5645,16 @@ MathTrigonometry.prototype.onExecute = function() case "acos": value = Math.acos(v); break; case "atan": value = Math.atan(v); break; } - this.setOutputData(i, amp * value ); + this.setOutputData(i, amplitude * value + offset); } } +MathTrigonometry.prototype.onGetInputs = function() +{ + return [["v","number"],["amplitude","number"],["offset","number"]]; +} + + MathTrigonometry.prototype.onGetOutputs = function() { return [["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos","number"],["atan","number"]]; @@ -5656,6 +5744,7 @@ if(window.glMatrix) { this.addInputs([["x","number"],["y","number"],["z","number"]]); this.addOutput("vec3","vec3"); + this.properties = {x:0, y:0, z:0}; } Math3DXYZToVec3.title = "XYZ->Vec3"; @@ -5664,11 +5753,11 @@ if(window.glMatrix) Math3DXYZToVec3.prototype.onExecute = function() { var x = this.getInputData(0); - if(x == null) x = 0; + if(x == null) x = this.properties.x; var y = this.getInputData(1); - if(y == null) y = 0; + if(y == null) y = this.properties.y; var z = this.getInputData(2); - if(z == null) z = 0; + if(z == null) z = this.properties.z; this.setOutputData( 0, vec3.fromValues(x,y,z) ); } diff --git a/build/litegraph.min.js b/build/litegraph.min.js index ac9f88f3e..a35839456 100644 --- a/build/litegraph.min.js +++ b/build/litegraph.min.js @@ -10,8 +10,8 @@ LGraph.prototype.start=function(a){if(this.status!=LGraph.STATUS_RUNNING){this.s LGraph.prototype.stop=function(){if(this.status!=LGraph.STATUS_STOPPED){this.status=LGraph.STATUS_STOPPED;if(this.onStopEvent)this.onStopEvent();null!=this.execution_timer_id&&clearInterval(this.execution_timer_id);this.execution_timer_id=null;this.sendEventToAllNodes("onStop")}}; LGraph.prototype.runStep=function(a){a=a||1;var b=LiteGraph.getTime();this.globaltime=0.001*(b-this.starttime);try{for(var c=0;c=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(null==a.id||-1==a.id)a.id=this.last_node_id++;a.graph=this;this._nodes.push(a);this._nodes_by_id[a.id]=a;if(a.onAdded)a.onAdded();this.config.align_to_grid&&a.alignToGrid();b||this.updateExecutionOrder();if(this.onNodeAdded)this.onNodeAdded(a);this.setDirtyCanvas(!0);this.change();return a}}; LGraph.prototype.remove=function(a){if(null!=this._nodes_by_id[a.id]&&!a.ignore_remove){if(a.inputs)for(var b=0;bLiteGraph.getTime()-this.last_mouseclick&&this.selected_nodes[c.id]){if(c.onDblClick)c.onDblClick(a);this.processNodeDblClicked(c);e=!0}c.onMouseDown&&c.onMouseDown(a)? e=!0:this.live_mode&&(e=d=!0);e||(this.allow_dragnodes&&(this.node_dragged=c),this.selected_nodes[c.id]||this.processNodeSelected(c,a));this.dirty_canvas=!0}}else d=!0;d&&this.allow_dragcanvas&&(this.dragging_canvas=!0)}else 2!=a.which&&3==a.which&&this.processContextualMenu(c,a);this.last_mouse[0]=a.localX;this.last_mouse[1]=a.localY;this.last_mouseclick=LiteGraph.getTime();this.canvas_mouse=[a.canvasX,a.canvasY];this.graph.change();(!b.document.activeElement||"input"!=b.document.activeElement.nodeName.toLowerCase()&& @@ -105,8 +105,8 @@ c[1]),a.stroke()};LGraphCanvas.prototype.computeConnectionPoint=function(a,b,c){ LGraphCanvas.prototype.resize=function(a,b){if(!a&&!b){var c=this.canvas.parentNode;a=c.offsetWidth;b=c.offsetHeight}if(this.canvas.width!=a||this.canvas.height!=b)this.canvas.width=a,this.canvas.height=b,this.bgcanvas.width=this.canvas.width,this.bgcanvas.height=this.canvas.height,this.setDirty(!0,!0)}; LGraphCanvas.prototype.switchLiveMode=function(a){if(a){var b=this,c=this.live_mode?1.1:0.9;this.live_mode&&(this.live_mode=!1,this.editor_alpha=0.1);var d=setInterval(function(){b.editor_alpha*=c;b.dirty_canvas=!0;b.dirty_bgcanvas=!0;1>c&&0.01>b.editor_alpha&&(clearInterval(d),1>c&&(b.live_mode=!0));1"+e+""})}LiteGraph.createContextualMenu(d,{event:b,callback:function(b){a&&(b=LGraphCanvas.node_colors[b.value])&&(a.color=b.color,a.bgcolor=b.bgcolor,a.setDirtyCanvas(!0))},from:c});return!1}; @@ -147,20 +147,21 @@ function(a,b){this.properties[a]=b;this.str="number"==typeof b?b.toFixed(3):b;re this.properties.bgcolorBottom))};e.prototype.onDrawForeground=function(a){null==this.lineargradient&&this.createGradient(a);this.lineargradient&&(a.lineWidth=1,a.strokeStyle=this.properties.borderColor,a.fillStyle=this.lineargradient,this.properties.shadowSize?(a.shadowColor="#000",a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=this.properties.shadowSize):a.shadowColor="transparent",a.roundRect(0,0,this.size[0]-1,this.size[1]-1,this.properties.shadowSize),a.fill(),a.shadowColor="transparent",a.stroke())}; e.prototype.onWidget=function(a,b){"update"==b.name&&(this.lineargradient=null,this.setDirtyCanvas(!0))};LiteGraph.registerNodeType("widget/panel",e)})(); (function(){function a(){this.addOutput("value","number");this.properties={min:0,max:1};this.size=[60,20]}function b(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20];this.properties={min:0,max:1}}function c(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function d(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function e(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function f(){this.addInput("in", -"number",{label:""});this.addOutput("out","number",{label:""});this.size=[60,20];this.properties={factor:1}}function g(){this.addInput("A","number");this.addInput("B","number");this.addOutput("A+B","number");this.size=[80,20];this.properties={A:1,B:1}}function h(){this.addInputs("A","number");this.addInputs("B","number");this.addOutputs("A==B","number");this.addOutputs("A!=B","number");this.properties={A:0,B:0}}function l(){this.addInput("v","number");this.addOutput("sin","number");this.properties= -{amplitude:1};this.bgImageUrl="nodes/imgs/icon-sin.png"}a.title="Rand";a.desc="Random number";a.prototype.onExecute=function(){var a=this.properties.min,b=this.properties.max;this._last_v=Math.random()*(b-a)+a;this.setOutputData(0,this._last_v)};a.prototype.onDrawBackground=function(a){this.outputs[0].label=this._last_v?this._last_v.toFixed(3):"?"};LiteGraph.registerNodeType("math/rand",a);b.title="Clamp";b.desc="Clamp number between min and max";b.prototype.onExecute=function(){var a=this.getInputData(0); -null!=a&&(a=Math.max(this.properties.min,a),a=Math.min(this.properties.max,a),this.setOutputData(0,a))};LiteGraph.registerNodeType("math/clamp",b);c.title="Abs";c.desc="Absolute";c.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,Math.abs(a))};LiteGraph.registerNodeType("math/abs",c);d.title="Floor";d.desc="Floor number to remove fractional part";d.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a|1)};LiteGraph.registerNodeType("math/floor", -d);e.title="Frac";e.desc="Returns fractional part";e.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a%1)};LiteGraph.registerNodeType("math/frac",e);f.title="Scale";f.desc="v * factor";f.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a*this.properties.factor)};LiteGraph.registerNodeType("math/scale",f);g.title="Operation";g.desc="Easy math operators";g.prototype.setValue=function(a){"string"==typeof a&&(a=parseFloat(a)); -this.properties.value=a;this.setDirtyCanvas(!0)};g.prototype.onExecute=function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.A=a:a=this.properties.A;null!=b?this.properties.B=b:b=this.properties.B;for(var c=0,d=this.outputs.length;cB":value= -a>b;break;case "A=B":value=a>=b}this.setOutputData(c,value)}}};h.prototype.onGetOutputs=function(){return[["A==B","number"],["A!=B","number"],["A>B","number"],["A=B","number"],["A<=B","number"]]};LiteGraph.registerNodeType("math/compare",h);l.title="Trigonometry";l.desc="Sin Cos Tan";l.prototype.onExecute=function(){for(var a=this.getInputData(0),b=this.properties.amplitude,c=0,d=this.outputs.length;cXYZ",k.desc="vector 3 to components",k.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&(this.setOutputData(0,a[0]),this.setOutputData(1,a[1]),this.setOutputData(2,a[2]))},LiteGraph.registerNodeType("math3d/vec3-to-xyz", -k),k=function(){this.addInputs([["x","number"],["y","number"],["z","number"]]);this.addOutput("vec3","vec3")},k.title="XYZ->Vec3",k.desc="components to vector3",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=0);var b=this.getInputData(1);null==b&&(b=0);var c=this.getInputData(2);null==c&&(c=0);this.setOutputData(0,vec3.fromValues(a,b,c))},LiteGraph.registerNodeType("math3d/xyz-to-vec3",k),k=function(){this.addInputs([["degrees","number"],["axis","vec3"]]);this.addOutput("quat", -"quat");this.properties={angle:90,axis:vec3.fromValues(0,1,0)}},k.title="Rotation",k.desc="quaternion rotation",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.angle);var b=this.getInputData(1);null==b&&(b=this.properties.axis);a=quat.setAxisAngle(quat.create(),b,0.0174532925*a);this.setOutputData(0,a)},LiteGraph.registerNodeType("math3d/rotation",k),k=function(){this.addInputs([["vec3","vec3"],["quat","quat"]]);this.addOutput("result","vec3");this.properties= -{vec:[0,0,1]}},k.title="Rot. Vec3",k.desc="rotate a point",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.vec);var b=this.getInputData(1);null==b?this.setOutputData(a):this.setOutputData(0,vec3.transformQuat(vec3.create(),a,b))},LiteGraph.registerNodeType("math3d/rotate_vec3",k),k=function(){this.addInputs([["A","quat"],["B","quat"]]);this.addOutput("A*B","quat")},k.title="Mult. Quat",k.desc="rotate quaternion",k.prototype.onExecute=function(){var a=this.getInputData(0); -if(null!=a){var b=this.getInputData(1);null!=b&&(a=quat.multiply(quat.create(),a,b),this.setOutputData(0,a))}},LiteGraph.registerNodeType("math3d/mult-quat",k))})(); +"number",{label:""});this.addOutput("out","number",{label:""});this.size=[60,20];this.properties={factor:1}}function g(){this.addInput("A","number");this.addInput("B","number");this.addOutput("A+B","number");this.properties={A:1,B:1}}function h(){this.addInputs("A","number");this.addInputs("B","number");this.addOutputs("A==B","number");this.addOutputs("A!=B","number");this.properties={A:0,B:0}}function l(){this.addInput("inc","number");this.addOutput("total","number");this.properties={increment:0, +value:0}}function n(){this.addInput("v","number");this.addOutput("sin","number");this.properties={amplitude:1,offset:0};this.bgImageUrl="nodes/imgs/icon-sin.png"}a.title="Rand";a.desc="Random number";a.prototype.onExecute=function(){var a=this.properties.min,b=this.properties.max;this._last_v=Math.random()*(b-a)+a;this.setOutputData(0,this._last_v)};a.prototype.onDrawBackground=function(a){this.outputs[0].label=this._last_v?this._last_v.toFixed(3):"?"};LiteGraph.registerNodeType("math/rand",a);b.title= +"Clamp";b.desc="Clamp number between min and max";b.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&(a=Math.max(this.properties.min,a),a=Math.min(this.properties.max,a),this.setOutputData(0,a))};LiteGraph.registerNodeType("math/clamp",b);c.title="Abs";c.desc="Absolute";c.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,Math.abs(a))};LiteGraph.registerNodeType("math/abs",c);d.title="Floor";d.desc="Floor number to remove fractional part";d.prototype.onExecute= +function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a|1)};LiteGraph.registerNodeType("math/floor",d);e.title="Frac";e.desc="Returns fractional part";e.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a%1)};LiteGraph.registerNodeType("math/frac",e);f.title="Scale";f.desc="v * factor";f.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&this.setOutputData(0,a*this.properties.factor)};LiteGraph.registerNodeType("math/scale",f);g.title= +"Operation";g.desc="Easy math operators";g.prototype.setValue=function(a){"string"==typeof a&&(a=parseFloat(a));this.properties.value=a;this.setDirtyCanvas(!0)};g.prototype.onExecute=function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.A=a:a=this.properties.A;null!=b?this.properties.B=b:b=this.properties.B;for(var c=0,d=this.outputs.length;cB":value=a>b;break;case "A=B":value=a>=b}this.setOutputData(c,value)}}};h.prototype.onGetOutputs=function(){return[["A==B","number"],["A!=B","number"],["A>B","number"],["A=B","number"],["A<=B","number"]]};LiteGraph.registerNodeType("math/compare",h);l.title="Accumulate";l.desc="Increments a value every time";l.prototype.onExecute= +function(){var a=this.getInputData(0);this.properties.value=null!==a?this.properties.value+a:this.properties.value+this.properties.increment;this.setOutputData(0,this.properties.value)};LiteGraph.registerNodeType("math/accumulate",l);n.title="Trigonometry";n.desc="Sin Cos Tan";n.prototype.onExecute=function(){var a=this.getInputData(0),b=this.properties.amplitude,c=this.findInputSlot("amplitude");-1!=c&&(b=this.getInputData(c));var d=this.properties.offset,c=this.findInputSlot("offset");-1!=c&&(d= +this.getInputData(c));for(var c=0,e=this.outputs.length;cXYZ", +k.desc="vector 3 to components",k.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&(this.setOutputData(0,a[0]),this.setOutputData(1,a[1]),this.setOutputData(2,a[2]))},LiteGraph.registerNodeType("math3d/vec3-to-xyz",k),k=function(){this.addInputs([["x","number"],["y","number"],["z","number"]]);this.addOutput("vec3","vec3");this.properties={x:0,y:0,z:0}},k.title="XYZ->Vec3",k.desc="components to vector3",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.x); +var b=this.getInputData(1);null==b&&(b=this.properties.y);var c=this.getInputData(2);null==c&&(c=this.properties.z);this.setOutputData(0,vec3.fromValues(a,b,c))},LiteGraph.registerNodeType("math3d/xyz-to-vec3",k),k=function(){this.addInputs([["degrees","number"],["axis","vec3"]]);this.addOutput("quat","quat");this.properties={angle:90,axis:vec3.fromValues(0,1,0)}},k.title="Rotation",k.desc="quaternion rotation",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.angle); +var b=this.getInputData(1);null==b&&(b=this.properties.axis);a=quat.setAxisAngle(quat.create(),b,0.0174532925*a);this.setOutputData(0,a)},LiteGraph.registerNodeType("math3d/rotation",k),k=function(){this.addInputs([["vec3","vec3"],["quat","quat"]]);this.addOutput("result","vec3");this.properties={vec:[0,0,1]}},k.title="Rot. Vec3",k.desc="rotate a point",k.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.vec);var b=this.getInputData(1);null==b?this.setOutputData(a): +this.setOutputData(0,vec3.transformQuat(vec3.create(),a,b))},LiteGraph.registerNodeType("math3d/rotate_vec3",k),k=function(){this.addInputs([["A","quat"],["B","quat"]]);this.addOutput("A*B","quat")},k.title="Mult. Quat",k.desc="rotate quaternion",k.prototype.onExecute=function(){var a=this.getInputData(0);if(null!=a){var b=this.getInputData(1);null!=b&&(a=quat.multiply(quat.create(),a,b),this.setOutputData(0,a))}},LiteGraph.registerNodeType("math3d/mult-quat",k))})(); (function(){function a(){this.addInput("f","number");this.addOutput("Color","color");this.properties={colorA:"#444444",colorB:"#44AAFF",colorC:"#44FFAA",colorD:"#FFFFFF"}}function b(){this.addInput("","image");this.size=[200,200]}function c(){this.addInputs([["img1","image"],["img2","image"],["fade","number"]]);this.addInput("","image");this.properties={fade:0.5,width:512,height:512}}function d(){this.inputs=[];this.addOutput("frame","image");this.properties={url:""}}function e(){this.addInput("", "image");this.addOutputs("","image");this.properties={width:256,height:256,x:0,y:0,scale:1};this.size=[50,20]}function f(){this.addInput("t","number");this.addOutputs([["frame","image"],["t","number"],["d","number"]]);this.properties={url:""}}function g(){this.addOutput("Webcam","image");this.properties={}}a.title="Palette";a.desc="Generates a color";a.prototype.onExecute=function(){var a=[];null!=this.properties.colorA&&a.push(hex2num(this.properties.colorA));null!=this.properties.colorB&&a.push(hex2num(this.properties.colorB)); null!=this.properties.colorC&&a.push(hex2num(this.properties.colorC));null!=this.properties.colorD&&a.push(hex2num(this.properties.colorD));var b=this.getInputData(0);null==b&&(b=0.5);1b&&(b=0);if(0!=a.length){var c=[0,0,0];if(0==b)c=a[0];else if(1==b)c=a[a.length-1];else{var d=(a.length-1)*b,b=a[Math.floor(d)],a=a[Math.floor(d)+1],d=d-Math.floor(d);c[0]=b[0]*(1-d)+a[0]*d;c[1]=b[1]*(1-d)+a[1]*d;c[2]=b[2]*(1-d)+a[2]*d}for(var e in c)c[e]/=255;this.boxcolor=colorToString(c);this.setOutputData(0, diff --git a/doc/classes/LGraph.html b/doc/classes/LGraph.html index 561b624fb..67608031b 100644 --- a/doc/classes/LGraph.html +++ b/doc/classes/LGraph.html @@ -96,7 +96,7 @@
- Defined in: ../src/litegraph.js:299 + Defined in: ../src/litegraph.js:227
@@ -147,7 +147,7 @@ - ../src/litegraph.js:299 + ../src/litegraph.js:227

@@ -405,7 +405,7 @@ - ../src/litegraph.js:645 + ../src/litegraph.js:582

@@ -494,7 +494,7 @@ - ../src/litegraph.js:361 + ../src/litegraph.js:296

@@ -572,7 +572,7 @@ - ../src/litegraph.js:317 + ../src/litegraph.js:251

@@ -637,7 +637,7 @@ - ../src/litegraph.js:920 + ../src/litegraph.js:922

@@ -726,7 +726,7 @@ - ../src/litegraph.js:380 + ../src/litegraph.js:315

@@ -818,7 +818,7 @@ - ../src/litegraph.js:780 + ../src/litegraph.js:726

@@ -925,7 +925,7 @@ - ../src/litegraph.js:764 + ../src/litegraph.js:710

@@ -1022,7 +1022,7 @@ - ../src/litegraph.js:605 + ../src/litegraph.js:542

@@ -1096,7 +1096,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:594 + ../src/litegraph.js:531

@@ -1175,7 +1175,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:751 + ../src/litegraph.js:697

@@ -1279,7 +1279,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:796 + ../src/litegraph.js:742

@@ -1408,7 +1408,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:583 + ../src/litegraph.js:520

@@ -1477,7 +1477,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:869 + ../src/litegraph.js:856

@@ -1542,7 +1542,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:690 + ../src/litegraph.js:631

@@ -1631,7 +1631,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:443 + ../src/litegraph.js:378

@@ -1726,7 +1726,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:617 + ../src/litegraph.js:554

@@ -1825,7 +1825,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:893 + ../src/litegraph.js:889

@@ -1910,7 +1910,7 @@ if the nodes are using graphical actions

- ../src/litegraph.js:817 + ../src/litegraph.js:804

@@ -2020,7 +2020,7 @@ can be easily accesed from the outside of the graph

- ../src/litegraph.js:832 + ../src/litegraph.js:819

@@ -2123,7 +2123,7 @@ can be easily accesed from the outside of the graph

- ../src/litegraph.js:394 + ../src/litegraph.js:329

@@ -2202,7 +2202,7 @@ can be easily accesed from the outside of the graph

- ../src/litegraph.js:421 + ../src/litegraph.js:356

@@ -2257,7 +2257,7 @@ can be easily accesed from the outside of the graph

- ../src/litegraph.js:487 + ../src/litegraph.js:422

diff --git a/doc/classes/LGraphCanvas.html b/doc/classes/LGraphCanvas.html index fcb197b6b..2d66a2b02 100644 --- a/doc/classes/LGraphCanvas.html +++ b/doc/classes/LGraphCanvas.html @@ -96,7 +96,7 @@ @@ -108,7 +108,7 @@
-

The Global Scope. It contains all the registered node classes.

+

marks as dirty the canvas, this way it will be rendered again

@@ -163,7 +163,7 @@ - ../src/litegraph.js:1794 + ../src/litegraph.js:2116

@@ -192,7 +192,7 @@
-

the canvas where you want to render (it accepts a selector in string format)

+

the canvas where you want to render (it accepts a selector in string format or the canvas itself)

@@ -208,7 +208,8 @@
- +

[optional]

+
@@ -231,6 +232,8 @@
  • Index
  • +
  • Methods
  • + @@ -241,6 +244,56 @@

    Item Index

    +
    +

    Methods

    + + +
    + @@ -250,6 +303,428 @@ +
    +

    Methods

    + + +
    +

    clear

    + + + () + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1912 + +

    + + + + + +
    + +
    +

    clears all the data inside

    + +
    + + + + + + +
    + + +
    +

    getCanvasWindow

    + + + () + + + + + Window + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:2132 + +

    + + + + + +
    + +
    +

    Used to attach the canvas in a popup

    + +
    + + + + +
    +

    Returns:

    + +
    + + + Window: + +

    returns the window where the canvas is attached (the DOM root node)

    + + +
    +
    + + + +
    + + +
    +

    setCanvas

    + + +
    + (
      + +
    • + + assigns + +
    • + +
    ) +
    + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1994 + +

    + + + + + +
    + +
    +

    assigns a canvas

    + +
    + + +
    +

    Parameters:

    + +
      + +
    • + + assigns + Canvas + + + + +
      +

      a canvas

      + +
      + + +
    • + +
    +
    + + + + + +
    + + +
    +

    setGraph

    + + +
    + (
      + +
    • + + assigns + +
    • + +
    ) +
    + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1966 + +

    + + + + + +
    + +
    +

    assigns a graph, you can reasign graphs to the same canvas

    + +
    + + +
    +

    Parameters:

    + +
      + +
    • + + assigns + LGraph + + + + +
      +

      a graph

      + +
      + + +
    • + +
    +
    + + + + + +
    + + +
    +

    startRendering

    + + + () + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:2144 + +

    + + + + + +
    + +
    +

    starts rendering the content of the canvas when needed

    + +
    + + + + + + +
    + + +
    +

    stopRendering

    + + + () + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:2175 + +

    + + + + + +
    + +
    +

    stops rendering the content of the canvas (to save resources)

    + +
    + + + + + + +
    + + +
    + diff --git a/doc/classes/LGraphNode.html b/doc/classes/LGraphNode.html index 7d966a3da..36fc193be 100644 --- a/doc/classes/LGraphNode.html +++ b/doc/classes/LGraphNode.html @@ -96,7 +96,7 @@ @@ -148,6 +148,13 @@ + + +
  • + addInputs + + +
  • @@ -155,6 +162,13 @@ +
  • + +
  • + addOutputs + + +
  • @@ -197,6 +211,20 @@ +
  • + +
  • + findInputSlot + + + +
  • + +
  • + findOutputSlot + + +
  • @@ -239,6 +267,13 @@ +
  • + +
  • + getTitle + + +
  • @@ -380,7 +415,7 @@ - ../src/litegraph.js:1320 + ../src/litegraph.js:1385

    @@ -528,7 +563,7 @@ - ../src/litegraph.js:1289 + ../src/litegraph.js:1331

    @@ -603,6 +638,95 @@ + + + +
    +

    addInputs

    + + +
    + (
      + +
    • + + array + +
    • + +
    ) +
    + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1350 + +

    + + + + + +
    + +
    +

    add several new input slots in this node

    + +
    + + +
    +

    Parameters:

    + +
      + +
    • + + array + Array + + + + +
      +

      of triplets like [[name,type,extra_info],[...]]

      + +
      + + +
    • + +
    +
    + + + + +
    @@ -660,7 +784,7 @@ - ../src/litegraph.js:1258 + ../src/litegraph.js:1277

    @@ -735,6 +859,95 @@ + + + +
    +

    addOutputs

    + + +
    + (
      + +
    • + + array + +
    • + +
    ) +
    + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1296 + +

    + + + + + +
    + +
    +

    add a new output slot to use in this node

    + +
    + + +
    +

    Parameters:

    + +
      + +
    • + + array + Array + + + + +
      +

      of triplets like [[name,type,extra_info],[...]]

      + +
      + + +
    • + +
    +
    + + + + +
    @@ -770,7 +983,7 @@ - ../src/litegraph.js:1756 + ../src/litegraph.js:1842

    @@ -839,7 +1052,7 @@ - ../src/litegraph.js:1333 + ../src/litegraph.js:1398

    @@ -931,7 +1144,7 @@ - ../src/litegraph.js:1026 + ../src/litegraph.js:1029

    @@ -942,7 +1155,7 @@
    -

    configure a node from an object

    +

    configure a node from an object containing the serialized info

    @@ -1012,7 +1225,7 @@ - ../src/litegraph.js:1401 + ../src/litegraph.js:1478

    @@ -1151,7 +1364,7 @@ - ../src/litegraph.js:1545 + ../src/litegraph.js:1628

    @@ -1264,7 +1477,7 @@ - ../src/litegraph.js:1482 + ../src/litegraph.js:1561

    @@ -1338,6 +1551,220 @@ + + + +
    +

    findInputSlot

    + + +
    + (
      + +
    • + + name + +
    • + +
    ) +
    + + + + + Number + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1448 + +

    + + + + + +
    + +
    +

    returns the input slot with a given name (used for dynamic slots), -1 if not found

    + +
    + + +
    +

    Parameters:

    + +
      + +
    • + + name + String + + + + +
      +

      the name of the slot

      + +
      + + +
    • + +
    +
    + + + +
    +

    Returns:

    + +
    + + + Number: + +

    the slot (-1 if not found)

    + + +
    +
    + + + +
    + + +
    +

    findOutputSlot

    + + +
    + (
      + +
    • + + name + +
    • + +
    ) +
    + + + + + Number + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1463 + +

    + + + + + +
    + +
    +

    returns the output slot with a given name (used for dynamic slots), -1 if not found

    + +
    + + +
    +

    Parameters:

    + +
      + +
    • + + name + String + + + + +
      +

      the name of the slot

      + +
      + + +
    • + +
    +
    + + + +
    +

    Returns:

    + +
    + + + Number: + +

    the slot (-1 if not found)

    + + +
    +
    + + +
    @@ -1377,7 +1804,7 @@ - ../src/litegraph.js:1351 + ../src/litegraph.js:1416

    @@ -1466,7 +1893,7 @@ - ../src/litegraph.js:1599 + ../src/litegraph.js:1685

    @@ -1589,7 +2016,7 @@ - ../src/litegraph.js:1161 + ../src/litegraph.js:1180

    @@ -1695,7 +2122,7 @@ - ../src/litegraph.js:1187 + ../src/litegraph.js:1206

    @@ -1799,7 +2226,7 @@ - ../src/litegraph.js:1202 + ../src/litegraph.js:1221

    @@ -1903,7 +2330,7 @@ - ../src/litegraph.js:1229 + ../src/litegraph.js:1248

    @@ -1958,6 +2385,61 @@ + + + +
    +

    getTitle

    + + + () + + + + + + + + + + + + + + + + +
    + + + +

    + + Defined in + + + + + ../src/litegraph.js:1148 + +

    + + + + + +
    + +
    +

    get the title string

    + +
    + + + + + +
    @@ -2007,7 +2489,7 @@ - ../src/litegraph.js:1175 + ../src/litegraph.js:1194

    @@ -2111,7 +2593,7 @@ - ../src/litegraph.js:1217 + ../src/litegraph.js:1236

    @@ -2221,7 +2703,7 @@ - ../src/litegraph.js:1361 + ../src/litegraph.js:1426

    @@ -2326,7 +2808,7 @@ - ../src/litegraph.js:1769 + ../src/litegraph.js:1855

    @@ -2391,7 +2873,7 @@ - ../src/litegraph.js:1308 + ../src/litegraph.js:1373

    @@ -2479,7 +2961,7 @@ - ../src/litegraph.js:1277 + ../src/litegraph.js:1319

    @@ -2557,7 +3039,7 @@ - ../src/litegraph.js:1073 + ../src/litegraph.js:1075

    @@ -2628,7 +3110,7 @@ - ../src/litegraph.js:1145 + ../src/litegraph.js:1161

    @@ -2721,7 +3203,7 @@ - ../src/litegraph.js:1132 + ../src/litegraph.js:1136

    diff --git a/doc/classes/LiteGraph.html b/doc/classes/LiteGraph.html index e2709b8d7..9cab56904 100644 --- a/doc/classes/LiteGraph.html +++ b/doc/classes/LiteGraph.html @@ -298,7 +298,7 @@ - ../src/litegraph.js:67 + ../src/litegraph.js:65

    @@ -423,7 +423,7 @@ - ../src/litegraph.js:143 + ../src/litegraph.js:105

    @@ -530,7 +530,7 @@ - ../src/litegraph.js:156 + ../src/litegraph.js:118

    @@ -627,7 +627,7 @@ - ../src/litegraph.js:178 + ../src/litegraph.js:140

    @@ -712,7 +712,7 @@ - ../src/litegraph.js:33 + ../src/litegraph.js:34

    diff --git a/doc/data.json b/doc/data.json index ca7f52bba..4e51b636d 100644 --- a/doc/data.json +++ b/doc/data.json @@ -38,7 +38,7 @@ "plugin_for": [], "extension_for": [], "file": "../src/litegraph.js", - "line": 299, + "line": 227, "description": "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.", "is_constructor": 1 }, @@ -51,7 +51,7 @@ "plugin_for": [], "extension_for": [], "file": "../src/litegraph.js", - "line": 997, + "line": 1000, "description": "Base Class for all the node type classes", "params": [ { @@ -70,27 +70,28 @@ "plugin_for": [], "extension_for": [], "file": "../src/litegraph.js", - "line": 1794, - "description": "The Global Scope. It contains all the registered node classes.", + "line": 2116, + "description": "marks as dirty the canvas, this way it will be rendered again", "is_constructor": 1, "params": [ { "name": "canvas", - "description": "the canvas where you want to render (it accepts a selector in string format)", + "description": "the canvas where you want to render (it accepts a selector in string format or the canvas itself)", "type": "HTMLCanvas" }, { "name": "graph", - "description": "", + "description": "[optional]", "type": "LGraph" } - ] + ], + "itemtype": "method" } }, "classitems": [ { "file": "../src/litegraph.js", - "line": 33, + "line": 34, "description": "Register a node class so it can be listed when the user wants to create a new one", "itemtype": "method", "name": "registerNodeType", @@ -110,7 +111,7 @@ }, { "file": "../src/litegraph.js", - "line": 67, + "line": 65, "description": "Create a node of a given type with a name. The node is not attached to any graph yet.", "itemtype": "method", "name": "createNode", @@ -135,7 +136,7 @@ }, { "file": "../src/litegraph.js", - "line": 143, + "line": 105, "description": "Returns a registered node type with a given name", "itemtype": "method", "name": "getNodeType", @@ -154,7 +155,7 @@ }, { "file": "../src/litegraph.js", - "line": 156, + "line": 118, "description": "Returns a list of node types matching one category", "itemtype": "method", "name": "getNodeType", @@ -173,7 +174,7 @@ }, { "file": "../src/litegraph.js", - "line": 178, + "line": 140, "description": "Returns a list with all the node type categories", "itemtype": "method", "name": "getNodeTypesCategories", @@ -185,7 +186,7 @@ }, { "file": "../src/litegraph.js", - "line": 317, + "line": 251, "description": "Removes all nodes from this graph", "itemtype": "method", "name": "clear", @@ -193,7 +194,7 @@ }, { "file": "../src/litegraph.js", - "line": 361, + "line": 296, "description": "Attach Canvas to this graph", "itemtype": "method", "name": "attachCanvas", @@ -208,7 +209,7 @@ }, { "file": "../src/litegraph.js", - "line": 380, + "line": 315, "description": "Detach Canvas from this graph", "itemtype": "method", "name": "detachCanvas", @@ -223,7 +224,7 @@ }, { "file": "../src/litegraph.js", - "line": 394, + "line": 329, "description": "Starts running this graph every interval milliseconds.", "itemtype": "method", "name": "start", @@ -238,7 +239,7 @@ }, { "file": "../src/litegraph.js", - "line": 421, + "line": 356, "description": "Stops the execution loop of the graph", "itemtype": "method", "name": "stop execution", @@ -246,7 +247,7 @@ }, { "file": "../src/litegraph.js", - "line": 443, + "line": 378, "description": "Run N steps (cycles) of the graph", "itemtype": "method", "name": "runStep", @@ -261,7 +262,7 @@ }, { "file": "../src/litegraph.js", - "line": 487, + "line": 422, "description": "Updates the graph execution order according to relevance of the nodes (nodes with only outputs have more relevance than\nnodes with only inputs.", "itemtype": "method", "name": "updateExecutionOrder", @@ -269,7 +270,7 @@ }, { "file": "../src/litegraph.js", - "line": 583, + "line": 520, "description": "Returns the amount of time the graph has been running in milliseconds", "itemtype": "method", "name": "getTime", @@ -281,7 +282,7 @@ }, { "file": "../src/litegraph.js", - "line": 594, + "line": 531, "description": "Returns the amount of time accumulated using the fixedtime_lapse var. This is used in context where the time increments should be constant", "itemtype": "method", "name": "getFixedTime", @@ -293,7 +294,7 @@ }, { "file": "../src/litegraph.js", - "line": 605, + "line": 542, "description": "Returns the amount of time it took to compute the latest iteration. Take into account that this number could be not correct\nif the nodes are using graphical actions", "itemtype": "method", "name": "getElapsedTime", @@ -305,7 +306,7 @@ }, { "file": "../src/litegraph.js", - "line": 617, + "line": 554, "description": "Sends an event to all the nodes, useful to trigger stuff", "itemtype": "method", "name": "sendEventToAllNodes", @@ -325,7 +326,7 @@ }, { "file": "../src/litegraph.js", - "line": 645, + "line": 582, "description": "Adds a new node instasnce to this graph", "itemtype": "method", "name": "add", @@ -340,7 +341,7 @@ }, { "file": "../src/litegraph.js", - "line": 690, + "line": 631, "description": "Removes a node from the graph", "itemtype": "method", "name": "remove", @@ -355,7 +356,7 @@ }, { "file": "../src/litegraph.js", - "line": 751, + "line": 697, "description": "Returns a node by its id.", "itemtype": "method", "name": "getNodeById", @@ -370,7 +371,7 @@ }, { "file": "../src/litegraph.js", - "line": 764, + "line": 710, "description": "Returns a list of nodes that matches a type", "itemtype": "method", "name": "findNodesByType", @@ -389,7 +390,7 @@ }, { "file": "../src/litegraph.js", - "line": 780, + "line": 726, "description": "Returns a list of nodes that matches a name", "itemtype": "method", "name": "findNodesByName", @@ -408,7 +409,7 @@ }, { "file": "../src/litegraph.js", - "line": 796, + "line": 742, "description": "Returns the top-most node in this position of the canvas", "itemtype": "method", "name": "getNodeOnPos", @@ -437,7 +438,7 @@ }, { "file": "../src/litegraph.js", - "line": 817, + "line": 804, "description": "Assigns a value to all the nodes that matches this name. This is used to create global variables of the node that\ncan be easily accesed from the outside of the graph", "itemtype": "method", "name": "setInputData", @@ -457,7 +458,7 @@ }, { "file": "../src/litegraph.js", - "line": 832, + "line": 819, "description": "Returns the value of the first node with this name. This is used to access global variables of the graph from the outside", "itemtype": "method", "name": "setInputData", @@ -476,7 +477,7 @@ }, { "file": "../src/litegraph.js", - "line": 869, + "line": 856, "description": "returns if the graph is in live mode", "itemtype": "method", "name": "isLive", @@ -484,7 +485,7 @@ }, { "file": "../src/litegraph.js", - "line": 893, + "line": 889, "description": "Creates a Object containing all the info about this graph, it can be serialized", "itemtype": "method", "name": "serialize", @@ -496,7 +497,7 @@ }, { "file": "../src/litegraph.js", - "line": 920, + "line": 922, "description": "Configure a graph from a JSON string", "itemtype": "method", "name": "configure", @@ -511,15 +512,15 @@ }, { "file": "../src/litegraph.js", - "line": 1026, - "description": "configure a node from an object", + "line": 1029, + "description": "configure a node from an object containing the serialized info", "itemtype": "method", "name": "configure", "class": "LGraphNode" }, { "file": "../src/litegraph.js", - "line": 1073, + "line": 1075, "description": "serialize the content", "itemtype": "method", "name": "serialize", @@ -527,7 +528,7 @@ }, { "file": "../src/litegraph.js", - "line": 1132, + "line": 1136, "description": "serialize and stringify", "itemtype": "method", "name": "toString", @@ -535,7 +536,15 @@ }, { "file": "../src/litegraph.js", - "line": 1145, + "line": 1148, + "description": "get the title string", + "itemtype": "method", + "name": "getTitle", + "class": "LGraphNode" + }, + { + "file": "../src/litegraph.js", + "line": 1161, "description": "sets the output data", "itemtype": "method", "name": "setOutputData", @@ -555,7 +564,7 @@ }, { "file": "../src/litegraph.js", - "line": 1161, + "line": 1180, "description": "retrieves the input data from one slot", "itemtype": "method", "name": "getInputData", @@ -574,7 +583,7 @@ }, { "file": "../src/litegraph.js", - "line": 1175, + "line": 1194, "description": "tells you if there is a connection in one input slot", "itemtype": "method", "name": "isInputConnected", @@ -593,7 +602,7 @@ }, { "file": "../src/litegraph.js", - "line": 1187, + "line": 1206, "description": "tells you info about an input connection (which node, type, etc)", "itemtype": "method", "name": "getInputInfo", @@ -612,7 +621,7 @@ }, { "file": "../src/litegraph.js", - "line": 1202, + "line": 1221, "description": "tells you info about an output connection (which node, type, etc)", "itemtype": "method", "name": "getOutputInfo", @@ -631,7 +640,7 @@ }, { "file": "../src/litegraph.js", - "line": 1217, + "line": 1236, "description": "tells you if there is a connection in one output slot", "itemtype": "method", "name": "isOutputConnected", @@ -650,7 +659,7 @@ }, { "file": "../src/litegraph.js", - "line": 1229, + "line": 1248, "description": "retrieves all the nodes connected to this output slot", "itemtype": "method", "name": "getOutputNodes", @@ -669,7 +678,7 @@ }, { "file": "../src/litegraph.js", - "line": 1258, + "line": 1277, "description": "add a new output slot to use in this node", "itemtype": "method", "name": "addOutput", @@ -694,7 +703,22 @@ }, { "file": "../src/litegraph.js", - "line": 1277, + "line": 1296, + "description": "add a new output slot to use in this node", + "itemtype": "method", + "name": "addOutputs", + "params": [ + { + "name": "array", + "description": "of triplets like [[name,type,extra_info],[...]]", + "type": "Array" + } + ], + "class": "LGraphNode" + }, + { + "file": "../src/litegraph.js", + "line": 1319, "description": "remove an existing output slot", "itemtype": "method", "name": "removeOutput", @@ -709,7 +733,7 @@ }, { "file": "../src/litegraph.js", - "line": 1289, + "line": 1331, "description": "add a new input slot to use in this node", "itemtype": "method", "name": "addInput", @@ -734,7 +758,22 @@ }, { "file": "../src/litegraph.js", - "line": 1308, + "line": 1350, + "description": "add several new input slots in this node", + "itemtype": "method", + "name": "addInputs", + "params": [ + { + "name": "array", + "description": "of triplets like [[name,type,extra_info],[...]]", + "type": "Array" + } + ], + "class": "LGraphNode" + }, + { + "file": "../src/litegraph.js", + "line": 1373, "description": "remove an existing input slot", "itemtype": "method", "name": "removeInput", @@ -749,7 +788,7 @@ }, { "file": "../src/litegraph.js", - "line": 1320, + "line": 1385, "description": "add an special connection to this node (used for special kinds of graphs)", "itemtype": "method", "name": "addConnection", @@ -779,7 +818,7 @@ }, { "file": "../src/litegraph.js", - "line": 1333, + "line": 1398, "description": "computes the size of a node according to its inputs and output slots", "itemtype": "method", "name": "computeSize", @@ -798,7 +837,7 @@ }, { "file": "../src/litegraph.js", - "line": 1351, + "line": 1416, "description": "returns the bounding of the object, used for rendering purposes", "itemtype": "method", "name": "getBounding", @@ -810,7 +849,7 @@ }, { "file": "../src/litegraph.js", - "line": 1361, + "line": 1426, "description": "checks if a point is inside the shape of a node", "itemtype": "method", "name": "isPointInsideNode", @@ -834,7 +873,45 @@ }, { "file": "../src/litegraph.js", - "line": 1401, + "line": 1448, + "description": "returns the input slot with a given name (used for dynamic slots), -1 if not found", + "itemtype": "method", + "name": "findInputSlot", + "params": [ + { + "name": "name", + "description": "the name of the slot", + "type": "String" + } + ], + "return": { + "description": "the slot (-1 if not found)", + "type": "Number" + }, + "class": "LGraphNode" + }, + { + "file": "../src/litegraph.js", + "line": 1463, + "description": "returns the output slot with a given name (used for dynamic slots), -1 if not found", + "itemtype": "method", + "name": "findOutputSlot", + "params": [ + { + "name": "name", + "description": "the name of the slot", + "type": "String" + } + ], + "return": { + "description": "the slot (-1 if not found)", + "type": "Number" + }, + "class": "LGraphNode" + }, + { + "file": "../src/litegraph.js", + "line": 1478, "description": "connect this node output to the input of another node", "itemtype": "method", "name": "connect", @@ -863,7 +940,7 @@ }, { "file": "../src/litegraph.js", - "line": 1482, + "line": 1561, "description": "disconnect one output to an specific node", "itemtype": "method", "name": "disconnectOutput", @@ -887,7 +964,7 @@ }, { "file": "../src/litegraph.js", - "line": 1545, + "line": 1628, "description": "disconnect one input", "itemtype": "method", "name": "disconnectInput", @@ -906,7 +983,7 @@ }, { "file": "../src/litegraph.js", - "line": 1599, + "line": 1685, "description": "returns the center of a connection point in canvas coords", "itemtype": "method", "name": "getConnectionPos", @@ -930,7 +1007,7 @@ }, { "file": "../src/litegraph.js", - "line": 1756, + "line": 1842, "description": "Collapse the node to make it smaller on the canvas", "itemtype": "method", "name": "collapse", @@ -938,11 +1015,77 @@ }, { "file": "../src/litegraph.js", - "line": 1769, + "line": 1855, "description": "Forces the node to do not move or realign on Z", "itemtype": "method", "name": "pin", "class": "LGraphNode" + }, + { + "file": "../src/litegraph.js", + "line": 1912, + "description": "clears all the data inside", + "itemtype": "method", + "name": "clear", + "class": "LGraphCanvas" + }, + { + "file": "../src/litegraph.js", + "line": 1966, + "description": "assigns a graph, you can reasign graphs to the same canvas", + "itemtype": "method", + "name": "setGraph", + "params": [ + { + "name": "assigns", + "description": "a graph", + "type": "LGraph" + } + ], + "class": "LGraphCanvas" + }, + { + "file": "../src/litegraph.js", + "line": 1994, + "description": "assigns a canvas", + "itemtype": "method", + "name": "setCanvas", + "params": [ + { + "name": "assigns", + "description": "a canvas", + "type": "Canvas" + } + ], + "class": "LGraphCanvas" + }, + { + "file": "../src/litegraph.js", + "line": 2132, + "description": "Used to attach the canvas in a popup", + "itemtype": "method", + "name": "getCanvasWindow", + "return": { + "description": "returns the window where the canvas is attached (the DOM root node)", + "type": "Window" + }, + "class": "LGraphCanvas" + }, + { + "file": "../src/litegraph.js", + "line": 2144, + "description": "starts rendering the content of the canvas when needed", + "itemtype": "method", + "name": "startRendering", + "class": "LGraphCanvas" + }, + { + "file": "../src/litegraph.js", + "line": 2175, + "description": "stops rendering the content of the canvas (to save resources)", + "itemtype": "method", + "name": "stopRendering", + "class": "LGraphCanvas" } ], "warnings": [] diff --git a/doc/files/.._src_litegraph.js.html b/doc/files/.._src_litegraph.js.html index 50a66387c..7c64f139b 100644 --- a/doc/files/.._src_litegraph.js.html +++ b/doc/files/.._src_litegraph.js.html @@ -118,10 +118,11 @@ var LiteGraph = { NODE_DEFAULT_BOXCOLOR: "#AEF", NODE_DEFAULT_SHAPE: "box", MAX_NUMBER_OF_NODES: 1000, //avoid infinite loops - DEFAULT_POSITION: [100,100], + DEFAULT_POSITION: [100,100],//default node position node_images_path: "", debug: false, + throw_errors: true, registered_node_types: {}, /** @@ -133,13 +134,10 @@ var LiteGraph = { registerNodeType: function(type, base_class) { - var title = type; - if(base_class.prototype && base_class.prototype.title) - title = base_class.prototype.title; - else if(base_class.title) - title = base_class.title; - + if(!base_class.prototype) + throw("Cannot register a simple object, it must be a class with a prototype"); base_class.type = type; + if(LiteGraph.debug) console.log("Node registered: " + type); @@ -149,13 +147,13 @@ var LiteGraph = { base_class.category = type.substr(0,pos); //info.name = name.substr(pos+1,name.length - pos); - //inheritance + //extend class if(base_class.prototype) //is a class for(var i in LGraphNode.prototype) if(!base_class.prototype[i]) base_class.prototype[i] = LGraphNode.prototype[i]; - this.registered_node_types[type] = base_class; + this.registered_node_types[ type ] = base_class; }, /** @@ -166,7 +164,7 @@ var LiteGraph = { * @param {Object} options to set options */ - createNode: function(type,name, options) + createNode: function(type, title, options) { var base_class = this.registered_node_types[type]; if (!base_class) @@ -178,48 +176,12 @@ var LiteGraph = { var prototype = base_class.prototype || base_class; - name = name || prototype.title || base_class.title || type; + title = title || base_class.title || type; - var node = null; - if (base_class.prototype) //is a class - { - node = new base_class(name); - } - else - { - node = new LGraphNode(name); - node.inputs = []; - node.outputs = []; - - //add inputs and outputs - for (var i in prototype) - { - if(i == "inputs") - { - for(var j in prototype[i]) - node.addInput( prototype[i][j][0],prototype[i][j][1], prototype[i][j][2] ); - } - else if(i == "outputs") - { - for(var j in prototype[i]) - node.addOutput( prototype[i][j][0],prototype[i][j][1], prototype[i][j][2] ); - } - else - { - if( prototype[i].concat ) //array - node[i] = prototype[i].concat(); - else if (typeof(prototype[i]) == 'object') - node[i] = LiteGraph.cloneObject(prototype[i]); //slow but safe - else - node[i] = prototype[i]; - } - } - //set size - if(base_class.size) node.size = base_class.size.concat(); //save size - } + var node = new base_class( name ); node.type = type; - if(!node.name) node.name = name; + if(!node.title) node.title = title; if(!node.flags) node.flags = {}; if(!node.size) node.size = node.computeSize(); if(!node.pos) node.pos = LiteGraph.DEFAULT_POSITION.concat(); @@ -332,6 +294,7 @@ var LiteGraph = { //separated just to improve if it doesnt work cloneObject: function(obj, target) { + if(obj == null) return null; var r = JSON.parse( JSON.stringify( obj ) ); if(!target) return r; @@ -339,53 +302,18 @@ var LiteGraph = { target[i] = r[i]; return target; } - - /* - benchmark: function(mode) - { - mode = mode || "all"; - - trace("Benchmarking " + mode + "..."); - trace(" Num. nodes: " + this._nodes.length ); - var links = 0; - for(var i in this._nodes) - for(var j in this._nodes[i].outputs) - if(this._nodes[i].outputs[j].node_id != null) - links++; - trace(" Num. links: " + links ); - - var numTimes = 200; - if(mode == "core") - numTimes = 30000; - - var start = new Date().getTime(); - - for(var i = 0; i < numTimes; i++) - { - if(mode == "render") - this.draw(false); - else if(mode == "core") - this.sendEventToAllNodes("onExecute"); - else - { - this.sendEventToAllNodes("onExecute"); - this.draw(false); - } - } - - var elapsed = (new Date().getTime()) - start; - trace(" Time take for " + numTimes + " iterations: " + (elapsed*0.001).toFixed(3) + " seconds."); - var seconds_per_iteration = (elapsed*0.001)/numTimes; - trace(" Time per iteration: " + seconds_per_iteration.toFixed( seconds_per_iteration < 0.001 ? 6 : 3) + " seconds"); - trace(" Avg FPS: " + (1000/(elapsed/numTimes)).toFixed(3)); - } - */ }; +if(typeof(performance) != "undefined") + LiteGraph.getTime = function getTime() { return performance.now(); } +else + LiteGraph.getTime = function getTime() { return Date.now(); } + + //********************************************************************************* // LGraph CLASS //********************************************************************************* @@ -405,6 +333,12 @@ function LGraph() this.clear(); } +//default supported types +LGraph.supported_types = ["number","string","boolean"]; + +//used to know which types of connections support this graph (some graphs do not allow certain types) +LGraph.prototype.getSupportedTypes = function() { return this.supported_types || LGraph.supported_types; } + LGraph.STATUS_STOPPED = 1; LGraph.STATUS_RUNNING = 2; @@ -425,7 +359,7 @@ LGraph.prototype.clear = function() //links this.last_link_id = 0; - this.links = {}; + this.links = {}; //container with all the links //iterations this.iteration = 0; @@ -442,7 +376,8 @@ LGraph.prototype.clear = function() this.starttime = 0; //globals - this.globals = {}; + this.global_inputs = {}; + this.global_outputs = {}; this.graph = {}; this.debug = true; @@ -502,7 +437,7 @@ LGraph.prototype.start = function(interval) this.sendEventToAllNodes("onStart"); //launch - this.starttime = window.performance.now(); + this.starttime = LiteGraph.getTime(); interval = interval || 1; var that = this; @@ -544,7 +479,7 @@ LGraph.prototype.runStep = function(num) { num = num || 1; - var start = window.performance.now(); + var start = LiteGraph.getTime(); this.globaltime = 0.001 * (start - this.starttime); try @@ -571,7 +506,7 @@ LGraph.prototype.runStep = function(num) this.stop(); } - var elapsed = window.performance.now() - start; + var elapsed = LiteGraph.getTime() - start; if (elapsed == 0) elapsed = 1; this.elapsed_time = 0.001 * elapsed; this.globaltime += 0.001 * elapsed; @@ -638,20 +573,22 @@ LGraph.prototype.computeExecutionOrder = function() //for every connection for(var j = 0; j < output.links.length; j++) { - var link = output.links[j]; + var link_id = output.links[j]; + var link = this.links[link_id]; + if(!link) continue; //already visited link (ignore it) - if(visited_links[ link[0] ]) + if(visited_links[ link.id ]) continue; - var target_node = this.getNodeById( link[3] ); + var target_node = this.getNodeById( link.target_id ); if(target_node == null) { - visited_links[ link[0] ] = true; + visited_links[ link.id ] = true; continue; } - visited_links[link[0]] = true; //mark as visited + visited_links[link.id] = true; //mark as visited remaining_links[target_node.id] -= 1; //reduce the number of links remaining if (remaining_links[target_node.id] == 0) S.push(target_node); //if no more links, then add to Starters array @@ -742,7 +679,7 @@ LGraph.prototype.sendActionToCanvas = function(action, params) * @param {LGraphNode} node the instance of the node */ -LGraph.prototype.add = function(node) +LGraph.prototype.add = function(node, skip_compute_order) { if(!node || (node.id != -1 && this._nodes_by_id[node.id] != null)) return; //already added @@ -765,16 +702,20 @@ LGraph.prototype.add = function(node) node.bgImage = node.loadImage(node.bgImageUrl); */ - if(node.onInit) - node.onInit(); + if(node.onAdded) + node.onAdded(); if(this.config.align_to_grid) node.alignToGrid(); - - this.updateExecutionOrder(); - if(this.canvas) - this.canvas.dirty_canvas = true; + if(!skip_compute_order) + this.updateExecutionOrder(); + + if(this.onNodeAdded) + this.onNodeAdded(node); + + + this.setDirtyCanvas(true); this.change(); @@ -816,16 +757,19 @@ LGraph.prototype.remove = function(node) node.id = -1; //callback - if(node.onDelete) - node.onDelete(); + if(node.onRemoved) + node.onRemoved(); - //remove from environment - if(this.canvas) + node.graph = null; + + //remove from canvas render + for(var i in this.list_of_graphcanvas) { - if(this.canvas.selected_nodes[node.id]) - delete this.canvas.selected_nodes[node.id]; - if(this.canvas.node_dragged == node) - this.canvas.node_dragged = null; + var canvas = this.list_of_graphcanvas[i]; + if(canvas.selected_nodes[node.id]) + delete canvas.selected_nodes[node.id]; + if(canvas.node_dragged == node) + canvas.node_dragged = null; } //remove from containers @@ -834,8 +778,10 @@ LGraph.prototype.remove = function(node) this._nodes.splice(pos,1); delete this._nodes_by_id[node.id]; - if(this.canvas) - this.canvas.setDirty(true,true); + if(this.onNodeRemoved) + this.onNodeRemoved(node); + + this.setDirtyCanvas(true,true); this.change(); @@ -878,11 +824,11 @@ LGraph.prototype.findNodesByType = function(type) * @return {Array} a list with all the nodes with this name */ -LGraph.prototype.findNodesByName = function(name) +LGraph.prototype.findNodesByTitle = function(title) { var result = []; for (var i in this._nodes) - if(this._nodes[i].name == name) + if(this._nodes[i].title == title) result.push(this._nodes[i]); return result; } @@ -908,6 +854,47 @@ LGraph.prototype.getNodeOnPos = function(x,y, nodes_list) return null; } +//Tell this graph has a global input of this type +LGraph.prototype.addGlobalInput = function(name, type, value) +{ + this.global_inputs[name] = { type: type, value: value }; +} + +//assign a data to the global input +LGraph.prototype.setGlobalInputData = function(name, data) +{ + var input = this.global_inputs[name]; + if (!input) + return; + input.value = data; +} + +//rename the global input +LGraph.prototype.renameGlobalInput = function(old_name, name, data) +{ +} + + +LGraph.prototype.addGlobalOutput = function(name, type, value) +{ + this.global_outputs[name] = { type: type, value: value }; +} + +//assign a data to the global output +LGraph.prototype.setGlobalOutputData = function(name, data) +{ + var output = this.global_outputs[ name ]; + if (!output) + return; + output.value = data; +} + +//rename the global output +LGraph.prototype.renameGlobalOutput = function(old_name, name, data) +{ +} + + /** * Assigns a value to all the nodes that matches this name. This is used to create global variables of the node that * can be easily accesed from the outside of the graph @@ -967,8 +954,12 @@ LGraph.prototype.onConnectionChange = function() LGraph.prototype.isLive = function() { - if(!this.canvas) return false; - return this.canvas.live_mode; + for(var i in this.list_of_graphcanvas) + { + var c = this.list_of_graphcanvas[i]; + if(c.live_mode) return true; + } + return false; } /* Called when something visually changed */ @@ -983,6 +974,11 @@ LGraph.prototype.change = function() this.on_change(this); } +LGraph.prototype.setDirtyCanvas = function(fg,bg) +{ + this.sendActionToCanvas("setDirty",[fg,bg]); +} + //save and recover app state *************************************** /** * Creates a Object containing all the info about this graph, it can be serialized @@ -995,6 +991,11 @@ LGraph.prototype.serialize = function() for (var i in this._nodes) nodes_info.push( this._nodes[i].serialize() ); + //remove data from links, we dont want to store it + for (var i in this.links) + this.links[i].data = null; + + var data = { graph: this.graph, @@ -1002,6 +1003,7 @@ LGraph.prototype.serialize = function() frame: this.frame, last_node_id: this.last_node_id, last_link_id: this.last_link_id, + links: LiteGraph.cloneObject( this.links ), config: this.config, nodes: nodes_info @@ -1034,8 +1036,8 @@ LGraph.prototype.configure = function(data, keep_old) for (var i in nodes) { var n_info = nodes[i]; //stored info - var n = LiteGraph.createNode( n_info.type, n_info.name ); - if(!n) + var node = LiteGraph.createNode( n_info.type, n_info.title ); + if(!node) { if(LiteGraph.debug) console.log("Node not found: " + n_info.type); @@ -1043,21 +1045,19 @@ LGraph.prototype.configure = function(data, keep_old) continue; } - n.configure(n_info); - this.add(n); + node.id = n_info.id; //id it or it will create a new id + this.add(node, true); //add before configure, otherwise configure cannot create links + node.configure(n_info); } - //TODO: dispatch redraw - if(this.canvas) - this.canvas.draw(true,true); - + this.updateExecutionOrder(); + this.setDirtyCanvas(true,true); return error; } LGraph.prototype.onNodeTrace = function(node, msg, color) { - if(this.canvas) - this.canvas.onNodeTrace(node,msg,color); + //TODO } // ************************************************************* @@ -1070,18 +1070,21 @@ LGraph.prototype.onNodeTrace = function(node, msg, color) + unsafe_execution: not allowed for safe execution supported callbacks: - + onInit: when added to graph + + onAdded: when added to graph + + onRemoved: when removed from graph + onStart: when starts playing + onStop: when stops playing - + onDrawForeground - + onDrawBackground + + onDrawForeground: render the inside widgets inside the node + + onDrawBackground: render the background area inside the node (only in edit mode) + + onMouseDown + onMouseMove - + onMouseOver + + onMouseUp + + onMouseEnter + + onMouseLeave + onExecute: execute the node + onPropertyChange: when a property is changed in the panel (return true to skip default behaviour) + onGetInputs: returns an array of possible inputs + onGetOutputs: returns an array of possible outputs - + onClick + onDblClick + onSerialize + onSelected @@ -1094,9 +1097,9 @@ LGraph.prototype.onNodeTrace = function(node, msg, color) * @param {String} name a name for the node */ -function LGraphNode(name) +function LGraphNode(title) { - this.name = name || "Unnamed"; + this.title = title || "Unnamed"; this.size = [LiteGraph.NODE_WIDTH,60]; this.graph = null; @@ -1118,7 +1121,7 @@ function LGraphNode(name) } /** -* configure a node from an object +* configure a node from an object containing the serialized info * @method configure */ LGraphNode.prototype.configure = function(info) @@ -1129,39 +1132,38 @@ LGraphNode.prototype.configure = function(info) if(info[j] == null) continue; - else if( info[j].concat ) //array - this[j] = info[j].concat(); else if (typeof(info[j]) == 'object') //object - this[j] = LiteGraph.cloneObject(info[j], this[j] || {} ); + this[j] = LiteGraph.cloneObject(info[j], this[j]); else //value this[j] = info[j]; } -} -/* Copy all the info from one object to this node (used for serialization) */ -LGraphNode.prototype.copyFromObject = function(info, ignore_connections) -{ - var outputs = null; - var inputs = null; - var properties = null; - var local_data = null; - - for (var j in info) + //FOR LEGACY, PLEASE REMOVE ON NEXT VERSION + for(var i in this.inputs) { - if(ignore_connections && (j == "outputs" || j == "inputs")) + var input = this.inputs[i]; + if(!input.link || !input.link.length ) continue; - - if(j == "console") continue; - - if(info[j] == null) + var link = input.link; + if(typeof(link) != "object") continue; - else if( info[j].concat ) //array - this[j] = info[j].concat(); - else if (typeof(info[j]) == 'object') //object - this[j] = LiteGraph.cloneObject(info[j]); - else //value - this[j] = info[j]; + input.link = link[0]; + this.graph.links[ link[0] ] = { id: link[0], origin_id: link[1], origin_slot: link[2], target_id: link[3], target_slot: link[4] }; } + for(var i in this.outputs) + { + var output = this.outputs[i]; + if(!output.links || output.links.length == 0) + continue; + for(var j in output.links) + { + var link = output.links[j]; + if(typeof(link) != "object") + continue; + output.links[j] = link[0]; + } + } + } /** @@ -1173,17 +1175,19 @@ LGraphNode.prototype.serialize = function() { var o = { id: this.id, - name: this.name, + title: this.title, type: this.type, pos: this.pos, size: this.size, data: this.data, - properties: LiteGraph.cloneObject(this.properties), flags: LiteGraph.cloneObject(this.flags), inputs: this.inputs, outputs: this.outputs }; + if(this.properties) + o.properties = LiteGraph.cloneObject(this.properties); + if(!o.type) o.type = this.constructor.type; @@ -1210,8 +1214,8 @@ LGraphNode.prototype.reducedObjectivize = function() var type = LiteGraph.getNodeType(o.type); - if(type.name == o.name) - delete o["name"]; + if(type.title == o.title) + delete o["title"]; if(type.size && compareObjects(o.size,type.size)) delete o["size"]; @@ -1235,6 +1239,18 @@ LGraphNode.prototype.toString = function() //LGraphNode.prototype.unserialize = function(info) {} //this cannot be done from within, must be done in LiteGraph +/** +* get the title string +* @method getTitle +*/ + +LGraphNode.prototype.getTitle = function() +{ + return this.title || this.constructor.title; +} + + + // Execution ************************* /** * sets the output data @@ -1248,7 +1264,10 @@ LGraphNode.prototype.setOutputData = function(slot,data) if(slot > -1 && slot < this.outputs.length && this.outputs[slot] && this.outputs[slot].links != null) { for(var i = 0; i < this.outputs[slot].links.length; i++) - this.graph.links[ this.outputs[slot].links[i][0] ] = data; + { + var link_id = this.outputs[slot].links[i]; + this.graph.links[ link_id ].data = data; + } } } @@ -1262,7 +1281,7 @@ LGraphNode.prototype.getInputData = function(slot) { if(!this.inputs) return null; if(slot < this.inputs.length && this.inputs[slot].link != null) - return this.graph.links[ this.inputs[slot].link[0] ]; + return this.graph.links[ this.inputs[slot].link ].data; return null; } @@ -1334,7 +1353,7 @@ LGraphNode.prototype.getOutputNodes = function(slot) var output = this.outputs[slot]; var r = []; for(var i = 0; i < output.length; i++) - r.push( this.graph.getNodeById( output.links[i][3] )); + r.push( this.graph.getNodeById( output.links[i].target_id )); return r; } return null; @@ -1368,6 +1387,29 @@ LGraphNode.prototype.addOutput = function(name,type,extra_info) this.size = this.computeSize(); } +/** +* add a new output slot to use in this node +* @method addOutputs +* @param {Array} array of triplets like [[name,type,extra_info],[...]] +*/ +LGraphNode.prototype.addOutputs = function(array) +{ + for(var i in array) + { + var info = array[i]; + var o = {name:info[0],type:info[1],link:null}; + if(array[2]) + for(var j in info[2]) + o[j] = info[2][j]; + + if(!this.outputs) + this.outputs = []; + this.outputs.push(o); + } + + this.size = this.computeSize(); +} + /** * remove an existing output slot * @method removeOutput @@ -1399,6 +1441,29 @@ LGraphNode.prototype.addInput = function(name,type,extra_info) this.size = this.computeSize(); } +/** +* add several new input slots in this node +* @method addInputs +* @param {Array} array of triplets like [[name,type,extra_info],[...]] +*/ +LGraphNode.prototype.addInputs = function(array) +{ + for(var i in array) + { + var info = array[i]; + var o = {name:info[0],type:info[1],link:null}; + if(array[2]) + for(var j in info[2]) + o[j] = info[2][j]; + + if(!this.inputs) + this.inputs = []; + this.inputs.push(o); + } + + this.size = this.computeSize(); +} + /** * remove an existing input slot * @method removeInput @@ -1461,7 +1526,7 @@ LGraphNode.prototype.getBounding = function() */ LGraphNode.prototype.isPointInsideNode = function(x,y) { - var margin_top = this.graph.isLive() ? 0 : 20; + 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) @@ -1474,6 +1539,12 @@ LGraphNode.prototype.isPointInsideNode = function(x,y) return false; } +/** +* returns the input slot with a given name (used for dynamic slots), -1 if not found +* @method findInputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findInputSlot = function(name) { if(!this.inputs) return -1; @@ -1483,6 +1554,12 @@ LGraphNode.prototype.findInputSlot = function(name) return -1; } +/** +* returns the output slot with a given name (used for dynamic slots), -1 if not found +* @method findOutputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findOutputSlot = function(name) { if(!this.outputs) return -1; @@ -1560,12 +1637,14 @@ LGraphNode.prototype.connect = function(slot, node, target_slot) output.type == node.inputs[target_slot].type) //same type { //info: link structure => [ 0:link_id, 1:start_node_id, 2:start_slot, 3:end_node_id, 4:end_slot ] - var link = [ this.graph.last_link_id++, this.id, slot, node.id, target_slot ]; + //var link = [ this.graph.last_link_id++, this.id, slot, node.id, target_slot ]; + var link = { id: this.graph.last_link_id++, origin_id: this.id, origin_slot: slot, target_id: node.id, target_slot: target_slot }; + this.graph.links[ link.id ] = link; //connect if( output.links == null ) output.links = []; - output.links.push(link); - node.inputs[target_slot].link = link; + output.links.push( link.id ); + node.inputs[target_slot].link = link.id; this.setDirtyCanvas(false,true); this.graph.onConnectionChange(); @@ -1608,13 +1687,15 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node) { for(var i = 0, l = output.links.length; i < l; i++) { - var link = output.links[i]; + var link_id = output.links[i]; + var link_info = this.graph.links[ link_id ]; + //is the link we are searching for... - if( link[3] == target_node.id ) + if( link_info.target_id == target_node.id ) { output.links.splice(i,1); //remove here - target_node.inputs[ link[4] ].link = null; //remove there - delete this.graph.links[link[0]]; + target_node.inputs[ link_info.target_slot ].link = null; //remove there + delete this.graph.links[ link_id ]; //remove the link from the links pool break; } } @@ -1623,10 +1704,12 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node) { for(var i = 0, l = output.links.length; i < l; i++) { - var link = output.links[i]; - var target_node = this.graph.getNodeById( link[3] ); + var link_id = output.links[i]; + var link_info = this.graph.links[ link_id ]; + + var target_node = this.graph.getNodeById( link_info.target_id ); if(target_node) - target_node.inputs[ link[4] ].link = null; //remove other side link + target_node.inputs[ link_info.target_slot ].link = null; //remove other side link } output.links = null; } @@ -1664,21 +1747,24 @@ LGraphNode.prototype.disconnectInput = function(slot) var input = this.inputs[slot]; if(!input) return false; - var link = this.inputs[slot].link; + var link_id = this.inputs[slot].link; this.inputs[slot].link = null; //remove other side - var node = this.graph.getNodeById( link[1] ); + 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[2] ]; + 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++) { - var link = output.links[i]; - if( link[3] == this.id ) + 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; @@ -1843,7 +1929,7 @@ LGraphNode.prototype.captureInput = function(v) //change c.node_capturing_input = v ? this : null; if(this.graph.debug) - console.log(this.name + ": Capturing input " + (v?"ON":"OFF")); + console.log(this.title + ": Capturing input " + (v?"ON":"OFF")); } } @@ -1890,8 +1976,8 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas) * * @class LGraphCanvas * @constructor -* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format) -* @param {LGraph} graph +* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format or the canvas itself) +* @param {LGraph} graph [optional] */ function LGraphCanvas(canvas, graph) { @@ -1916,6 +2002,12 @@ function LGraphCanvas(canvas, graph) LGraphCanvas.link_type_colors = {'number':"#AAC",'node':"#DCA"}; + +/** +* clears all the data inside +* +* @method clear +*/ LGraphCanvas.prototype.clear = function() { this.frame = 0; @@ -1965,6 +2057,12 @@ LGraphCanvas.prototype.clear = function() //this.UIinit(); } +/** +* assigns a graph, you can reasign graphs to the same canvas +* +* @method setGraph +* @param {LGraph} assigns a graph +*/ LGraphCanvas.prototype.setGraph = function(graph) { if(this.graph == graph) return; @@ -1987,6 +2085,12 @@ LGraphCanvas.prototype.setGraph = function(graph) this.setDirty(true,true); } +/** +* assigns a canvas +* +* @method setCanvas +* @param {Canvas} assigns a canvas +*/ LGraphCanvas.prototype.setCanvas = function(canvas) { var that = this; @@ -2025,7 +2129,7 @@ LGraphCanvas.prototype.setCanvas = function(canvas) this._mousemove_callback = this.processMouseMove.bind(this); this._mouseup_callback = this.processMouseUp.bind(this); - this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this) ); //down do not need to store the binded + this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded this.canvas.addEventListener("mousemove", this._mousemove_callback); this.canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; }); @@ -2103,6 +2207,14 @@ LGraphCanvas.prototype.UIinit = function() } */ +/** +* marks as dirty the canvas, this way it will be rendered again +* +* @class LGraphCanvas +* @method setDirty +* @param {bool} fgcanvas if the foreground canvas is dirty (the one containing the nodes) +* @param {bool} bgcanvas if the background canvas is dirty (the one containing the wires) +*/ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) { if(fgcanvas) @@ -2111,13 +2223,23 @@ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) this.dirty_bgcanvas = true; } -//Used to attach the canvas in a popup +/** +* Used to attach the canvas in a popup +* +* @method getCanvasWindow +* @return {window} returns the window where the canvas is attached (the DOM root node) +*/ LGraphCanvas.prototype.getCanvasWindow = function() { var doc = this.canvas.ownerDocument; return doc.defaultView || doc.parentWindow; } +/** +* starts rendering the content of the canvas when needed +* +* @method startRendering +*/ LGraphCanvas.prototype.startRendering = function() { if(this.is_rendering) return; //already rendering @@ -2144,6 +2266,11 @@ LGraphCanvas.prototype.startRendering = function() */ } +/** +* stops rendering the content of the canvas (to save resources) +* +* @method stopRendering +*/ LGraphCanvas.prototype.stopRendering = function() { this.is_rendering = false; @@ -2168,8 +2295,8 @@ LGraphCanvas.prototype.processMouseDown = function(e) var document = ref_window.document; this.canvas.removeEventListener("mousemove", this._mousemove_callback ); - ref_window.document.addEventListener("mousemove", this._mousemove_callback ); //catch for the entire window - ref_window.document.addEventListener("mouseup", this._mouseup_callback ); + 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 skip_dragging = false; @@ -2250,7 +2377,7 @@ LGraphCanvas.prototype.processMouseDown = function(e) var block_drag_node = false; //double clicking - var now = window.performance.now(); + var now = LiteGraph.getTime(); if ((now - this.last_mouseclick) < 300 && this.selected_nodes[n.id]) { //double click node @@ -2305,7 +2432,7 @@ LGraphCanvas.prototype.processMouseDown = function(e) this.last_mouse[0] = e.localX; this.last_mouse[1] = e.localY; - this.last_mouseclick = window.performance.now(); + this.last_mouseclick = LiteGraph.getTime(); this.canvas_mouse = [e.canvasX, e.canvasY]; /* @@ -2422,8 +2549,8 @@ LGraphCanvas.prototype.processMouseMove = function(e) n.pos[0] += delta[0] / this.scale; n.pos[1] += delta[1] / this.scale; - n.pos[0] = Math.round(n.pos[0]); - n.pos[1] = Math.round(n.pos[1]); + //n.pos[0] = Math.round(n.pos[0]); + //n.pos[1] = Math.round(n.pos[1]); } this.dirty_canvas = true; @@ -2516,7 +2643,8 @@ LGraphCanvas.prototype.processMouseUp = function(e) { this.dirty_canvas = true; this.dirty_bgcanvas = true; - + this.node_dragged.pos[0] = Math.round(this.node_dragged.pos[0]); + this.node_dragged.pos[1] = Math.round(this.node_dragged.pos[1]); if(this.graph.config.align_to_grid) this.node_dragged.alignToGrid(); this.node_dragged = null; @@ -2856,7 +2984,7 @@ LGraphCanvas.prototype.computeVisibleNodes = function() LGraphCanvas.prototype.draw = function(force_canvas, force_bgcanvas) { //fps counting - var now = window.performance.now(); + var now = LiteGraph.getTime(); this.render_time = (now - this.last_draw_time)*0.001; this.last_draw_time = now; @@ -3103,10 +3231,10 @@ LGraphCanvas.prototype.drawNode = function(node, ctx ) } else if(this.render_shadows) { - ctx.shadowColor = "#111"; + ctx.shadowColor = "rgba(0,0,0,0.5)"; ctx.shadowOffsetX = 2; ctx.shadowOffsetY = 2; - ctx.shadowBlur = 4; + ctx.shadowBlur = 3; } else ctx.shadowColor = "transparent"; @@ -3363,10 +3491,11 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo //title text ctx.font = this.title_text_font; - if(node.name != "" && this.scale > 0.8) + var title = node.getTitle(); + if(title && this.scale > 0.8) { ctx.fillStyle = "#222"; - ctx.fillText(node.name,16,13-title_height ); + ctx.fillText( title, 16, 13 - title_height ); } } } @@ -3444,12 +3573,15 @@ LGraphCanvas.prototype.drawConnections = function(ctx) for(var i in node.inputs) { var input = node.inputs[i]; - if(!input || !input.link ) continue; - var link = input.link; + if(!input || input.link == null) + continue; + var link_id = input.link; + var link = this.graph.links[ link_id ]; + if(!link) continue; - var start_node = this.graph.getNodeById( link[1] ); + var start_node = this.graph.getNodeById( link.origin_id ); if(start_node == null) continue; - var start_node_slot = link[2]; + var start_node_slot = link.origin_slot; var start_node_slotpos = null; if(start_node_slot == -1) @@ -3479,7 +3611,7 @@ LGraphCanvas.prototype.renderLink = function(ctx,a,b,color) var dist = distance(a,b); - if(this.render_connections_border) + if(this.render_connections_border && this.scale > 0.6) ctx.lineWidth = this.connections_width + 4; ctx.beginPath(); @@ -3499,7 +3631,7 @@ LGraphCanvas.prototype.renderLink = function(ctx,a,b,color) ctx.lineTo(b[0]-10,b[1]); } - if(this.render_connections_border) + if(this.render_connections_border && this.scale > 0.6) { ctx.strokeStyle = "rgba(0,0,0,0.5)"; ctx.stroke(); @@ -3782,7 +3914,7 @@ LGraphCanvas.onMenuNodeOutputs = function(node, e, prev_menu) LGraphCanvas.onMenuNodeCollapse = function(node) { node.flags.collapsed = !node.flags.collapsed; - node.graph.canvas.setDirty(true,true); + node.setDirtyCanvas(true,true); } LGraphCanvas.onMenuNodePin = function(node) @@ -3809,7 +3941,7 @@ LGraphCanvas.onMenuNodeColors = function(node, e, prev_menu) { node.color = color.color; node.bgcolor = color.bgcolor; - node.graph.canvas.setDirty(true); + node.setDirtyCanvas(true); } } @@ -3824,7 +3956,7 @@ LGraphCanvas.onMenuNodeShapes = function(node,e) { if(!node) return; node.shape = v; - node.graph.canvas.setDirty(true); + node.setDirtyCanvas(true); } return false; @@ -3834,7 +3966,7 @@ LGraphCanvas.onMenuNodeRemove = function(node) { if(node.removable == false) return; node.graph.remove(node); - node.graph.canvas.setDirty(true,true); + node.setDirtyCanvas(true,true); } LGraphCanvas.onMenuNodeClone = function(node) @@ -3844,7 +3976,7 @@ LGraphCanvas.onMenuNodeClone = function(node) if(!newnode) return; newnode.pos = [node.pos[0]+5,node.pos[1]+5]; node.graph.add(newnode); - node.graph.canvas.setDirty(true,true); + node.setDirtyCanvas(true,true); } LGraphCanvas.node_colors = { @@ -3883,10 +4015,19 @@ LGraphCanvas.prototype.getNodeMenuOptions = function(node) if( node.removable == false ) options[9].disabled = true; - if(node.onGetInputs && node.onGetInputs().length ) - options[0].disabled = false; - if(node.onGetOutputs && node.onGetOutputs().length ) - options[1].disabled = false; + if(node.onGetInputs) + { + var inputs = node.onGetInputs(); + if(inputs && inputs.length) + options[0].disabled = false; + } + + if(node.onGetOutputs) + { + var outputs = node.onGetOutputs(); + if(outputs && outputs.length ) + options[1].disabled = false; + } return options; } diff --git a/index.html b/index.html index 6e8b2adef..2ac0f7556 100644 --- a/index.html +++ b/index.html @@ -44,6 +44,7 @@

    Documentation

    +

    Here you can check automatically generated documentation.

    diff --git a/src/litegraph.js b/src/litegraph.js index 77361ed50..02083227c 100644 --- a/src/litegraph.js +++ b/src/litegraph.js @@ -1445,6 +1445,12 @@ LGraphNode.prototype.isPointInsideNode = function(x,y) return false; } +/** +* returns the input slot with a given name (used for dynamic slots), -1 if not found +* @method findInputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findInputSlot = function(name) { if(!this.inputs) return -1; @@ -1454,6 +1460,12 @@ LGraphNode.prototype.findInputSlot = function(name) return -1; } +/** +* returns the output slot with a given name (used for dynamic slots), -1 if not found +* @method findOutputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findOutputSlot = function(name) { if(!this.outputs) return -1; @@ -1870,8 +1882,8 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas) * * @class LGraphCanvas * @constructor -* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format) -* @param {LGraph} graph +* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format or the canvas itself) +* @param {LGraph} graph [optional] */ function LGraphCanvas(canvas, graph) { @@ -1896,6 +1908,12 @@ function LGraphCanvas(canvas, graph) LGraphCanvas.link_type_colors = {'number':"#AAC",'node':"#DCA"}; + +/** +* clears all the data inside +* +* @method clear +*/ LGraphCanvas.prototype.clear = function() { this.frame = 0; @@ -1945,6 +1963,12 @@ LGraphCanvas.prototype.clear = function() //this.UIinit(); } +/** +* assigns a graph, you can reasign graphs to the same canvas +* +* @method setGraph +* @param {LGraph} assigns a graph +*/ LGraphCanvas.prototype.setGraph = function(graph) { if(this.graph == graph) return; @@ -1967,6 +1991,12 @@ LGraphCanvas.prototype.setGraph = function(graph) this.setDirty(true,true); } +/** +* assigns a canvas +* +* @method setCanvas +* @param {Canvas} assigns a canvas +*/ LGraphCanvas.prototype.setCanvas = function(canvas) { var that = this; @@ -2005,7 +2035,7 @@ LGraphCanvas.prototype.setCanvas = function(canvas) this._mousemove_callback = this.processMouseMove.bind(this); this._mouseup_callback = this.processMouseUp.bind(this); - this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this) ); //down do not need to store the binded + this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded this.canvas.addEventListener("mousemove", this._mousemove_callback); this.canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; }); @@ -2083,6 +2113,14 @@ LGraphCanvas.prototype.UIinit = function() } */ +/** +* marks as dirty the canvas, this way it will be rendered again +* +* @class LGraphCanvas +* @method setDirty +* @param {bool} fgcanvas if the foreground canvas is dirty (the one containing the nodes) +* @param {bool} bgcanvas if the background canvas is dirty (the one containing the wires) +*/ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) { if(fgcanvas) @@ -2091,13 +2129,23 @@ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) this.dirty_bgcanvas = true; } -//Used to attach the canvas in a popup +/** +* Used to attach the canvas in a popup +* +* @method getCanvasWindow +* @return {window} returns the window where the canvas is attached (the DOM root node) +*/ LGraphCanvas.prototype.getCanvasWindow = function() { var doc = this.canvas.ownerDocument; return doc.defaultView || doc.parentWindow; } +/** +* starts rendering the content of the canvas when needed +* +* @method startRendering +*/ LGraphCanvas.prototype.startRendering = function() { if(this.is_rendering) return; //already rendering @@ -2124,6 +2172,11 @@ LGraphCanvas.prototype.startRendering = function() */ } +/** +* stops rendering the content of the canvas (to save resources) +* +* @method stopRendering +*/ LGraphCanvas.prototype.stopRendering = function() { this.is_rendering = false; @@ -2148,8 +2201,8 @@ LGraphCanvas.prototype.processMouseDown = function(e) var document = ref_window.document; this.canvas.removeEventListener("mousemove", this._mousemove_callback ); - ref_window.document.addEventListener("mousemove", this._mousemove_callback ); //catch for the entire window - ref_window.document.addEventListener("mouseup", this._mouseup_callback ); + 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 skip_dragging = false; diff --git a/src/nodes/math.js b/src/nodes/math.js index bafc79119..6d45045e9 100644 --- a/src/nodes/math.js +++ b/src/nodes/math.js @@ -146,7 +146,6 @@ function MathOperation() this.addInput("A","number"); this.addInput("B","number"); this.addOutput("A+B","number"); - this.size = [80,20]; this.properties = {A:1.0, B:1.0}; } @@ -252,12 +251,34 @@ MathCompare.prototype.onGetOutputs = function() LiteGraph.registerNodeType("math/compare",MathCompare); +function MathAccumulate() +{ + this.addInput("inc","number"); + this.addOutput("total","number"); + this.properties = { increment: 0, value: 0 }; +} + +MathAccumulate.title = "Accumulate"; +MathAccumulate.desc = "Increments a value every time"; + +MathAccumulate.prototype.onExecute = function() +{ + var inc = this.getInputData(0); + if(inc !== null) + this.properties.value += inc; + else + this.properties.value += this.properties.increment; + this.setOutputData(0, this.properties.value ); +} + +LiteGraph.registerNodeType("math/accumulate", MathAccumulate); + //Math Trigonometry function MathTrigonometry() { this.addInput("v","number"); this.addOutput("sin","number"); - this.properties = {amplitude:1.0}; + this.properties = {amplitude:1.0, offset: 0}; this.bgImageUrl = "nodes/imgs/icon-sin.png"; } @@ -267,7 +288,15 @@ MathTrigonometry.desc = "Sin Cos Tan"; MathTrigonometry.prototype.onExecute = function() { var v = this.getInputData(0); - var amp = this.properties["amplitude"]; + var amplitude = this.properties["amplitude"]; + var slot = this.findInputSlot("amplitude"); + if(slot != -1) + amplitude = this.getInputData(slot); + var offset = this.properties["offset"]; + slot = this.findInputSlot("offset"); + if(slot != -1) + offset = this.getInputData(slot); + for(var i = 0, l = this.outputs.length; i < l; ++i) { var output = this.outputs[i]; @@ -280,10 +309,16 @@ MathTrigonometry.prototype.onExecute = function() case "acos": value = Math.acos(v); break; case "atan": value = Math.atan(v); break; } - this.setOutputData(i, amp * value ); + this.setOutputData(i, amplitude * value + offset); } } +MathTrigonometry.prototype.onGetInputs = function() +{ + return [["v","number"],["amplitude","number"],["offset","number"]]; +} + + MathTrigonometry.prototype.onGetOutputs = function() { return [["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos","number"],["atan","number"]]; @@ -373,6 +408,7 @@ if(window.glMatrix) { this.addInputs([["x","number"],["y","number"],["z","number"]]); this.addOutput("vec3","vec3"); + this.properties = {x:0, y:0, z:0}; } Math3DXYZToVec3.title = "XYZ->Vec3"; @@ -381,11 +417,11 @@ if(window.glMatrix) Math3DXYZToVec3.prototype.onExecute = function() { var x = this.getInputData(0); - if(x == null) x = 0; + if(x == null) x = this.properties.x; var y = this.getInputData(1); - if(y == null) y = 0; + if(y == null) y = this.properties.y; var z = this.getInputData(2); - if(z == null) z = 0; + if(z == null) z = this.properties.z; this.setOutputData( 0, vec3.fromValues(x,y,z) ); }