diff --git a/web/scripts/app.js b/web/scripts/app.js index 609cc4cf7..f0869d2a1 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -90,7 +90,10 @@ class ComfyApp { callback: () => { const a = document.createElement("a"); a.href = img.src; - a.setAttribute("download", new URLSearchParams(new URL(img.src).search).get("filename")); + a.setAttribute( + "download", + new URLSearchParams(new URL(img.src).search).get("filename") + ); document.body.append(a); a.click(); requestAnimationFrame(() => a.remove()); @@ -247,7 +250,14 @@ class ComfyApp { ctx.drawImage(this.imgs[imageIndex], x, y, w, h); const drawButton = (x, y, sz, text) => { - const hovered = LiteGraph.isInsideRectangle(mouse[0], mouse[1], x + this.pos[0], y + this.pos[1], sz, sz); + const hovered = LiteGraph.isInsideRectangle( + mouse[0], + mouse[1], + x + this.pos[0], + y + this.pos[1], + sz, + sz + ); let fill = "#333"; let textFill = "#fff"; let isClicking = false; @@ -380,27 +390,35 @@ class ComfyApp { const self = this; const origProcessMouseDown = LGraphCanvas.prototype.processMouseDown; - LGraphCanvas.prototype.processMouseDown = function(e) { + LGraphCanvas.prototype.processMouseDown = function (e) { const res = origProcessMouseDown.apply(this, arguments); this.selected_group_moving = false; if (this.selected_group && !this.selected_group_resizing) { - var font_size = - this.selected_group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; + var font_size = this.selected_group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; var height = font_size * 1.4; // Move group by header - if (LiteGraph.isInsideRectangle(e.canvasX, e.canvasY, this.selected_group.pos[0], this.selected_group.pos[1], this.selected_group.size[0], height)) { + if ( + LiteGraph.isInsideRectangle( + e.canvasX, + e.canvasY, + this.selected_group.pos[0], + this.selected_group.pos[1], + this.selected_group.size[0], + height + ) + ) { this.selected_group_moving = true; } } return res; - } + }; const origProcessMouseMove = LGraphCanvas.prototype.processMouseMove; - LGraphCanvas.prototype.processMouseMove = function(e) { + LGraphCanvas.prototype.processMouseMove = function (e) { const orig_selected_group = this.selected_group; if (this.selected_group && !this.selected_group_resizing && !this.selected_group_moving) { @@ -424,7 +442,7 @@ class ComfyApp { const self = this; const origDrawGroups = LGraphCanvas.prototype.drawGroups; - LGraphCanvas.prototype.drawGroups = function(canvas, ctx) { + LGraphCanvas.prototype.drawGroups = function (canvas, ctx) { if (!this.graph) { return; } @@ -447,8 +465,7 @@ class ComfyApp { var size = group._size; ctx.globalAlpha = 0.25 * this.editor_alpha; ctx.beginPath(); - var font_size = - group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; + var font_size = group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; ctx.rect(pos[0] + 0.5, pos[1] + 0.5, size[0], font_size * 1.4); ctx.fill(); ctx.globalAlpha = this.editor_alpha; @@ -458,7 +475,7 @@ class ComfyApp { const res = origDrawGroups.apply(this, arguments); return res; - } + }; } /** @@ -467,7 +484,15 @@ class ComfyApp { #addDrawNodeHandler() { const orig = LGraphCanvas.prototype.drawNodeShape; const self = this; - LGraphCanvas.prototype.drawNodeShape = function (node, ctx, size, fgcolor, bgcolor, selected, mouse_over) { + LGraphCanvas.prototype.drawNodeShape = function ( + node, + ctx, + size, + fgcolor, + bgcolor, + selected, + mouse_over + ) { const res = orig.apply(this, arguments); let color = null; @@ -483,8 +508,16 @@ class ComfyApp { ctx.globalAlpha = 0.8; ctx.beginPath(); if (shape == LiteGraph.BOX_SHAPE) - ctx.rect(-6, -6 + LiteGraph.NODE_TITLE_HEIGHT, 12 + size[0] + 1, 12 + size[1] + LiteGraph.NODE_TITLE_HEIGHT); - else if (shape == LiteGraph.ROUND_SHAPE || (shape == LiteGraph.CARD_SHAPE && node.flags.collapsed)) + ctx.rect( + -6, + -6 + LiteGraph.NODE_TITLE_HEIGHT, + 12 + size[0] + 1, + 12 + size[1] + LiteGraph.NODE_TITLE_HEIGHT + ); + else if ( + shape == LiteGraph.ROUND_SHAPE || + (shape == LiteGraph.CARD_SHAPE && node.flags.collapsed) + ) ctx.roundRect( -6, -6 - LiteGraph.NODE_TITLE_HEIGHT, @@ -583,7 +616,9 @@ class ComfyApp { await this.#loadExtensions(); // Create and mount the LiteGraph in the DOM - const canvasEl = (this.canvasEl = Object.assign(document.createElement("canvas"), { id: "graph-canvas" })); + const canvasEl = (this.canvasEl = Object.assign(document.createElement("canvas"), { + id: "graph-canvas", + })); canvasEl.tabIndex = "1"; document.body.prepend(canvasEl); @@ -627,7 +662,10 @@ class ComfyApp { } // Save current workflow automatically - setInterval(() => localStorage.setItem("workflow", JSON.stringify(this.graph.serialize())), 1000); + setInterval( + () => localStorage.setItem("workflow", JSON.stringify(this.graph.serialize())), + 1000 + ); this.#addDrawNodeHandler(); this.#addDrawGroupsHandler(); @@ -661,8 +699,12 @@ class ComfyApp { const node = Object.assign( function ComfyNode() { var inputs = nodeData["input"]["required"]; - if (nodeData["input"]["optional"] != undefined){ - inputs = Object.assign({}, nodeData["input"]["required"], nodeData["input"]["optional"]) + if (nodeData["input"]["optional"] != undefined) { + inputs = Object.assign( + {}, + nodeData["input"]["required"], + nodeData["input"]["optional"] + ); } const config = { minWidth: 1, minHeight: 1 }; for (const inputName in inputs) { @@ -674,7 +716,10 @@ class ComfyApp { Object.assign(config, widgets.COMBO(this, inputName, inputData, app) || {}); } else if (`${type}:${inputName}` in widgets) { // Support custom widgets by Type:Name - Object.assign(config, widgets[`${type}:${inputName}`](this, inputName, inputData, app) || {}); + Object.assign( + config, + widgets[`${type}:${inputName}`](this, inputName, inputData, app) || {} + ); } else if (type in widgets) { // Standard type widgets Object.assign(config, widgets[type](this, inputName, inputData, app) || {}); @@ -783,7 +828,9 @@ class ComfyApp { for (const i in widgets) { const widget = widgets[i]; if (!widget.options || widget.options.serialize !== false) { - inputs[widget.name] = widget.serializeValue ? await widget.serializeValue(n, i) : widget.value; + inputs[widget.name] = widget.serializeValue + ? await widget.serializeValue(n, i) + : widget.value; } } } @@ -885,24 +932,31 @@ class ComfyApp { async refreshComboInNodes() { const defs = await api.getNodeDefs(); - for(let nodeNum in this.graph._nodes) { + for (let nodeNum in this.graph._nodes) { const node = this.graph._nodes[nodeNum]; const def = defs[node.type]; - for(const widgetNum in node.widgets) { - const widget = node.widgets[widgetNum] + for (const widgetNum in node.widgets) { + const widget = node.widgets[widgetNum]; - if(widget.type == "combo" && def["input"]["required"][widget.name] !== undefined) { + if (widget.type == "combo" && def["input"]["required"][widget.name] !== undefined) { widget.options.values = def["input"]["required"][widget.name][0]; - if(!widget.options.values.includes(widget.value)) { + if (!widget.options.values.includes(widget.value)) { widget.value = widget.options.values[0]; } } } } } + + /** + * Clean current state + */ + clean() { + this.nodeOutputs = {}; + } } export const app = new ComfyApp(); diff --git a/web/scripts/ui.js b/web/scripts/ui.js index c79caaa9b..63fc21899 100644 --- a/web/scripts/ui.js +++ b/web/scripts/ui.js @@ -42,9 +42,9 @@ function dragElement(dragEl) { posStartY = 0, newPosX = 0, newPosY = 0; - if (dragEl.getElementsByClassName('drag-handle')[0]) { + if (dragEl.getElementsByClassName("drag-handle")[0]) { // if present, the handle is where you move the DIV from: - dragEl.getElementsByClassName('drag-handle')[0].onmousedown = dragMouseDown; + dragEl.getElementsByClassName("drag-handle")[0].onmousedown = dragMouseDown; } else { // otherwise, move the DIV from anywhere inside the DIV: dragEl.onmousedown = dragMouseDown; @@ -69,8 +69,14 @@ function dragElement(dragEl) { posDiffY = e.clientY - posStartY; posStartX = e.clientX; posStartY = e.clientY; - newPosX = Math.min((document.body.clientWidth - dragEl.clientWidth), Math.max(0, (dragEl.offsetLeft + posDiffX))); - newPosY = Math.min((document.body.clientHeight - dragEl.clientHeight), Math.max(0, (dragEl.offsetTop + posDiffY))); + newPosX = Math.min( + document.body.clientWidth - dragEl.clientWidth, + Math.max(0, dragEl.offsetLeft + posDiffX) + ); + newPosY = Math.min( + document.body.clientHeight - dragEl.clientHeight, + Math.max(0, dragEl.offsetTop + posDiffY) + ); // set the element's new position: dragEl.style.top = newPosY + "px"; dragEl.style.left = newPosX + "px"; @@ -306,6 +312,7 @@ export class ComfyUI { style: { display: "none" }, parent: document.body, onchange: () => { + app.clean(); app.handleFile(fileInput.files[0]); }, }); @@ -314,40 +321,68 @@ export class ComfyUI { $el("div", { style: { overflow: "hidden", position: "relative", width: "100%" } }, [ $el("span.drag-handle"), $el("span", { $: (q) => (this.queueSize = q) }), - $el("button.comfy-settings-btn", { textContent: "⚙️", onclick: () => this.settings.show() }), + $el("button.comfy-settings-btn", { + textContent: "⚙️", + onclick: () => this.settings.show(), + }), ]), - $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0, this.batchCount) }), + $el("button.comfy-queue-btn", { + textContent: "Queue Prompt", + onclick: () => app.queuePrompt(0, this.batchCount), + }), $el("div", {}, [ - $el("label", { innerHTML: "Extra options"}, [ - $el("input", { type: "checkbox", - onchange: (i) => { - document.getElementById('extraOptions').style.display = i.srcElement.checked ? "block" : "none"; - this.batchCount = i.srcElement.checked ? document.getElementById('batchCountInputRange').value : 1; - document.getElementById('autoQueueCheckbox').checked = false; - } - }) - ]) - ]), - $el("div", { id: "extraOptions", style: { width: "100%", display: "none" }}, [ - $el("label", { innerHTML: "Batch count" }, [ - $el("input", { id: "batchCountInputNumber", type: "number", value: this.batchCount, min: "1", style: { width: "35%", "margin-left": "0.4em" }, - oninput: (i) => { - this.batchCount = i.target.value; - document.getElementById('batchCountInputRange').value = this.batchCount; - } + $el("label", { innerHTML: "Extra options" }, [ + $el("input", { + type: "checkbox", + onchange: (i) => { + document.getElementById("extraOptions").style.display = i.srcElement.checked + ? "block" + : "none"; + this.batchCount = i.srcElement.checked + ? document.getElementById("batchCountInputRange").value + : 1; + document.getElementById("autoQueueCheckbox").checked = false; + }, }), - $el("input", { id: "batchCountInputRange", type: "range", min: "1", max: "100", value: this.batchCount, + ]), + ]), + $el("div", { id: "extraOptions", style: { width: "100%", display: "none" } }, [ + $el("label", { innerHTML: "Batch count" }, [ + $el("input", { + id: "batchCountInputNumber", + type: "number", + value: this.batchCount, + min: "1", + style: { width: "35%", "margin-left": "0.4em" }, + oninput: (i) => { + this.batchCount = i.target.value; + document.getElementById("batchCountInputRange").value = this.batchCount; + }, + }), + $el("input", { + id: "batchCountInputRange", + type: "range", + min: "1", + max: "100", + value: this.batchCount, oninput: (i) => { this.batchCount = i.srcElement.value; - document.getElementById('batchCountInputNumber').value = i.srcElement.value; - } + document.getElementById("batchCountInputNumber").value = i.srcElement.value; + }, + }), + $el("input", { + id: "autoQueueCheckbox", + type: "checkbox", + checked: false, + title: "automatically queue prompt when the queue size hits 0", }), - $el("input", { id: "autoQueueCheckbox", type: "checkbox", checked: false, title: "automatically queue prompt when the queue size hits 0", - }) ]), ]), $el("div.comfy-menu-btns", [ - $el("button", { textContent: "Queue Front", onclick: () => app.queuePrompt(-1, this.batchCount) }), + $el("button", { + textContent: "Queue Front", + onclick: () => app.queuePrompt(-1, this.batchCount), + }), $el("button", { $: (b) => (this.queue.button = b), textContent: "View Queue", @@ -388,8 +423,20 @@ export class ComfyUI { }), $el("button", { textContent: "Load", onclick: () => fileInput.click() }), $el("button", { textContent: "Refresh", onclick: () => app.refreshComboInNodes() }), - $el("button", { textContent: "Clear", onclick: () => app.graph.clear() }), - $el("button", { textContent: "Load Default", onclick: () => app.loadGraphData() }), + $el("button", { + textContent: "Clear", + onclick: () => { + app.clean(); + app.graph.clear(); + }, + }), + $el("button", { + textContent: "Load Default", + onclick: () => { + app.clean(); + app.loadGraphData(); + }, + }), ]); dragElement(this.menuContainer); @@ -398,12 +445,17 @@ export class ComfyUI { } setStatus(status) { - this.queueSize.textContent = "Queue size: " + (status ? status.exec_info.queue_remaining : "ERR"); + this.queueSize.textContent = + "Queue size: " + (status ? status.exec_info.queue_remaining : "ERR"); if (status) { - if (this.lastQueueSize != 0 && status.exec_info.queue_remaining == 0 && document.getElementById('autoQueueCheckbox').checked) { + if ( + this.lastQueueSize != 0 && + status.exec_info.queue_remaining == 0 && + document.getElementById("autoQueueCheckbox").checked + ) { app.queuePrompt(0, this.batchCount); } - this.lastQueueSize = status.exec_info.queue_remaining + this.lastQueueSize = status.exec_info.queue_remaining; } } }