Multi target support
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
ComfyUI canvas editor page
|
||||
|
||||
## Updates
|
||||
- 2024-1-24 Added multi canvas node support.
|
||||
- 2024-1-11 Added CSS for prefers-color-scheme:dark
|
||||
- 2023-12-23 Added tool to scale and rotate layers (Hotkey is T, doubleClick on image to toggle between Rotate and Scale mode)
|
||||
- 2023-12-4 Added hotkeys for Brush Radius, Added Duplicate Layer button. Ctrl-Click duplicates the target layer.
|
||||
- 2023-12-2 Added Trigger Queue on change toggle.
|
||||
@@ -26,6 +28,9 @@ Drag images around with the middle mouse button and scale them with the mouse wh
|
||||
There is a green Tab on the side of images in the editor, click on that tab to highlight it.
|
||||
The image with the highlighted tab is sent through to the comfyUI node.
|
||||
|
||||
Multiple Canvas Tab nodes are supported, If the title of the node and the title of the image in the editor are set to the same name
|
||||
The output of the canvas editor will be sent to that node.
|
||||
|
||||
You can have multiple image layers and you can select generated images to be
|
||||
added as a new layer, replace an existing layers, or as a new image.
|
||||
|
||||
@@ -52,7 +57,8 @@ send images directly to the editor.
|
||||
- CTRL_SHIFT_Z redo
|
||||
|
||||
|
||||
##Why would you do such a thing?
|
||||
|
||||
## Why would you do such a thing?
|
||||
|
||||
My main motivation for making this was to develop an inpainting workflow,
|
||||
but I have also found it quite useful for scribble based images,
|
||||
|
||||
+12
-6
@@ -41,7 +41,7 @@ function checkAndClear(key) {
|
||||
function handleStatusUpdate(e) {
|
||||
const detail = e.detail;
|
||||
if (detail?.exec_info?.queue_remaining === 0) {
|
||||
console.log({anotherQueueWaiting,autoQueueInProgress})
|
||||
//console.log({anotherQueueWaiting,autoQueueInProgress})
|
||||
if (anotherQueueWaiting) {
|
||||
app.queuePrompt();
|
||||
anotherQueueWaiting=false;
|
||||
@@ -99,7 +99,7 @@ function initEditorNode(node)
|
||||
node.collected_images = [];
|
||||
node.addWidget("button","Edit","bingo", (widget,graphCanvas, node, {x,y}, event) => focusEditor(node));
|
||||
node.triggerQueue=node.addWidget("toggle","Queue on change",false,_=>{});
|
||||
node.widgets.reverse();// because auto created widget get put in first
|
||||
node.widgets.reverse();// because auto created widgets get put in first
|
||||
|
||||
node.canvasWidget=node.widgets[2];
|
||||
node.maskWidget=node.widgets[3];
|
||||
@@ -138,7 +138,6 @@ function addDragDropSupport(node) {
|
||||
|
||||
}
|
||||
function transmitImages(images) {
|
||||
console.log("transmit",editor)
|
||||
if (!editor.window || editor.window.closed) openEditor();
|
||||
|
||||
if(editor.channel) {
|
||||
@@ -274,8 +273,7 @@ function addCanvasWidget(node,name,inputData,app) {
|
||||
widget.uploadedBlobName = result.name;
|
||||
widget.sendBlobRequired=false;
|
||||
}
|
||||
}
|
||||
console.log(widget)
|
||||
}
|
||||
return widget.uploadedBlobName;
|
||||
}
|
||||
}
|
||||
@@ -324,8 +322,16 @@ function handleWindowMessage(e) {
|
||||
}
|
||||
|
||||
async function messageFromEditor(event) {
|
||||
const nodes = app.graph.findNodesByType("Canvas_Tab");
|
||||
let nodes = app.graph.findNodesByType("Canvas_Tab");
|
||||
//send same thing to all of the Canvas_Tab nodes
|
||||
const {title, selected} = event.data;
|
||||
|
||||
console.log({title,selected});
|
||||
if (title) {
|
||||
|
||||
let targetNodes = nodes.filter(node=>node.title==title || (node.title=="Edit In Another Tab" && selected));
|
||||
nodes=targetNodes;
|
||||
}
|
||||
let queue = false;
|
||||
if (event.data.image instanceof Blob) {
|
||||
for (const node of nodes) {
|
||||
|
||||
+18
-10
@@ -89,7 +89,8 @@ function setExportPic(pic) {
|
||||
button.classList.add("output");
|
||||
|
||||
pic.updateVisualRepresentation(true);
|
||||
transmitMask(pic.mask.canvas);
|
||||
transmitMask(pic.mask.canvas,pic.title,true);
|
||||
|
||||
}
|
||||
|
||||
function closePic(pic) {
|
||||
@@ -322,6 +323,7 @@ function createDrawArea(canvas = blankCanvas(),initialTitle="Image") {
|
||||
set mask(m) {mask=m},
|
||||
get width() {return canvas.width},
|
||||
get height() {return canvas.height},
|
||||
get title() {return title.textContent},
|
||||
scale:1,
|
||||
scalefactor:0,
|
||||
offsetX:0,
|
||||
@@ -388,15 +390,14 @@ function createDrawArea(canvas = blankCanvas(),initialTitle="Image") {
|
||||
this.activeLayer.transform= [1,0 ,0,1, 0,0];
|
||||
|
||||
this.isDrawing = false;
|
||||
if (selectedExport===this) {
|
||||
//if (selectedExport===this) {
|
||||
if (this.activeLayer===this.mask) {
|
||||
transmitMask(this.mask.canvas);
|
||||
transmitMask(this.mask.canvas,this.title,selectedExport===this);
|
||||
} else {
|
||||
this.composite(true);
|
||||
transmitCanvas(canvas);
|
||||
}
|
||||
|
||||
}
|
||||
transmitCanvas(canvas,this.title,selectedExport===this);
|
||||
}
|
||||
//}
|
||||
if (activePic===this) {
|
||||
updateLayerList(); //inefficient to remake all controls on edit, fix this
|
||||
}
|
||||
@@ -413,9 +414,9 @@ function createDrawArea(canvas = blankCanvas(),initialTitle="Image") {
|
||||
this.commit();
|
||||
},
|
||||
updateVisualRepresentation(transmit=true) {
|
||||
if (transmit && this===selectedExport) {
|
||||
if (transmit) {
|
||||
this.composite(true); //suppress mask for transmitted canvas
|
||||
transmitCanvas(canvas);
|
||||
transmitCanvas(canvas,this.title,this===selectedExport);
|
||||
}
|
||||
this.composite(false);
|
||||
if (typeof tool?.drawUI === "function") tool.drawUI();
|
||||
@@ -864,7 +865,6 @@ function addNewImage(image) {
|
||||
|
||||
let result =createDrawArea(target);
|
||||
$("#workspace").append(result.element);
|
||||
//transmitCanvas(target);
|
||||
return(result)
|
||||
}
|
||||
|
||||
@@ -919,7 +919,15 @@ function handleMouseDown(e) {
|
||||
setActivePic(pic);
|
||||
|
||||
const maskLayer = activePic.activeLayer.mask
|
||||
if (e.altKey) {
|
||||
switch (e.button) {
|
||||
case 0:
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.button) {
|
||||
case 0:
|
||||
|
||||
+5
-4
@@ -31,23 +31,24 @@ if (location.pathname.includes("/page/")) {
|
||||
|
||||
let portToMain; // variable to hold the MessageChannel port
|
||||
|
||||
function transmitCanvas(canvas) {
|
||||
function transmitCanvas(canvas,title="",selected=true) {
|
||||
if (portToMain) {
|
||||
canvas.toBlob( blob=>{
|
||||
portToMain.postMessage( {"image": blob} );
|
||||
portToMain.postMessage( {"image": blob,title,selected} );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function transmitMask(canvas) {
|
||||
function transmitMask(canvas,title="",selected=true) {
|
||||
if (portToMain) {
|
||||
canvas.toBlob( blob=>{
|
||||
portToMain.postMessage( {"mask": blob} );
|
||||
portToMain.postMessage( {"mask": blob,title,selected} );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function loadImagefromURL(url) {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
|
||||
Reference in New Issue
Block a user