refactor: Replace brush preview feature with missionfloyd implementation

This commit is contained in:
Lt.Dr.Data 2023-04-27 10:25:04 +09:00
parent fc976f48b1
commit d662e9298e

View File

@ -132,7 +132,7 @@ class MaskEditorDialog extends ComfyDialog {
return divElement;
}
setLayout(imgCanvas, maskCanvas, cursorCanvas) {
setlayout(imgCanvas, maskCanvas) {
const self = this;
// If it is specified as relative, using it only as a hidden placeholder for padding is recommended
@ -148,6 +148,23 @@ class MaskEditorDialog extends ComfyDialog {
bottom_panel.style.right = "0";
bottom_panel.style.height = "50px";
var brush = document.createElement("div");
brush.id = "brush";
brush.style.backgroundColor = "transparent";
brush.style.border = "1px dashed black";
brush.style.borderRadius = "50%";
brush.style.MozBorderRadius = "50%";
brush.style.WebkitBorderRadius = "50%";
brush.style.position = "absolute";
brush.style.zIndex = 100;
brush.style.pointerEvents = "none";
this.brush = brush;
this.element.appendChild(imgCanvas);
this.element.appendChild(maskCanvas);
this.element.appendChild(placeholder); // must below z-index than bottom_panel to avoid covering button
this.element.appendChild(bottom_panel);
document.body.appendChild(brush);
var clearButton = this.createLeftButton("Clear", "280px",
() => {
self.maskCtx.clearRect(0, 0, self.maskCanvas.width, self.maskCanvas.height);
@ -171,7 +188,6 @@ class MaskEditorDialog extends ComfyDialog {
});
this.element.appendChild(imgCanvas);
this.element.appendChild(cursorCanvas);
this.element.appendChild(maskCanvas);
this.element.appendChild(placeholder); // must below z-index than bottom_panel to avoid covering button
this.element.appendChild(bottom_panel);
@ -187,30 +203,27 @@ class MaskEditorDialog extends ComfyDialog {
imgCanvas.style.left = "0";
maskCanvas.style.position = "absolute";
cursorCanvas.style.position = "absolute";
}
show() {
// layout
const imgCanvas = document.createElement('canvas');
const maskCanvas = document.createElement('canvas');
const cursorCanvas = document.createElement('canvas');
const backupCanvas = document.createElement('canvas');
imgCanvas.id = "imageCanvas";
maskCanvas.id = "maskCanvas";
cursorCanvas.id = "cursorCanvas";
backupCanvas.id = "backupCanvas";
this.setlayout(imgCanvas, maskCanvas);
// prepare content
this.maskCanvas = maskCanvas;
this.backupCanvas = backupCanvas;
this.cursorCanvas = cursorCanvas;
this.maskCtx = maskCanvas.getContext('2d');
this.cursorCtx = cursorCanvas.getContext('2d');
this.backupCtx = backupCanvas.getContext('2d');
this.setLayout(imgCanvas, maskCanvas, cursorCanvas);
// separate original_imgs and imgs
if(ComfyApp.clipspace.imgs[0] === ComfyApp.clipspace.original_imgs[0]) {
var copiedImage = new Image();
@ -218,46 +231,14 @@ class MaskEditorDialog extends ComfyDialog {
ComfyApp.clipspace.imgs = [copiedImage];
}
this.setImages(imgCanvas, backupCanvas, cursorCanvas);
this.setImages(imgCanvas, backupCanvas);
this.setEventHandler(maskCanvas);
}
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) {
setImages(imgCanvas, backupCanvas) {
const imgCtx = imgCanvas.getContext('2d');
const backupCtx = backupCanvas.getContext('2d');
const maskCtx = this.maskCtx;
const cursorCtx = this.cursorCtx;
const maskCanvas = this.maskCanvas;
// image load
@ -284,16 +265,10 @@ class MaskEditorDialog extends ComfyDialog {
// update mask
backupCtx.drawImage(maskCanvas, 0, 0, maskCanvas.width, maskCanvas.height, 0, 0, backupCanvas.width, backupCanvas.height);
cursorCanvas.width = maskCanvas.width = drawWidth;
cursorCanvas.height = maskCanvas.height = drawHeight;
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);
maskCanvas.width = drawWidth;
maskCanvas.height = drawHeight;
maskCanvas.style.top = imgCanvas.offsetTop + "px";
maskCanvas.style.left = imgCanvas.offsetLeft + "px";
maskCtx.drawImage(backupCanvas, 0, 0, backupCanvas.width, backupCanvas.height, 0, 0, maskCanvas.width, maskCanvas.height);
});
@ -360,22 +335,27 @@ class MaskEditorDialog extends ComfyDialog {
else
self.brush_size = Math.max(self.brush_size-2, 1);
self.brush_slider_input.value = self.brush_size;
self.invalidateCursorCanvas(self, true, null, null);
// self.brush_slider_input.dispatchEvent(new Event('input'));
}
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);
const brush = this.brush;
brush.style.width = (this.brush_size - 1) * 2 + "px";
brush.style.height = (this.brush_size - 1) * 2 + "px";
brush.style.left = (event.pageX - this.brush_size) + "px";
brush.style.top = (event.pageY - this.brush_size) + "px";
if (event instanceof TouchEvent || event.buttons === 1) {
event.preventDefault();
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)
requestAnimationFrame(() => {
self.maskCtx.beginPath();
@ -387,7 +367,7 @@ class MaskEditorDialog extends ComfyDialog {
self.lasty = y;
});
else
requestAnimationFrame(() => {
requestAnimationFrame(() => {
self.maskCtx.beginPath();
self.maskCtx.fillStyle = "rgb(0,0,0)";
self.maskCtx.globalCompositeOperation = "source-over";
@ -413,6 +393,9 @@ class MaskEditorDialog extends ComfyDialog {
}
else if(event.buttons === 2) {
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
requestAnimationFrame(() => {
@ -424,7 +407,7 @@ class MaskEditorDialog extends ComfyDialog {
self.lasty = y;
});
else
requestAnimationFrame(() => {
requestAnimationFrame(() => {
self.maskCtx.beginPath();
self.maskCtx.globalCompositeOperation = "destination-out";
@ -476,7 +459,7 @@ class MaskEditorDialog extends ComfyDialog {
const y = event.offsetY || event.targetTouches[0].clientY - maskRect.top;
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.fill();
self.lastx = x;