Merge branch 'comfyanonymous:master' into image-to-mask

This commit is contained in:
missionfloyd 2023-04-13 03:07:08 -06:00 committed by GitHub
commit 45b907fbf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 314 additions and 132 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ temp/
custom_nodes/
!custom_nodes/example_node.py.example
extra_model_paths.yaml
/.vs

View File

@ -35,6 +35,11 @@ Workflow examples can be found on the [Examples page](https://comfyanonymous.git
- **Ctrl + A** select all nodes
- **Ctrl + M** mute/unmute selected nodes
- **Delete** or **Backspace** delete selected nodes
- **Space** Holding space key while moving the cursor moves the canvas around. It works when holding the mouse button down so it is easier to connect different nodes when the canvas gets too large.
- **Ctrl/Shift + Click** Add clicked node to selection.
- **Ctrl + C/Ctrl + V** - Copy and paste selected nodes, without maintaining the connection to the outputs of unselected nodes.
- **Ctrl + C/Ctrl + Shift + V** - Copy and paste selected nodes, and maintaining the connection from the outputs of unselected nodes to the inputs of the newly pasted nodes.
- Holding **Shift** and drag selected nodes - Move multiple selected nodes at the same time.
# Installing
@ -92,6 +97,11 @@ Install the dependencies by opening your terminal inside the ComfyUI folder and:
After this you should have everything installed and can proceed to running ComfyUI.
### Others:
[Intel Arc](https://github.com/comfyanonymous/ComfyUI/discussions/476)
Mac/MPS: There is basic support in the code but until someone makes some install instruction you are on your own.
### I already have another UI for Stable Diffusion installed do I really have to install all of these dependencies?

View File

@ -940,6 +940,8 @@ class LoadImageMask:
input_dir = folder_paths.get_input_directory()
image_path = os.path.join(input_dir, image)
i = Image.open(image_path)
if i.getbands() != ("R", "G", "B", "A"):
i = i.convert("RGBA")
mask = None
c = channel[0].upper()
if c in i.getbands():

View File

@ -5,9 +5,9 @@ import { api } from "/scripts/api.js";
// Manage color palettes
const colorPalettes = {
"palette_1": {
"id": "palette_1",
"name": "Palette 1",
"dark": {
"id": "dark",
"name": "Dark (Default)",
"colors": {
"node_slot": {
"CLIP": "#FFD500", // bright yellow
@ -45,6 +45,70 @@ const colorPalettes = {
"EVENT_LINK_COLOR": "#A86",
"CONNECTING_LINK_COLOR": "#AFA",
},
"comfy_base": {
"fg-color": "#fff",
"bg-color": "#202020",
"comfy-menu-bg": "#353535",
"comfy-input-bg": "#222",
"input-text": "#ddd",
"descrip-text": "#999",
"drag-text": "#ccc",
"error-text": "#ff4444",
"border-color": "#4e4e4e"
}
},
},
"light": {
"id": "light",
"name": "Light",
"colors": {
"node_slot": {
"CLIP": "#FFA726", // orange
"CLIP_VISION": "#5C6BC0", // indigo
"CLIP_VISION_OUTPUT": "#8D6E63", // brown
"CONDITIONING": "#EF5350", // red
"CONTROL_NET": "#66BB6A", // green
"IMAGE": "#42A5F5", // blue
"LATENT": "#AB47BC", // purple
"MASK": "#9CCC65", // light green
"MODEL": "#7E57C2", // deep purple
"STYLE_MODEL": "#D4E157", // lime
"VAE": "#FF7043", // deep orange
},
"litegraph_base": {
"NODE_TITLE_COLOR": "#222",
"NODE_SELECTED_TITLE_COLOR": "#000",
"NODE_TEXT_SIZE": 14,
"NODE_TEXT_COLOR": "#444",
"NODE_SUBTEXT_SIZE": 12,
"NODE_DEFAULT_COLOR": "#F7F7F7",
"NODE_DEFAULT_BGCOLOR": "#F5F5F5",
"NODE_DEFAULT_BOXCOLOR": "#CCC",
"NODE_DEFAULT_SHAPE": "box",
"NODE_BOX_OUTLINE_COLOR": "#000",
"DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.1)",
"DEFAULT_GROUP_FONT": 24,
"WIDGET_BGCOLOR": "#D4D4D4",
"WIDGET_OUTLINE_COLOR": "#999",
"WIDGET_TEXT_COLOR": "#222",
"WIDGET_SECONDARY_TEXT_COLOR": "#555",
"LINK_COLOR": "#4CAF50",
"EVENT_LINK_COLOR": "#FF9800",
"CONNECTING_LINK_COLOR": "#2196F3",
},
"comfy_base": {
"fg-color": "#222",
"bg-color": "#DDD",
"comfy-menu-bg": "#F5F5F5",
"comfy-input-bg": "#C9C9C9",
"input-text": "#222",
"descrip-text": "#444",
"drag-text": "#555",
"error-text": "#F44336",
"border-color": "#CCC"
}
},
},
"solarized": {
@ -52,49 +116,60 @@ const colorPalettes = {
"name": "Solarized",
"colors": {
"node_slot": {
"CLIP": "#859900", // Green
"CLIP_VISION": "#6c71c4", // Indigo
"CLIP_VISION_OUTPUT": "#859900", // Green
"CONDITIONING": "#d33682", // Magenta
"CONTROL_NET": "#cb4b16", // Orange
"IMAGE": "#dc322f", // Red
"LATENT": "#268bd2", // Blue
"MASK": "#073642", // Base02
"MODEL": "#cb4b16", // Orange
"STYLE_MODEL": "#073642", // Base02
"UPSCALE_MODEL": "#6c71c4", // Indigo
"VAE": "#586e75", // Base1
"CLIP": "#2AB7CA", // light blue
"CLIP_VISION": "#6c71c4", // blue violet
"CLIP_VISION_OUTPUT": "#859900", // olive green
"CONDITIONING": "#d33682", // magenta
"CONTROL_NET": "#d1ffd7", // light mint green
"IMAGE": "#5940bb", // deep blue violet
"LATENT": "#268bd2", // blue
"MASK": "#CCC9E7", // light purple-gray
"MODEL": "#dc322f", // red
"STYLE_MODEL": "#1a998a", // teal
"UPSCALE_MODEL": "#054A29", // dark green
"VAE": "#facfad", // light pink-orange
},
"litegraph_base": {
"NODE_TITLE_COLOR": "#fdf6e3",
"NODE_SELECTED_TITLE_COLOR": "#b58900",
"NODE_TITLE_COLOR": "#fdf6e3", // Base3
"NODE_SELECTED_TITLE_COLOR": "#A9D400",
"NODE_TEXT_SIZE": 14,
"NODE_TEXT_COLOR": "#657b83",
"NODE_TEXT_COLOR": "#657b83", // Base00
"NODE_SUBTEXT_SIZE": 12,
"NODE_DEFAULT_COLOR": "#586e75",
"NODE_DEFAULT_BGCOLOR": "#073642",
"NODE_DEFAULT_BOXCOLOR": "#839496",
"NODE_DEFAULT_COLOR": "#094656",
"NODE_DEFAULT_BGCOLOR": "#073642", // Base02
"NODE_DEFAULT_BOXCOLOR": "#839496", // Base0
"NODE_DEFAULT_SHAPE": "box",
"NODE_BOX_OUTLINE_COLOR": "#fdf6e3",
"NODE_BOX_OUTLINE_COLOR": "#fdf6e3", // Base3
"DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)",
"DEFAULT_GROUP_FONT": 24,
"WIDGET_BGCOLOR": "#002b36",
"WIDGET_OUTLINE_COLOR": "#839496",
"WIDGET_TEXT_COLOR": "#fdf6e3",
"WIDGET_SECONDARY_TEXT_COLOR": "#93a1a1",
"WIDGET_BGCOLOR": "#002b36", // Base03
"WIDGET_OUTLINE_COLOR": "#839496", // Base0
"WIDGET_TEXT_COLOR": "#fdf6e3", // Base3
"WIDGET_SECONDARY_TEXT_COLOR": "#93a1a1", // Base1
"LINK_COLOR": "#2aa198",
"EVENT_LINK_COLOR": "#268bd2",
"CONNECTING_LINK_COLOR": "#859900",
"LINK_COLOR": "#2aa198", // Solarized Cyan
"EVENT_LINK_COLOR": "#268bd2", // Solarized Blue
"CONNECTING_LINK_COLOR": "#859900", // Solarized Green
},
"comfy_base": {
"fg-color": "#fdf6e3", // Base3
"bg-color": "#002b36", // Base03
"comfy-menu-bg": "#073642", // Base02
"comfy-input-bg": "#002b36", // Base03
"input-text": "#93a1a1", // Base1
"descrip-text": "#586e75", // Base01
"drag-text": "#839496", // Base0
"error-text": "#dc322f", // Solarized Red
"border-color": "#657b83" // Base00
}
},
}
};
const id = "Comfy.ColorPalette";
const idCustomColorPalettes = "Comfy.CustomColorPalettes";
const defaultColorPaletteId = "palette_1";
const defaultColorPaletteId = "dark";
const els = {}
// const ctxMenu = LiteGraph.ContextMenu;
app.registerExtension({
@ -236,10 +311,12 @@ app.registerExtension({
const loadColorPalette = async (colorPalette) => {
colorPalette = await completeColorPalette(colorPalette);
if (colorPalette.colors) {
// Sets the colors of node slots and links
if (colorPalette.colors.node_slot) {
Object.assign(app.canvas.default_connection_color_byType, colorPalette.colors.node_slot);
Object.assign(LGraphCanvas.link_type_colors, colorPalette.colors.node_slot);
}
// Sets the colors of the LiteGraph objects
if (colorPalette.colors.litegraph_base) {
// Everything updates correctly in the loop, except the Node Title and Link Color for some reason
app.canvas.node_title_color = colorPalette.colors.litegraph_base.NODE_TITLE_COLOR;
@ -251,6 +328,13 @@ app.registerExtension({
}
}
}
// Sets the color of ComfyUI elements
if (colorPalette.colors.comfy_base) {
const rootStyle = document.documentElement.style;
for (const key in colorPalette.colors.comfy_base) {
rootStyle.setProperty('--' + key, colorPalette.colors.comfy_base[key]);
}
}
app.canvas.draw(true, true);
}
};

View File

@ -90,7 +90,7 @@ app.registerExtension({
const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
if (!this.properties || !("Node name for S&R" in this.properties)) {
this.addProperty("Node name for S&R", this.title, "string");
this.addProperty("Node name for S&R", this.constructor.type, "string");
}
return r;

View File

@ -1,4 +1,4 @@
import { ComfyWidgets, addRandomizeWidget } from "/scripts/widgets.js";
import { ComfyWidgets, addValueControlWidget } from "/scripts/widgets.js";
import { app } from "/scripts/app.js";
const CONVERTED_TYPE = "converted-widget";
@ -23,7 +23,7 @@ function hideWidget(node, widget, suffix = "") {
return widget.origSerializeValue ? widget.origSerializeValue() : widget.value;
};
// Hide any linked widgets, e.g. seed+randomize
// Hide any linked widgets, e.g. seed+seedControl
if (widget.linkedWidgets) {
for (const w of widget.linkedWidgets) {
hideWidget(node, w, ":" + widget.name);
@ -40,7 +40,7 @@ function showWidget(widget) {
delete widget.origComputeSize;
delete widget.origSerializeValue;
// Hide any linked widgets, e.g. seed+randomize
// Hide any linked widgets, e.g. seed+seedControl
if (widget.linkedWidgets) {
for (const w of widget.linkedWidgets) {
showWidget(w);
@ -285,7 +285,7 @@ app.registerExtension({
}
if (widget.type === "number") {
addRandomizeWidget(this, widget, "Random after every gen");
addValueControlWidget(this, widget, "fixed");
}
// When our value changes, update other widgets to reflect our changes

View File

@ -142,6 +142,8 @@
pointerevents_method: "pointer", // "mouse"|"pointer" use mouse for retrocompatibility issues? (none found @ now)
// TODO implement pointercancel, gotpointercapture, lostpointercapture, (pointerover, pointerout if necessary)
ctrl_shift_v_paste_connect_unselected_outputs: true, //[true!] allows ctrl + shift + v to paste nodes with the outputs of the unselected nodes connected with the inputs of the newly pasted nodes
/**
* Register a node class so it can be listed when the user wants to create a new one
* @method registerNodeType
@ -253,12 +255,17 @@
* @param {String|Object} type name of the node or the node constructor itself
*/
unregisterNodeType: function(type) {
var base_class = type.constructor === String ? this.registered_node_types[type] : type;
if(!base_class)
throw("node type not found: " + type );
const base_class =
type.constructor === String
? this.registered_node_types[type]
: type;
if (!base_class) {
throw "node type not found: " + type;
}
delete this.registered_node_types[base_class.type];
if(base_class.constructor.name)
if (base_class.constructor.name) {
delete this.Nodes[base_class.constructor.name];
}
},
/**
@ -269,36 +276,47 @@
*/
registerNodeAndSlotType: function(type, slot_type, out){
out = out || false;
var base_class = type.constructor === String && this.registered_node_types[type] !== "anonymous" ? this.registered_node_types[type] : type;
const base_class =
type.constructor === String &&
this.registered_node_types[type] !== "anonymous"
? this.registered_node_types[type]
: type;
var sCN = base_class.constructor.type;
const class_type = base_class.constructor.type;
if (typeof slot_type == "string"){
var aTypes = slot_type.split(",");
let allTypes = [];
if (typeof slot_type === "string") {
allTypes = slot_type.split(",");
} else if (slot_type == this.EVENT || slot_type == this.ACTION) {
var aTypes = ["_event_"];
allTypes = ["_event_"];
} else {
var aTypes = ["*"];
allTypes = ["*"];
}
for (var i = 0; i < aTypes.length; ++i) {
var sT = aTypes[i]; //.toLowerCase();
if (sT === ""){
sT = "*";
for (let i = 0; i < allTypes.length; ++i) {
let slotType = allTypes[i];
if (slotType === "") {
slotType = "*";
}
const registerTo = out
? "registered_slot_out_types"
: "registered_slot_in_types";
if (this[registerTo][slotType] === undefined) {
this[registerTo][slotType] = { nodes: [] };
}
if (!this[registerTo][slotType].nodes.includes(class_type)) {
this[registerTo][slotType].nodes.push(class_type);
}
var registerTo = out ? "registered_slot_out_types" : "registered_slot_in_types";
if (typeof this[registerTo][sT] == "undefined") this[registerTo][sT] = {nodes: []};
this[registerTo][sT].nodes.push(sCN);
// check if is a new type
if (!out) {
if (!this.slot_types_in.includes(sT.toLowerCase())){
this.slot_types_in.push(sT.toLowerCase());
if (!this.slot_types_in.includes(slotType.toLowerCase())) {
this.slot_types_in.push(slotType.toLowerCase());
this.slot_types_in.sort();
}
} else {
if (!this.slot_types_out.includes(sT.toLowerCase())){
this.slot_types_out.push(sT.toLowerCase());
if (!this.slot_types_out.includes(slotType.toLowerCase())) {
this.slot_types_out.push(slotType.toLowerCase());
this.slot_types_out.sort();
}
}
@ -1616,7 +1634,8 @@
var nRet = null;
for (var i = nodes_list.length - 1; i >= 0; i--) {
var n = nodes_list[i];
if (n.isPointInside(x, y, margin)) {
var skip_title = n.constructor.title_mode == LiteGraph.NO_TITLE;
if (n.isPointInside(x, y, margin, skip_title)) {
// check for lesser interest nodes (TODO check for overlapping, use the top)
/*if (typeof n == "LGraphGroup"){
nRet = n;
@ -3967,8 +3986,8 @@
var aSource = (type+"").toLowerCase().split(",");
var aDest = aSlots[i].type=="0"||aSlots[i].type=="*"?"0":aSlots[i].type;
aDest = (aDest+"").toLowerCase().split(",");
for(sI=0;sI<aSource.length;sI++){
for(dI=0;dI<aDest.length;dI++){
for(var sI=0;sI<aSource.length;sI++){
for(var dI=0;dI<aDest.length;dI++){
if (aSource[sI]=="_event_") aSource[sI] = LiteGraph.EVENT;
if (aDest[sI]=="_event_") aDest[sI] = LiteGraph.EVENT;
if (aSource[sI]=="*") aSource[sI] = 0;
@ -3987,8 +4006,8 @@
var aSource = (type+"").toLowerCase().split(",");
var aDest = aSlots[i].type=="0"||aSlots[i].type=="*"?"0":aSlots[i].type;
aDest = (aDest+"").toLowerCase().split(",");
for(sI=0;sI<aSource.length;sI++){
for(dI=0;dI<aDest.length;dI++){
for(var sI=0;sI<aSource.length;sI++){
for(var dI=0;dI<aDest.length;dI++){
if (aSource[sI]=="*") aSource[sI] = 0;
if (aDest[sI]=="*") aDest[sI] = 0;
if (aSource[sI] == aDest[dI]) {
@ -4019,7 +4038,7 @@
if (target_node && target_node.constructor === Number) {
target_node = this.graph.getNodeById(target_node);
}
target_slot = target_node.findInputSlotByType(target_slotType, false, true);
var target_slot = target_node.findInputSlotByType(target_slotType, false, true);
if (target_slot >= 0 && target_slot !== null){
//console.debug("CONNbyTYPE type "+target_slotType+" for "+target_slot)
return this.connect(slot, target_node, target_slot);
@ -4072,7 +4091,7 @@
if (source_node && source_node.constructor === Number) {
source_node = this.graph.getNodeById(source_node);
}
source_slot = source_node.findOutputSlotByType(source_slotType, false, true);
var source_slot = source_node.findOutputSlotByType(source_slotType, false, true);
if (source_slot >= 0 && source_slot !== null){
//console.debug("CONNbyTYPE OUT! type "+source_slotType+" for "+source_slot)
return source_node.connect(source_slot, this, slot);
@ -5184,6 +5203,7 @@ LGraphNode.prototype.executeAction = function(action)
this.editor_alpha = 1; //used for transition
this.pause_rendering = false;
this.clear_background = true;
this.clear_background_color = "#222";
this.read_only = false; //if set to true users cannot modify the graph
this.render_only_selected = true;
@ -6986,7 +7006,7 @@ LGraphNode.prototype.executeAction = function(action)
block_default = true;
}
if (e.code == "KeyC" && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
if ((e.keyCode === 67) && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
//copy
if (this.selected_nodes) {
this.copyToClipboard();
@ -6994,9 +7014,9 @@ LGraphNode.prototype.executeAction = function(action)
}
}
if (e.code == "KeyV" && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
if ((e.keyCode === 86) && (e.metaKey || e.ctrlKey)) {
//paste
this.pasteFromClipboard();
this.pasteFromClipboard(e.shiftKey);
}
//delete or backspace
@ -7081,15 +7101,15 @@ LGraphNode.prototype.executeAction = function(action)
var target_node = this.graph.getNodeById(
link_info.origin_id
);
if (!target_node || !this.selected_nodes[target_node.id]) {
//improve this by allowing connections to non-selected nodes
if (!target_node) {
continue;
} //not selected
}
clipboard_info.links.push([
target_node._relative_id,
link_info.origin_slot, //j,
node._relative_id,
link_info.target_slot
link_info.target_slot,
target_node.id
]);
}
}
@ -7100,7 +7120,11 @@ LGraphNode.prototype.executeAction = function(action)
);
};
LGraphCanvas.prototype.pasteFromClipboard = function() {
LGraphCanvas.prototype.pasteFromClipboard = function(isConnectUnselected = false) {
// if ctrl + shift + v is off, return when isConnectUnselected is true (shift is pressed) to maintain old behavior
if (!LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && isConnectUnselected) {
return;
}
var data = localStorage.getItem("litegrapheditor_clipboard");
if (!data) {
return;
@ -7149,7 +7173,16 @@ LGraphNode.prototype.executeAction = function(action)
//create links
for (var i = 0; i < clipboard_info.links.length; ++i) {
var link_info = clipboard_info.links[i];
var origin_node = nodes[link_info[0]];
var origin_node;
var origin_node_relative_id = link_info[0];
if (origin_node_relative_id != null) {
origin_node = nodes[origin_node_relative_id];
} else if (LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && isConnectUnselected) {
var origin_node_id = link_info[4];
if (origin_node_id) {
origin_node = this.graph.getNodeById(origin_node_id);
}
}
var target_node = nodes[link_info[2]];
if( origin_node && target_node )
origin_node.connect(link_info[1], target_node, link_info[3]);
@ -8212,6 +8245,17 @@ LGraphNode.prototype.executeAction = function(action)
this.ds.toCanvasContext(ctx);
//render BG
if ( this.ds.scale < 1.5 && !bg_already_painted && this.clear_background_color )
{
ctx.fillStyle = this.clear_background_color;
ctx.fillRect(
this.visible_area[0],
this.visible_area[1],
this.visible_area[2],
this.visible_area[3]
);
}
if (
this.background_image &&
this.ds.scale > 0.5 &&
@ -12274,7 +12318,7 @@ LGraphNode.prototype.executeAction = function(action)
var aProps = LiteGraph.availableCanvasOptions;
aProps.sort();
for(pI in aProps){
for(var pI in aProps){
var pX = aProps[pI];
panel.addWidget( "boolean", pX, graphcanvas[pX], {key: pX, on: "True", off: "False"}, fUpdate);
}

View File

@ -362,8 +362,20 @@ class ComfyApp {
if (n && n.onDragDrop && (await n.onDragDrop(event))) {
return;
}
// Dragging from Chrome->Firefox there is a file but its a bmp, so ignore that
if (event.dataTransfer.files.length && event.dataTransfer.files[0].type !== "image/bmp") {
await this.handleFile(event.dataTransfer.files[0]);
} else {
// Try loading the first URI in the transfer list
const validTypes = ["text/uri-list", "text/x-moz-url"];
const match = [...event.dataTransfer.types].find((t) => validTypes.find(v => t === v));
if (match) {
const uri = event.dataTransfer.getData(match)?.split("\n")?.[0];
if (uri) {
await this.handleFile(await (await fetch(uri)).blob());
}
}
}
});
// Always clear over node on drag leave
@ -937,6 +949,11 @@ class ComfyApp {
widget.value = widget.value.slice(7);
}
}
if (widget.name == "control_after_generate") {
if (widget.value == true) {
widget.value = "randomize";
}
}
}
}
}
@ -1090,7 +1107,7 @@ class ComfyApp {
importA1111(this.graph, pngInfo.parameters);
}
}
} else if (file.type === "application/json" || file.name.endsWith(".json")) {
} else if (file.type === "application/json" || file.name?.endsWith(".json")) {
const reader = new FileReader();
reader.onload = () => {
this.loadGraphData(JSON.parse(reader.result));

View File

@ -10,37 +10,54 @@ function getNumberDefaults(inputData, defaultStep) {
return { val: defaultVal, config: { min, max, step: 10.0 * step } };
}
export function addRandomizeWidget(node, targetWidget, name, defaultValue = false) {
const randomize = node.addWidget("toggle", name, defaultValue, function (v) {}, {
on: "enabled",
off: "disabled",
export function addValueControlWidget(node, targetWidget, defaultValue = "randomize", values) {
const valueControl = node.addWidget("combo", "control_after_generate", defaultValue, function (v) { }, {
values: ["fixed", "increment", "decrement", "randomize"],
serialize: false, // Don't include this in prompt.
});
valueControl.afterQueued = () => {
randomize.afterQueued = () => {
if (randomize.value) {
const min = targetWidget.options?.min;
let max = targetWidget.options?.max;
if (min != null || max != null) {
if (max) {
// limit max to something that javascript can handle
var v = valueControl.value;
let min = targetWidget.options.min;
let max = targetWidget.options.max;
// limit to something that javascript can handle
max = Math.min(1125899906842624, max);
min = Math.max(-1125899906842624, min);
let range = (max - min) / (targetWidget.options.step / 10);
//adjust values based on valueControl Behaviour
switch (v) {
case "fixed":
break;
case "increment":
targetWidget.value += targetWidget.options.step / 10;
break;
case "decrement":
targetWidget.value -= targetWidget.options.step / 10;
break;
case "randomize":
targetWidget.value = Math.floor(Math.random() * range) * (targetWidget.options.step / 10) + min;
default:
break;
}
targetWidget.value = Math.floor(Math.random() * ((max ?? 9999999999) - (min ?? 0) + 1) + (min ?? 0));
} else {
targetWidget.value = Math.floor(Math.random() * 1125899906842624);
}
/*check if values are over or under their respective
* ranges and set them to min or max.*/
if (targetWidget.value < min)
targetWidget.value = min;
if (targetWidget.value > max)
targetWidget.value = max;
}
return valueControl;
};
return randomize;
}
function seedWidget(node, inputName, inputData) {
const seed = ComfyWidgets.INT(node, inputName, inputData);
const randomize = addRandomizeWidget(node, seed.widget, "Random seed after every gen", true);
const seedControl = addValueControlWidget(node, seed.widget, "randomize");
seed.widget.linkedWidgets = [randomize];
return { widget: seed, randomize };
seed.widget.linkedWidgets = [seedControl];
return seed;
}
const MultilineSymbol = Symbol();

View File

@ -1,6 +1,13 @@
:root {
--fg-color: #000;
--bg-color: #fff;
--comfy-menu-bg: #353535;
--comfy-input-bg: #222;
--input-text: #ddd;
--descrip-text: #999;
--drag-text: #ccc;
--error-text: #ff4444;
--border-color: #4e4e4e;
}
@media (prefers-color-scheme: dark) {
@ -25,8 +32,8 @@ body {
}
.comfy-multiline-input {
background-color: var(--bg-color);
color: var(--fg-color);
background-color: var(--comfy-input-bg);
color: var(--input-text);
overflow: hidden;
overflow-y: auto;
padding: 2px;
@ -39,8 +46,8 @@ body {
position: fixed; /* Stay in place */
z-index: 100; /* Sit on top */
padding: 30px 30px 10px 30px;
background-color: #353535; /* Modal background */
color: #ff4444;
background-color: var(--comfy-menu-bg); /* Modal background */
color: var(--error-text);
box-shadow: 0px 0px 20px #888888;
border-radius: 10px;
top: 50%;
@ -82,8 +89,8 @@ body {
display: flex;
flex-direction: column;
align-items: center;
color: #999;
background-color: #353535;
color: var(--descrip-text);
background-color: var(--comfy-menu-bg);
font-family: sans-serif;
padding: 10px;
border-radius: 0 8px 8px 8px;
@ -103,7 +110,7 @@ body {
.comfy-menu-btns button {
font-size: 10px;
width: 50%;
color: #999 !important;
color: var(--descrip-text) !important;
}
.comfy-menu > button {
@ -114,10 +121,10 @@ body {
.comfy-menu-btns button,
.comfy-menu .comfy-list button,
.comfy-modal button{
color: #ddd;
background-color: #222;
color: var(--input-text);
background-color: var(--comfy-input-bg);
border-radius: 8px;
border-color: #4e4e4e;
border-color: var(--border-color);
border-style: solid;
margin-top: 2px;
}
@ -136,7 +143,7 @@ body {
font-size: 12px;
font-family: sans-serif;
letter-spacing: 2px;
color: #cccccc;
color: var(--drag-text);
text-shadow: 1px 0 1px black;
position: absolute;
top: 0;
@ -152,7 +159,7 @@ body {
}
.comfy-list {
color: #999;
color: var(--descrip-text);
background-color: #333;
margin-bottom: 10px;
border-color: #4e4e4e;
@ -163,7 +170,7 @@ body {
overflow-y: scroll;
max-height: 100px;
min-height: 25px;
background-color: #222;
background-color: var(--comfy-input-bg);
padding: 5px;
}
@ -206,16 +213,16 @@ button.comfy-queue-btn {
.comfy-modal.comfy-manage-templates {
text-align: center;
font-family: sans-serif;
color: #999;
color: var(--descrip-text);
z-index: 99;
}
.comfy-modal input,
.comfy-modal select {
color: #ddd;
background-color: #222;
color: var(--input-text);
background-color: var(--comfy-input-bg);
border-radius: 8px;
border-color: #4e4e4e;
border-color: var(--border-color);
border-style: solid;
font-size: inherit;
}
@ -240,7 +247,7 @@ button.comfy-queue-btn {
.graphdialog .name {
font-size: 14px;
font-family: sans-serif;
color: #999999;
color: var(--descrip-text);
}
.graphdialog button {
@ -251,10 +258,10 @@ button.comfy-queue-btn {
}
.graphdialog input, .graphdialog textarea, .graphdialog select {
background-color: #222;
background-color: var(--comfy-input-bg);
border: 2px solid;
border-color: #444444;
color: #ddd;
border-color: var(--border-color);
color: var(--input-text);
border-radius: 12px 0 0 12px;
}