mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-02-09 13:02:31 +08:00
Add cursor functionality to display brush size
This commit is contained in:
parent
977c1ae506
commit
fc976f48b1
@ -132,7 +132,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
return divElement;
|
return divElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
setlayout(imgCanvas, maskCanvas) {
|
setLayout(imgCanvas, maskCanvas, cursorCanvas) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
// If it is specified as relative, using it only as a hidden placeholder for padding is recommended
|
// If it is specified as relative, using it only as a hidden placeholder for padding is recommended
|
||||||
@ -171,6 +171,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.element.appendChild(imgCanvas);
|
this.element.appendChild(imgCanvas);
|
||||||
|
this.element.appendChild(cursorCanvas);
|
||||||
this.element.appendChild(maskCanvas);
|
this.element.appendChild(maskCanvas);
|
||||||
this.element.appendChild(placeholder); // must below z-index than bottom_panel to avoid covering button
|
this.element.appendChild(placeholder); // must below z-index than bottom_panel to avoid covering button
|
||||||
this.element.appendChild(bottom_panel);
|
this.element.appendChild(bottom_panel);
|
||||||
@ -186,27 +187,30 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
imgCanvas.style.left = "0";
|
imgCanvas.style.left = "0";
|
||||||
|
|
||||||
maskCanvas.style.position = "absolute";
|
maskCanvas.style.position = "absolute";
|
||||||
|
cursorCanvas.style.position = "absolute";
|
||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
// layout
|
// layout
|
||||||
const imgCanvas = document.createElement('canvas');
|
const imgCanvas = document.createElement('canvas');
|
||||||
const maskCanvas = document.createElement('canvas');
|
const maskCanvas = document.createElement('canvas');
|
||||||
|
const cursorCanvas = document.createElement('canvas');
|
||||||
const backupCanvas = document.createElement('canvas');
|
const backupCanvas = document.createElement('canvas');
|
||||||
|
|
||||||
imgCanvas.id = "imageCanvas";
|
imgCanvas.id = "imageCanvas";
|
||||||
maskCanvas.id = "maskCanvas";
|
maskCanvas.id = "maskCanvas";
|
||||||
|
cursorCanvas.id = "cursorCanvas";
|
||||||
backupCanvas.id = "backupCanvas";
|
backupCanvas.id = "backupCanvas";
|
||||||
|
|
||||||
this.setlayout(imgCanvas, maskCanvas);
|
|
||||||
|
|
||||||
// prepare content
|
|
||||||
|
|
||||||
this.maskCanvas = maskCanvas;
|
this.maskCanvas = maskCanvas;
|
||||||
this.backupCanvas = backupCanvas;
|
this.backupCanvas = backupCanvas;
|
||||||
|
this.cursorCanvas = cursorCanvas;
|
||||||
this.maskCtx = maskCanvas.getContext('2d');
|
this.maskCtx = maskCanvas.getContext('2d');
|
||||||
|
this.cursorCtx = cursorCanvas.getContext('2d');
|
||||||
this.backupCtx = backupCanvas.getContext('2d');
|
this.backupCtx = backupCanvas.getContext('2d');
|
||||||
|
|
||||||
|
this.setLayout(imgCanvas, maskCanvas, cursorCanvas);
|
||||||
|
|
||||||
// separate original_imgs and imgs
|
// separate original_imgs and imgs
|
||||||
if(ComfyApp.clipspace.imgs[0] === ComfyApp.clipspace.original_imgs[0]) {
|
if(ComfyApp.clipspace.imgs[0] === ComfyApp.clipspace.original_imgs[0]) {
|
||||||
var copiedImage = new Image();
|
var copiedImage = new Image();
|
||||||
@ -214,14 +218,46 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
ComfyApp.clipspace.imgs = [copiedImage];
|
ComfyApp.clipspace.imgs = [copiedImage];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setImages(imgCanvas, backupCanvas);
|
this.setImages(imgCanvas, backupCanvas, cursorCanvas);
|
||||||
this.setEventHandler(maskCanvas);
|
this.setEventHandler(maskCanvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
setImages(imgCanvas, backupCanvas) {
|
invalidateCursorCanvas(self, update_brush_size_only, x, y) {
|
||||||
|
const ctx = self.cursorCtx;
|
||||||
|
|
||||||
|
if(self.cursorCtx.lastX == null) {
|
||||||
|
ctx.clearRect(0,0,self.cursorCanvas.width,self.cursorCanvas.height);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const lastBrushSize = ctx.lastBrushSize;
|
||||||
|
const lastX = ctx.lastX;
|
||||||
|
const lastY = ctx.lastY;
|
||||||
|
ctx.clearRect(lastX - lastBrushSize - 10, lastY - lastBrushSize - 10, 2*lastBrushSize + 20, 2*lastBrushSize + 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(update_brush_size_only) {
|
||||||
|
x = ctx.lastX;
|
||||||
|
y = ctx.lastY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x != null && y != null) {
|
||||||
|
ctx.lastX = x;
|
||||||
|
ctx.lastY = y;
|
||||||
|
ctx.lastBrushSize = self.brush_size;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.setLineDash([2, 2]);
|
||||||
|
ctx.arc(x, y, self.brush_size, 0, Math.PI * 2);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setImages(imgCanvas, backupCanvas, cursorCanvas) {
|
||||||
const imgCtx = imgCanvas.getContext('2d');
|
const imgCtx = imgCanvas.getContext('2d');
|
||||||
const backupCtx = backupCanvas.getContext('2d');
|
const backupCtx = backupCanvas.getContext('2d');
|
||||||
const maskCtx = this.maskCtx;
|
const maskCtx = this.maskCtx;
|
||||||
|
const cursorCtx = this.cursorCtx;
|
||||||
const maskCanvas = this.maskCanvas;
|
const maskCanvas = this.maskCanvas;
|
||||||
|
|
||||||
// image load
|
// image load
|
||||||
@ -248,10 +284,16 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
|
|
||||||
// update mask
|
// update mask
|
||||||
backupCtx.drawImage(maskCanvas, 0, 0, maskCanvas.width, maskCanvas.height, 0, 0, backupCanvas.width, backupCanvas.height);
|
backupCtx.drawImage(maskCanvas, 0, 0, maskCanvas.width, maskCanvas.height, 0, 0, backupCanvas.width, backupCanvas.height);
|
||||||
maskCanvas.width = drawWidth;
|
|
||||||
maskCanvas.height = drawHeight;
|
cursorCanvas.width = maskCanvas.width = drawWidth;
|
||||||
maskCanvas.style.top = imgCanvas.offsetTop + "px";
|
cursorCanvas.height = maskCanvas.height = drawHeight;
|
||||||
maskCanvas.style.left = imgCanvas.offsetLeft + "px";
|
cursorCanvas.style.top = maskCanvas.style.top = imgCanvas.offsetTop + "px";
|
||||||
|
cursorCanvas.style.left = maskCanvas.style.left = imgCanvas.offsetLeft + "px";
|
||||||
|
|
||||||
|
cursorCtx.lastX = null;
|
||||||
|
cursorCtx.lastY = null;
|
||||||
|
this.invalidateCursorCanvas(this, false, null, null);
|
||||||
|
|
||||||
maskCtx.drawImage(backupCanvas, 0, 0, backupCanvas.width, backupCanvas.height, 0, 0, maskCanvas.width, maskCanvas.height);
|
maskCtx.drawImage(backupCanvas, 0, 0, backupCanvas.width, backupCanvas.height, 0, 0, maskCanvas.width, maskCanvas.height);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -318,21 +360,22 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
else
|
else
|
||||||
self.brush_size = Math.max(self.brush_size-2, 1);
|
self.brush_size = Math.max(self.brush_size-2, 1);
|
||||||
|
|
||||||
|
|
||||||
self.brush_slider_input.value = self.brush_size;
|
self.brush_slider_input.value = self.brush_size;
|
||||||
// self.brush_slider_input.dispatchEvent(new Event('input'));
|
self.invalidateCursorCanvas(self, true, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_move(self, event) {
|
draw_move(self, event) {
|
||||||
|
const maskRect = self.maskCanvas.getBoundingClientRect();
|
||||||
|
const x = event.offsetX || event.targetTouches[0].clientX - maskRect.left;
|
||||||
|
const y = event.offsetY || event.targetTouches[0].clientY - maskRect.top;
|
||||||
|
|
||||||
|
self.invalidateCursorCanvas(self, false, x, y);
|
||||||
|
|
||||||
if (event instanceof TouchEvent || event.buttons === 1) {
|
if (event instanceof TouchEvent || event.buttons === 1) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
var diff = performance.now() - self.lasttime;
|
var diff = performance.now() - self.lasttime;
|
||||||
|
|
||||||
const maskRect = self.maskCanvas.getBoundingClientRect();
|
|
||||||
const x = event.offsetX || event.targetTouches[0].clientX - maskRect.left;
|
|
||||||
const y = event.offsetY || event.targetTouches[0].clientY - maskRect.top;
|
|
||||||
|
|
||||||
if(diff > 20 && !this.drawing_mode)
|
if(diff > 20 && !this.drawing_mode)
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
self.maskCtx.beginPath();
|
self.maskCtx.beginPath();
|
||||||
@ -344,7 +387,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
self.lasty = y;
|
self.lasty = y;
|
||||||
});
|
});
|
||||||
else
|
else
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
self.maskCtx.beginPath();
|
self.maskCtx.beginPath();
|
||||||
self.maskCtx.fillStyle = "rgb(0,0,0)";
|
self.maskCtx.fillStyle = "rgb(0,0,0)";
|
||||||
self.maskCtx.globalCompositeOperation = "source-over";
|
self.maskCtx.globalCompositeOperation = "source-over";
|
||||||
@ -370,9 +413,6 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
}
|
}
|
||||||
else if(event.buttons === 2) {
|
else if(event.buttons === 2) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const maskRect = self.maskCanvas.getBoundingClientRect();
|
|
||||||
const x = event.offsetX || event.targetTouches[0].clientX - maskRect.left;
|
|
||||||
const y = event.offsetY || event.targetTouches[0].clientY - maskRect.top;
|
|
||||||
|
|
||||||
if(diff > 20 && !drawing_mode) // cannot tracking drawing_mode for touch event
|
if(diff > 20 && !drawing_mode) // cannot tracking drawing_mode for touch event
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
@ -384,7 +424,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
self.lasty = y;
|
self.lasty = y;
|
||||||
});
|
});
|
||||||
else
|
else
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
self.maskCtx.beginPath();
|
self.maskCtx.beginPath();
|
||||||
self.maskCtx.globalCompositeOperation = "destination-out";
|
self.maskCtx.globalCompositeOperation = "destination-out";
|
||||||
|
|
||||||
@ -436,7 +476,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
const y = event.offsetY || event.targetTouches[0].clientY - maskRect.top;
|
const y = event.offsetY || event.targetTouches[0].clientY - maskRect.top;
|
||||||
|
|
||||||
self.maskCtx.beginPath();
|
self.maskCtx.beginPath();
|
||||||
self.maskCtx.globalCompositeOperation = "destination-out";
|
self.maskCtx.globalCompositeOperation = "destination-out";
|
||||||
self.maskCtx.arc(x, y, this.brush_size, 0, Math.PI * 2, false);
|
self.maskCtx.arc(x, y, this.brush_size, 0, Math.PI * 2, false);
|
||||||
self.maskCtx.fill();
|
self.maskCtx.fill();
|
||||||
self.lastx = x;
|
self.lastx = x;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user