mirror of
https://git.datalinker.icu/kijai/ComfyUI-KJNodes.git
synced 2025-12-09 12:54:40 +08:00
First commit
Most stuff probably still buggy
This commit is contained in:
commit
76d32c9822
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
__pycache__
|
||||
/venv
|
||||
.vscode
|
||||
*.ckpt
|
||||
*.safetensors
|
||||
*.pth
|
||||
7
README.md
Normal file
7
README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# KJNodes for ComfyUI
|
||||
|
||||
Various quality of life -nodes for ComfyUI, mostly just visual stuff to improve usability.
|
||||
|
||||
# Installation
|
||||
|
||||
1. Clone this repo into `custom_nodes` folder.
|
||||
4
__init__.py
Normal file
4
__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
from .nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
|
||||
|
||||
WEB_DIRECTORY = "./web"
|
||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
|
||||
BIN
favicon-active.ico
Normal file
BIN
favicon-active.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1006 B |
110
nodes.py
Normal file
110
nodes.py
Normal file
@ -0,0 +1,110 @@
|
||||
import nodes
|
||||
|
||||
class INTConstant:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {
|
||||
"value": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
RETURN_NAMES = ("value",)
|
||||
FUNCTION = "get_value"
|
||||
|
||||
CATEGORY = "KJNodes"
|
||||
|
||||
def get_value(self, value):
|
||||
return (value,)
|
||||
|
||||
class ConditioningMultiCombine:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {
|
||||
"conditioning_1": ("CONDITIONING", ),
|
||||
"conditioning_2": ("CONDITIONING", ),
|
||||
}}
|
||||
|
||||
RETURN_TYPES = ("CONDITIONING",)
|
||||
FUNCTION = "combine"
|
||||
CATEGORY = "KJNodes"
|
||||
|
||||
def combine(self, combine, **kwargs):
|
||||
cond_combine_node = nodes.ConditioningCombine()
|
||||
cond = kwargs["c1"]
|
||||
for c in range(1, combine):
|
||||
new_cond = kwargs[f"c{c + 1}"]
|
||||
cond = cond_combine_node.combine(new_cond, cond)[0]
|
||||
return (cond,)
|
||||
|
||||
class ConditioningSetMaskAndCombine:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"positive_1": ("CONDITIONING", ),
|
||||
"negative_1": ("CONDITIONING", ),
|
||||
"positive_2": ("CONDITIONING", ),
|
||||
"negative_2": ("CONDITIONING", ),
|
||||
"mask_1": ("MASK", ),
|
||||
"mask_2": ("MASK", ),
|
||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||
"set_cond_area": (["default", "mask bounds"],),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("CONDITIONING","CONDITIONING",)
|
||||
RETURN_NAMES = ("combined_positive", "combined_negative",)
|
||||
FUNCTION = "append"
|
||||
CATEGORY = "KJNodes"
|
||||
|
||||
def append(self, positive_1, negative_1, positive_2, negative_2, mask_1, mask_2, set_cond_area, strength):
|
||||
c = []
|
||||
c2 = []
|
||||
set_area_to_bounds = False
|
||||
if set_cond_area != "default":
|
||||
set_area_to_bounds = True
|
||||
if len(mask_1.shape) < 3:
|
||||
mask_1 = mask_1.unsqueeze(0)
|
||||
if len(mask_2.shape) < 3:
|
||||
mask_2 = mask_2.unsqueeze(0)
|
||||
for t in positive_1:
|
||||
n = [t[0], t[1].copy()]
|
||||
_, h, w = mask_1.shape
|
||||
n[1]['mask'] = mask_1
|
||||
n[1]['set_area_to_bounds'] = set_area_to_bounds
|
||||
n[1]['mask_strength'] = strength
|
||||
c.append(n)
|
||||
for t in positive_2:
|
||||
n = [t[0], t[1].copy()]
|
||||
_, h, w = mask_2.shape
|
||||
n[1]['mask'] = mask_2
|
||||
n[1]['set_area_to_bounds'] = set_area_to_bounds
|
||||
n[1]['mask_strength'] = strength
|
||||
c.append(n)
|
||||
for t in negative_1:
|
||||
n = [t[0], t[1].copy()]
|
||||
_, h, w = mask_1.shape
|
||||
n[1]['mask'] = mask_1
|
||||
n[1]['set_area_to_bounds'] = set_area_to_bounds
|
||||
n[1]['mask_strength'] = strength
|
||||
c2.append(n)
|
||||
for t in negative_2:
|
||||
n = [t[0], t[1].copy()]
|
||||
_, h, w = mask_2.shape
|
||||
n[1]['mask'] = mask_2
|
||||
n[1]['set_area_to_bounds'] = set_area_to_bounds
|
||||
n[1]['mask_strength'] = strength
|
||||
c2.append(n)
|
||||
return (c, c2)
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"INTConstant": INTConstant,
|
||||
"ConditioningMultiCombine": ConditioningMultiCombine,
|
||||
"ConditioningSetMaskAndCombine": ConditioningSetMaskAndCombine,
|
||||
}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"INTConstant": "INT Constant",
|
||||
"ConditioningMultiCombine": "Conditioning Multi Combine",
|
||||
"ConditioningSetMaskAndCombine": "ConditioningSetMaskAndCombine",
|
||||
}
|
||||
BIN
web/green.png
Normal file
BIN
web/green.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
22
web/js/appearance.js
Normal file
22
web/js/appearance.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
|
||||
app.registerExtension({
|
||||
name: "KJNodes.appearance",
|
||||
nodeCreated(node) {
|
||||
const title = node.getTitle();
|
||||
switch (title) {
|
||||
case "INT Constant":
|
||||
node.setSize([200, 58]);
|
||||
node.color = LGraphCanvas.node_colors.green.color;
|
||||
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
|
||||
break;
|
||||
case "ConditioningMultiCombine":
|
||||
|
||||
node.color = LGraphCanvas.node_colors.brown.color;
|
||||
node.bgcolor = LGraphCanvas.node_colors.brown.bgcolor;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
41
web/js/browserstatus.js
Normal file
41
web/js/browserstatus.js
Normal file
@ -0,0 +1,41 @@
|
||||
import { api } from "../../../scripts/api.js";
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "KJNodes.browserstatus",
|
||||
setup() {
|
||||
api.addEventListener("status", ({ detail }) => {
|
||||
let title = "ComfyUI";
|
||||
let favicon = "green";
|
||||
let queueRemaining = detail && detail.exec_info.queue_remaining;
|
||||
|
||||
if (queueRemaining) {
|
||||
favicon = "red";
|
||||
|
||||
title = `00% - ${queueRemaining} | ${title}`;
|
||||
}
|
||||
let link = document.querySelector("link[rel~='icon']");
|
||||
if (!link) {
|
||||
link = document.createElement("link");
|
||||
link.rel = "icon";
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
link.href = new URL(`../${favicon}.png`, import.meta.url);
|
||||
document.title = title;
|
||||
|
||||
});
|
||||
//add progress to the title
|
||||
api.addEventListener("progress", ({ detail }) => {
|
||||
const { value, max } = detail;
|
||||
const progress = Math.floor((value / max) * 100);
|
||||
let title = document.title;
|
||||
|
||||
if (!isNaN(progress) && progress >= 0 && progress <= 100) {
|
||||
const paddedProgress = String(progress).padStart(2, '0');
|
||||
title = `${paddedProgress}% ${title.replace(/^\d+%\s/, '')}`;
|
||||
}
|
||||
|
||||
document.title = title;
|
||||
});
|
||||
},
|
||||
});
|
||||
30
web/js/jsnodes.js
Normal file
30
web/js/jsnodes.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "KJNodes.ConditioningMultiCombine",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
switch (nodeData.name) {
|
||||
case "ConditioningMultiCombine":
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
this.inputs_offset = nodeData.name.includes("selective")?1:0
|
||||
this.cond_type = "CONDITIONING"
|
||||
this.addWidget("button", "Add", null, () => {
|
||||
if (!this.inputs) {
|
||||
this.inputs = [];
|
||||
}
|
||||
if (this.inputs.length < 20) {
|
||||
const newInputName = `conditioning_${this.inputs.length + 1}`;
|
||||
this.addInput(newInputName, this.cond_type);
|
||||
}
|
||||
});
|
||||
this.addWidget("button", "Remove", null, () => {
|
||||
if (this.inputs.length > 2) {
|
||||
const lastInputIndex = this.inputs.length - 1;
|
||||
this.removeInput(lastInputIndex);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
397
web/js/setgetnodes.js
Normal file
397
web/js/setgetnodes.js
Normal file
@ -0,0 +1,397 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
import { ComfyWidgets } from '../../../scripts/widgets.js';
|
||||
//based on diffus3's SetGet: https://github.com/diffus3/ComfyUI-extensions
|
||||
|
||||
// Nodes that allow you to tunnel connections for cleaner graphs
|
||||
app.registerExtension({
|
||||
name: "SetNode",
|
||||
registerCustomNodes() {
|
||||
class SetNode {
|
||||
defaultVisibility = true;
|
||||
serialize_widgets = true;
|
||||
constructor() {
|
||||
if (!this.properties) {
|
||||
this.properties = {
|
||||
"previousName": ""
|
||||
};
|
||||
}
|
||||
this.properties.showOutputText = SetNode.defaultVisibility;
|
||||
|
||||
const node = this;
|
||||
|
||||
|
||||
this.addWidget(
|
||||
"text",
|
||||
"Constant",
|
||||
'',
|
||||
(s, t, u, v, x) => {
|
||||
node.validateName(node.graph);
|
||||
this.update();
|
||||
this.properties.previousName = this.widgets[0].value;
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
this.addInput("*", "*");
|
||||
this.addOutput("*", '*');
|
||||
|
||||
|
||||
this.onConnectionsChange = function(
|
||||
slotType, //1 = input, 2 = output
|
||||
slot,
|
||||
isChangeConnect,
|
||||
link_info,
|
||||
output
|
||||
) {
|
||||
//On Disconnect
|
||||
if (slotType == 1 && !isChangeConnect) {
|
||||
this.inputs[slot].type = '*';
|
||||
this.inputs[slot].name = '*';
|
||||
this.title = "Set"
|
||||
}
|
||||
if (slotType == 2 && !isChangeConnect) {
|
||||
this.outputs[slot].type = '*';
|
||||
this.outputs[slot].name = '*';
|
||||
}
|
||||
//On Connect
|
||||
if (link_info && node.graph && slotType == 1 && isChangeConnect) {
|
||||
|
||||
const fromNode = node.graph._nodes.find((otherNode) => otherNode.id == link_info.origin_id);
|
||||
const type = fromNode.outputs[link_info.origin_slot].type;
|
||||
this.title = "Set_" + type;
|
||||
if (this.widgets[0].value == ''){
|
||||
this.widgets[0].value = type
|
||||
}
|
||||
|
||||
this.validateName(node.graph);
|
||||
this.inputs[0].type = type;
|
||||
this.inputs[0].name = type;
|
||||
|
||||
switch (type) {
|
||||
case "MODEL":
|
||||
this.color = LGraphCanvas.node_colors.blue.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.blue.bgcolor;
|
||||
break;
|
||||
case "LATENT":
|
||||
this.color = LGraphCanvas.node_colors.purple.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.purple.bgcolor;
|
||||
break;
|
||||
case "VAE":
|
||||
this.color = LGraphCanvas.node_colors.red.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.red.bgcolor;
|
||||
break;
|
||||
case "CONDITIONING":
|
||||
this.color = LGraphCanvas.node_colors.brown.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.brown.bgcolor;
|
||||
break;
|
||||
case "IMAGE":
|
||||
this.color = LGraphCanvas.node_colors.pale_blue.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.pale_blue.bgcolor;
|
||||
break;
|
||||
case "CLIP":
|
||||
this.color = LGraphCanvas.node_colors.yellow.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.yellow.bgcolor;
|
||||
break;
|
||||
case "INT":
|
||||
this.color = LGraphCanvas.node_colors.green.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (link_info && node.graph && slotType == 2 && isChangeConnect) {
|
||||
const fromNode = node.graph._nodes.find((otherNode) => otherNode.id == link_info.origin_id);
|
||||
const type = fromNode.inputs[link_info.origin_slot].type;
|
||||
|
||||
this.outputs[0].type = type;
|
||||
this.outputs[0].name = type;
|
||||
}
|
||||
|
||||
|
||||
//Update either way
|
||||
this.update();
|
||||
}
|
||||
|
||||
this.validateName = function(graph) {
|
||||
let widgetValue = node.widgets[0].value;
|
||||
|
||||
if (widgetValue != '') {
|
||||
let tries = 0;
|
||||
let collisions = [];
|
||||
|
||||
do {
|
||||
collisions = graph._nodes.filter((otherNode) => {
|
||||
if (otherNode == this) {
|
||||
return false;
|
||||
}
|
||||
if (otherNode.type == 'SetNode' && otherNode.widgets[0].value === widgetValue) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
if (collisions.length > 0) {
|
||||
widgetValue = node.widgets[0].value + "_" + tries;
|
||||
}
|
||||
tries++;
|
||||
} while (collisions.length > 0)
|
||||
node.widgets[0].value = widgetValue;
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
this.clone = function () {
|
||||
console.log("CLONE");
|
||||
const cloned = SetNode.prototype.clone.apply(this);
|
||||
cloned.inputs[0].name = '*';
|
||||
cloned.inputs[0].type = '*';
|
||||
cloned.value = '';
|
||||
cloned.properties.previousName = '';
|
||||
cloned.size = cloned.computeSize();
|
||||
return cloned;
|
||||
};
|
||||
|
||||
this.onAdded = function(graph) {
|
||||
this.validateName(graph);
|
||||
}
|
||||
|
||||
|
||||
this.update = function() {
|
||||
if (node.graph) {
|
||||
this.findGetters(node.graph).forEach((getter) => {
|
||||
getter.setType(this.inputs[0].type);
|
||||
});
|
||||
if (this.widgets[0].value) {
|
||||
this.findGetters(node.graph, true).forEach((getter) => {
|
||||
getter.setName(this.widgets[0].value)
|
||||
});
|
||||
}
|
||||
|
||||
const allGetters = node.graph._nodes.filter((otherNode) => otherNode.type == "GetNode");
|
||||
allGetters.forEach((otherNode) => {
|
||||
if (otherNode.setComboValues) {
|
||||
otherNode.setComboValues();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.findGetters = function(graph, checkForPreviousName) {
|
||||
const name = checkForPreviousName ? this.properties.previousName : this.widgets[0].value;
|
||||
return graph._nodes.filter((otherNode) => {
|
||||
if (otherNode.type == 'GetNode' && otherNode.widgets[0].value === name && name != '') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// This node is purely frontend and does not impact the resulting prompt so should not be serialized
|
||||
this.isVirtualNode = true;
|
||||
}
|
||||
|
||||
onRemoved() {
|
||||
console.log("onRemove");
|
||||
console.log(this);
|
||||
console.log(this.flags);
|
||||
const allGetters = this.graph._nodes.filter((otherNode) => otherNode.type == "GetNode");
|
||||
allGetters.forEach((otherNode) => {
|
||||
if (otherNode.setComboValues) {
|
||||
otherNode.setComboValues([this]);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LiteGraph.registerNodeType(
|
||||
"SetNode",
|
||||
Object.assign(SetNode, {
|
||||
title: "Set",
|
||||
})
|
||||
);
|
||||
|
||||
SetNode.category = "KJNodes";
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
app.registerExtension({
|
||||
name: "GetNode",
|
||||
registerCustomNodes() {
|
||||
class GetNode {
|
||||
|
||||
defaultVisibility = true;
|
||||
serialize_widgets = true;
|
||||
|
||||
constructor() {
|
||||
if (!this.properties) {
|
||||
this.properties = {};
|
||||
}
|
||||
this.properties.showOutputText = GetNode.defaultVisibility;
|
||||
|
||||
const node = this;
|
||||
this.addWidget(
|
||||
"combo",
|
||||
"Constant",
|
||||
"",
|
||||
(e) => {
|
||||
this.onRename();
|
||||
},
|
||||
{
|
||||
values: () => {
|
||||
const setterNodes = graph._nodes.filter((otherNode) => otherNode.type == 'SetNode');
|
||||
return setterNodes.map((otherNode) => otherNode.widgets[0].value).sort();
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
this.addOutput("*", '*');
|
||||
|
||||
|
||||
this.onConnectionsChange = function(
|
||||
slotType, //0 = output, 1 = input
|
||||
slot, //self-explanatory
|
||||
isChangeConnect,
|
||||
link_info,
|
||||
output
|
||||
) {
|
||||
this.validateLinks();
|
||||
}
|
||||
|
||||
|
||||
this.setName = function(name) {
|
||||
console.log("renaming getter: ");
|
||||
console.log(node.widgets[0].value + " -> " + name);
|
||||
node.widgets[0].value = name;
|
||||
node.onRename();
|
||||
node.serialize();
|
||||
|
||||
}
|
||||
|
||||
|
||||
this.onRename = function() {
|
||||
console.log("onRename");
|
||||
|
||||
const setter = this.findSetter(node.graph);
|
||||
if (setter) {
|
||||
let linkType = (setter.inputs[0].type);
|
||||
|
||||
this.setType(linkType);
|
||||
this.title = "Get_" + setter.inputs[0].type;
|
||||
|
||||
switch (linkType) {
|
||||
case "MODEL":
|
||||
this.color = LGraphCanvas.node_colors.blue.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.blue.bgcolor;
|
||||
break;
|
||||
case "LATENT":
|
||||
this.color = LGraphCanvas.node_colors.purple.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.purple.bgcolor;
|
||||
break;
|
||||
case "VAE":
|
||||
this.color = LGraphCanvas.node_colors.red.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.red.bgcolor;
|
||||
break;
|
||||
case "CONDITIONING":
|
||||
this.color = LGraphCanvas.node_colors.brown.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.brown.bgcolor;
|
||||
break;
|
||||
case "IMAGE":
|
||||
this.color = LGraphCanvas.node_colors.pale_blue.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.pale_blue.bgcolor;
|
||||
break;
|
||||
case "CLIP":
|
||||
this.color = LGraphCanvas.node_colors.yellow.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.yellow.bgcolor;
|
||||
break;
|
||||
case "INT":
|
||||
this.color = LGraphCanvas.node_colors.green.color;
|
||||
this.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
this.setType('*');
|
||||
}
|
||||
}
|
||||
|
||||
this.clone = function () {
|
||||
const cloned = GetNode.prototype.clone.apply(this);
|
||||
cloned.size = cloned.computeSize();
|
||||
return cloned;
|
||||
};
|
||||
|
||||
this.validateLinks = function() {
|
||||
console.log("validating links");
|
||||
if (this.outputs[0].type != '*' && this.outputs[0].links) {
|
||||
console.log("in");
|
||||
this.outputs[0].links.forEach((linkId) => {
|
||||
const link = node.graph.links[linkId];
|
||||
if (link && link.type != this.outputs[0].type && link.type != '*') {
|
||||
console.log("removing link");
|
||||
node.graph.removeLink(linkId)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.setType = function(type) {
|
||||
this.outputs[0].name = type;
|
||||
this.outputs[0].type = type;
|
||||
this.validateLinks();
|
||||
}
|
||||
|
||||
this.findSetter = function(graph) {
|
||||
const name = this.widgets[0].value;
|
||||
return graph._nodes.find((otherNode) => {
|
||||
if (otherNode.type == 'SetNode' && otherNode.widgets[0].value === name && name != '') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
// This node is purely frontend and does not impact the resulting prompt so should not be serialized
|
||||
this.isVirtualNode = true;
|
||||
}
|
||||
|
||||
|
||||
getInputLink(slot) {
|
||||
const setter = this.findSetter(this.graph);
|
||||
|
||||
if (setter) {
|
||||
const slot_info = setter.inputs[slot];
|
||||
console.log("slot info");
|
||||
console.log(slot_info);
|
||||
console.log(this.graph.links);
|
||||
const link = this.graph.links[ slot_info.link ];
|
||||
console.log("link:");
|
||||
console.log(link);
|
||||
return link;
|
||||
} else {
|
||||
console.log(this.widgets[0]);
|
||||
console.log(this.widgets[0].value);
|
||||
throw new Error("No SetNode found for " + this.widgets[0].value + "(" + this.type + ")");
|
||||
}
|
||||
|
||||
}
|
||||
onAdded(graph) {
|
||||
//this.setComboValues();
|
||||
//this.validateName(graph);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
LiteGraph.registerNodeType(
|
||||
"GetNode",
|
||||
Object.assign(GetNode, {
|
||||
title: "Get",
|
||||
})
|
||||
);
|
||||
|
||||
GetNode.category = "KJNodes";
|
||||
},
|
||||
});
|
||||
BIN
web/red.png
Normal file
BIN
web/red.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Loading…
x
Reference in New Issue
Block a user