mirror of
https://github.com/Azornes/Comfyui-LayerForge.git
synced 2026-03-24 14:02:11 -03:00
createElement to createCanvas
This commit is contained in:
11
js/Canvas.js
11
js/Canvas.js
@@ -12,7 +12,7 @@ import { CanvasIO } from "./CanvasIO.js";
|
||||
import { ImageReferenceManager } from "./ImageReferenceManager.js";
|
||||
import { BatchPreviewManager } from "./BatchPreviewManager.js";
|
||||
import { createModuleLogger } from "./utils/LoggerUtils.js";
|
||||
import { debounce } from "./utils/CommonUtils.js";
|
||||
import { debounce, createCanvas } from "./utils/CommonUtils.js";
|
||||
import { MaskEditorIntegration } from "./MaskEditorIntegration.js";
|
||||
import { CanvasSelection } from "./CanvasSelection.js";
|
||||
const useChainCallback = (original, next) => {
|
||||
@@ -38,10 +38,10 @@ export class Canvas {
|
||||
constructor(node, widget, callbacks = {}) {
|
||||
this.node = node;
|
||||
this.widget = widget;
|
||||
this.canvas = document.createElement('canvas');
|
||||
const ctx = this.canvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas, ctx } = createCanvas(0, 0, '2d', { willReadFrequently: true });
|
||||
if (!ctx)
|
||||
throw new Error("Could not create canvas context");
|
||||
this.canvas = canvas;
|
||||
this.ctx = ctx;
|
||||
this.width = 512;
|
||||
this.height = 512;
|
||||
@@ -54,11 +54,12 @@ export class Canvas {
|
||||
y: -(this.height / 4),
|
||||
zoom: 0.8,
|
||||
};
|
||||
this.offscreenCanvas = document.createElement('canvas');
|
||||
this.offscreenCtx = this.offscreenCanvas.getContext('2d', {
|
||||
const { canvas: offscreenCanvas, ctx: offscreenCtx } = createCanvas(0, 0, '2d', {
|
||||
alpha: false,
|
||||
willReadFrequently: true
|
||||
});
|
||||
this.offscreenCanvas = offscreenCanvas;
|
||||
this.offscreenCtx = offscreenCtx;
|
||||
this.dataInitialized = false;
|
||||
this.pendingDataCheck = null;
|
||||
this.imageCache = new Map();
|
||||
|
||||
@@ -52,10 +52,7 @@ export class CanvasIO {
|
||||
const { canvas: maskCanvas, ctx: maskCtx } = createCanvas(this.canvas.width, this.canvas.height);
|
||||
const originalShape = this.canvas.outputAreaShape;
|
||||
this.canvas.outputAreaShape = null;
|
||||
const visibilityCanvas = document.createElement('canvas');
|
||||
visibilityCanvas.width = this.canvas.width;
|
||||
visibilityCanvas.height = this.canvas.height;
|
||||
const visibilityCtx = visibilityCanvas.getContext('2d', { alpha: true });
|
||||
const { canvas: visibilityCanvas, ctx: visibilityCtx } = createCanvas(this.canvas.width, this.canvas.height, '2d', { alpha: true });
|
||||
if (!visibilityCtx)
|
||||
throw new Error("Could not create visibility context");
|
||||
if (!maskCtx)
|
||||
@@ -94,17 +91,11 @@ export class CanvasIO {
|
||||
tempMaskData.data[i + 3] = alpha;
|
||||
}
|
||||
// Create a temporary canvas to hold the processed mask
|
||||
const tempMaskCanvas = document.createElement('canvas');
|
||||
tempMaskCanvas.width = this.canvas.width;
|
||||
tempMaskCanvas.height = this.canvas.height;
|
||||
const tempMaskCtx = tempMaskCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: tempMaskCanvas, ctx: tempMaskCtx } = createCanvas(this.canvas.width, this.canvas.height, '2d', { willReadFrequently: true });
|
||||
if (!tempMaskCtx)
|
||||
throw new Error("Could not create temp mask context");
|
||||
// Put the processed mask data into a canvas that matches the output area size
|
||||
const outputMaskCanvas = document.createElement('canvas');
|
||||
outputMaskCanvas.width = toolMaskCanvas.width;
|
||||
outputMaskCanvas.height = toolMaskCanvas.height;
|
||||
const outputMaskCtx = outputMaskCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: outputMaskCanvas, ctx: outputMaskCtx } = createCanvas(toolMaskCanvas.width, toolMaskCanvas.height, '2d', { willReadFrequently: true });
|
||||
if (!outputMaskCtx)
|
||||
throw new Error("Could not create output mask context");
|
||||
outputMaskCtx.putImageData(tempMaskData, 0, 0);
|
||||
@@ -289,12 +280,9 @@ export class CanvasIO {
|
||||
if (!tensor || !tensor.data || !tensor.width || !tensor.height) {
|
||||
throw new Error("Invalid tensor data");
|
||||
}
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas, ctx } = createCanvas(tensor.width, tensor.height, '2d', { willReadFrequently: true });
|
||||
if (!ctx)
|
||||
throw new Error("Could not create canvas context");
|
||||
canvas.width = tensor.width;
|
||||
canvas.height = tensor.height;
|
||||
const imageData = new ImageData(new Uint8ClampedArray(tensor.data), tensor.width, tensor.height);
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -468,10 +456,7 @@ export class CanvasIO {
|
||||
}
|
||||
async createImageFromData(imageData) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = imageData.width;
|
||||
canvas.height = imageData.height;
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas, ctx } = createCanvas(imageData.width, imageData.height, '2d', { willReadFrequently: true });
|
||||
if (!ctx)
|
||||
throw new Error("Could not create canvas context");
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
@@ -456,12 +456,9 @@ export class CanvasLayers {
|
||||
}
|
||||
async getLayerImageData(layer) {
|
||||
try {
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: tempCanvas, ctx: tempCtx } = createCanvas(layer.width, layer.height, '2d', { willReadFrequently: true });
|
||||
if (!tempCtx)
|
||||
throw new Error("Could not create canvas context");
|
||||
tempCanvas.width = layer.width;
|
||||
tempCanvas.height = layer.height;
|
||||
// We need to draw the layer relative to the new canvas, so we "move" it to 0,0
|
||||
// by creating a temporary layer object for drawing.
|
||||
const layerToDraw = {
|
||||
@@ -803,10 +800,7 @@ export class CanvasLayers {
|
||||
}
|
||||
bounds = { x: minX, y: minY, width: newWidth, height: newHeight };
|
||||
}
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
tempCanvas.width = bounds.width;
|
||||
tempCanvas.height = bounds.height;
|
||||
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: tempCanvas, ctx: tempCtx } = createCanvas(bounds.width, bounds.height, '2d', { willReadFrequently: true });
|
||||
if (!tempCtx) {
|
||||
reject(new Error("Could not create canvas context"));
|
||||
return;
|
||||
@@ -896,10 +890,7 @@ export class CanvasLayers {
|
||||
async getFlattenedMaskAsBlob() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const bounds = this.canvas.outputAreaBounds;
|
||||
const maskCanvas = document.createElement('canvas');
|
||||
maskCanvas.width = bounds.width;
|
||||
maskCanvas.height = bounds.height;
|
||||
const maskCtx = maskCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: maskCanvas, ctx: maskCtx } = createCanvas(bounds.width, bounds.height, '2d', { willReadFrequently: true });
|
||||
if (!maskCtx) {
|
||||
reject(new Error("Could not create mask context"));
|
||||
return;
|
||||
@@ -910,10 +901,7 @@ export class CanvasLayers {
|
||||
maskCtx.fillStyle = '#ffffff';
|
||||
maskCtx.fillRect(0, 0, bounds.width, bounds.height);
|
||||
// Stwórz canvas do sprawdzenia przezroczystości warstw
|
||||
const visibilityCanvas = document.createElement('canvas');
|
||||
visibilityCanvas.width = bounds.width;
|
||||
visibilityCanvas.height = bounds.height;
|
||||
const visibilityCtx = visibilityCanvas.getContext('2d', { alpha: true });
|
||||
const { canvas: visibilityCanvas, ctx: visibilityCtx } = createCanvas(bounds.width, bounds.height, '2d', { alpha: true });
|
||||
if (!visibilityCtx) {
|
||||
reject(new Error("Could not create visibility context"));
|
||||
return;
|
||||
@@ -946,10 +934,7 @@ export class CanvasLayers {
|
||||
tempMaskData.data[i + 3] = 255; // Solidna alpha
|
||||
}
|
||||
// Stwórz tymczasowy canvas dla przetworzonej maski
|
||||
const tempMaskCanvas = document.createElement('canvas');
|
||||
tempMaskCanvas.width = toolMaskCanvas.width;
|
||||
tempMaskCanvas.height = toolMaskCanvas.height;
|
||||
const tempMaskCtx = tempMaskCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: tempMaskCanvas, ctx: tempMaskCtx } = createCanvas(toolMaskCanvas.width, toolMaskCanvas.height, '2d', { willReadFrequently: true });
|
||||
if (tempMaskCtx) {
|
||||
tempMaskCtx.putImageData(tempMaskData, 0, 0);
|
||||
maskCtx.globalCompositeOperation = 'screen';
|
||||
@@ -1007,10 +992,7 @@ export class CanvasLayers {
|
||||
showErrorNotification("Cannot fuse layers: invalid dimensions calculated.");
|
||||
return;
|
||||
}
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
tempCanvas.width = fusedWidth;
|
||||
tempCanvas.height = fusedHeight;
|
||||
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: tempCanvas, ctx: tempCtx } = createCanvas(fusedWidth, fusedHeight, '2d', { willReadFrequently: true });
|
||||
if (!tempCtx)
|
||||
throw new Error("Could not create canvas context");
|
||||
tempCtx.translate(-minX, -minY);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createModuleLogger } from "./utils/LoggerUtils.js";
|
||||
import { iconLoader, LAYERFORGE_TOOLS } from "./utils/IconLoader.js";
|
||||
import { createCanvas } from "./utils/CommonUtils.js";
|
||||
const log = createModuleLogger('CanvasLayersPanel');
|
||||
export class CanvasLayersPanel {
|
||||
constructor(canvas) {
|
||||
@@ -49,10 +50,7 @@ export class CanvasLayersPanel {
|
||||
iconContainer.appendChild(img);
|
||||
}
|
||||
else if (icon instanceof HTMLCanvasElement) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const { canvas, ctx } = createCanvas(size, size);
|
||||
if (ctx) {
|
||||
ctx.drawImage(icon, 0, 0, size, size);
|
||||
}
|
||||
@@ -95,10 +93,7 @@ export class CanvasLayersPanel {
|
||||
iconContainer.appendChild(img);
|
||||
}
|
||||
else if (icon instanceof HTMLCanvasElement) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 16;
|
||||
canvas.height = 16;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const { canvas, ctx } = createCanvas(16, 16);
|
||||
if (ctx) {
|
||||
ctx.globalAlpha = 0.3;
|
||||
ctx.drawImage(icon, 0, 0, 16, 16);
|
||||
@@ -423,12 +418,9 @@ export class CanvasLayersPanel {
|
||||
thumbnailContainer.style.background = '#4a4a4a';
|
||||
return;
|
||||
}
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas, ctx } = createCanvas(48, 48, '2d', { willReadFrequently: true });
|
||||
if (!ctx)
|
||||
return;
|
||||
canvas.width = 48;
|
||||
canvas.height = 48;
|
||||
const scale = Math.min(48 / layer.image.width, 48 / layer.image.height);
|
||||
const scaledWidth = layer.image.width * scale;
|
||||
const scaledHeight = layer.image.height * scale;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getCanvasState, setCanvasState, saveImage, getImage } from "./db.js";
|
||||
import { createModuleLogger } from "./utils/LoggerUtils.js";
|
||||
import { generateUUID, cloneLayers, getStateSignature, debounce } from "./utils/CommonUtils.js";
|
||||
import { generateUUID, cloneLayers, getStateSignature, debounce, createCanvas } from "./utils/CommonUtils.js";
|
||||
const log = createModuleLogger('CanvasState');
|
||||
export class CanvasState {
|
||||
constructor(canvas) {
|
||||
@@ -196,10 +196,7 @@ export class CanvasState {
|
||||
img.src = imageSrc;
|
||||
}
|
||||
else {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = imageSrc.width;
|
||||
canvas.height = imageSrc.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const { canvas, ctx } = createCanvas(imageSrc.width, imageSrc.height);
|
||||
if (ctx) {
|
||||
ctx.drawImage(imageSrc, 0, 0);
|
||||
const img = new Image();
|
||||
@@ -315,10 +312,7 @@ export class CanvasState {
|
||||
this.maskUndoStack.pop();
|
||||
}
|
||||
const maskCanvas = this.canvas.maskTool.getMask();
|
||||
const clonedCanvas = document.createElement('canvas');
|
||||
clonedCanvas.width = maskCanvas.width;
|
||||
clonedCanvas.height = maskCanvas.height;
|
||||
const clonedCtx = clonedCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: clonedCanvas, ctx: clonedCtx } = createCanvas(maskCanvas.width, maskCanvas.height, '2d', { willReadFrequently: true });
|
||||
if (clonedCtx) {
|
||||
clonedCtx.drawImage(maskCanvas, 0, 0);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { addStylesheet, getUrl, loadTemplate } from "./utils/ResourceManager.js"
|
||||
import { Canvas } from "./Canvas.js";
|
||||
import { clearAllCanvasStates } from "./db.js";
|
||||
import { ImageCache } from "./ImageCache.js";
|
||||
import { createCanvas } from "./utils/CommonUtils.js";
|
||||
import { createModuleLogger } from "./utils/LoggerUtils.js";
|
||||
import { showErrorNotification, showSuccessNotification } from "./utils/NotificationUtils.js";
|
||||
import { iconLoader, LAYERFORGE_TOOLS } from "./utils/IconLoader.js";
|
||||
@@ -541,10 +542,7 @@ async function createCanvasWidget(node, widget, app) {
|
||||
iconContainer.appendChild(img);
|
||||
}
|
||||
else if (icon instanceof HTMLCanvasElement) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 16;
|
||||
canvas.height = 16;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const { canvas, ctx } = createCanvas(16, 16);
|
||||
if (ctx) {
|
||||
ctx.drawImage(icon, 0, 0, 16, 16);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { processImageToMask, processMaskForViewport } from "./utils/MaskProcessi
|
||||
import { convertToImage } from "./utils/ImageUtils.js";
|
||||
import { updateNodePreview } from "./utils/PreviewUtils.js";
|
||||
import { mask_editor_showing, mask_editor_listen_for_cancel } from "./utils/mask_utils.js";
|
||||
import { createCanvas } from "./utils/CommonUtils.js";
|
||||
const log = createModuleLogger('MaskEditorIntegration');
|
||||
export class MaskEditorIntegration {
|
||||
constructor(canvas) {
|
||||
@@ -283,10 +284,7 @@ export class MaskEditorIntegration {
|
||||
return null;
|
||||
}
|
||||
const maskCanvas = this.maskTool.maskCanvas;
|
||||
const savedCanvas = document.createElement('canvas');
|
||||
savedCanvas.width = maskCanvas.width;
|
||||
savedCanvas.height = maskCanvas.height;
|
||||
const savedCtx = savedCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: savedCanvas, ctx: savedCtx } = createCanvas(maskCanvas.width, maskCanvas.height, '2d', { willReadFrequently: true });
|
||||
if (savedCtx) {
|
||||
savedCtx.drawImage(maskCanvas, 0, 0);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ export class MaskTool {
|
||||
this.currentDrawingChunk = null;
|
||||
this.maxActiveChunks = 25; // Safety limit to prevent memory issues (5x5 grid max)
|
||||
// Create active mask canvas (composite of chunks)
|
||||
this.activeMaskCanvas = document.createElement('canvas');
|
||||
const activeMaskCtx = this.activeMaskCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: activeMaskCanvas, ctx: activeMaskCtx } = createCanvas(1, 1, '2d', { willReadFrequently: true });
|
||||
if (!activeMaskCtx) {
|
||||
throw new Error("Failed to get 2D context for active mask canvas");
|
||||
}
|
||||
this.activeMaskCanvas = activeMaskCanvas;
|
||||
this.activeMaskCtx = activeMaskCtx;
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
@@ -32,20 +32,20 @@ export class MaskTool {
|
||||
this.brushHardness = 0.5;
|
||||
this.isDrawing = false;
|
||||
this.lastPosition = null;
|
||||
this.previewCanvas = document.createElement('canvas');
|
||||
const previewCtx = this.previewCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: previewCanvas, ctx: previewCtx } = createCanvas(1, 1, '2d', { willReadFrequently: true });
|
||||
if (!previewCtx) {
|
||||
throw new Error("Failed to get 2D context for preview canvas");
|
||||
}
|
||||
this.previewCanvas = previewCanvas;
|
||||
this.previewCtx = previewCtx;
|
||||
this.previewVisible = false;
|
||||
this.previewCanvasInitialized = false;
|
||||
// Initialize shape preview system
|
||||
this.shapePreviewCanvas = document.createElement('canvas');
|
||||
const shapePreviewCtx = this.shapePreviewCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: shapePreviewCanvas, ctx: shapePreviewCtx } = createCanvas(1, 1, '2d', { willReadFrequently: true });
|
||||
if (!shapePreviewCtx) {
|
||||
throw new Error("Failed to get 2D context for shape preview canvas");
|
||||
}
|
||||
this.shapePreviewCanvas = shapePreviewCanvas;
|
||||
this.shapePreviewCtx = shapePreviewCtx;
|
||||
this.shapePreviewVisible = false;
|
||||
this.isPreviewMode = false;
|
||||
@@ -1262,10 +1262,7 @@ export class MaskTool {
|
||||
getMaskForOutputArea() {
|
||||
const bounds = this.canvasInstance.outputAreaBounds;
|
||||
// Create canvas sized to output area
|
||||
const outputMaskCanvas = document.createElement('canvas');
|
||||
outputMaskCanvas.width = bounds.width;
|
||||
outputMaskCanvas.height = bounds.height;
|
||||
const outputMaskCtx = outputMaskCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const { canvas: outputMaskCanvas, ctx: outputMaskCtx } = createCanvas(bounds.width, bounds.height, '2d', { willReadFrequently: true });
|
||||
if (!outputMaskCtx) {
|
||||
throw new Error("Failed to get 2D context for output area mask canvas");
|
||||
}
|
||||
@@ -1304,7 +1301,8 @@ export class MaskTool {
|
||||
const oldHeight = oldMask.height;
|
||||
const isIncreasingWidth = width > this.canvasInstance.width;
|
||||
const isIncreasingHeight = height > this.canvasInstance.height;
|
||||
this.activeMaskCanvas = document.createElement('canvas');
|
||||
const { canvas: activeMaskCanvas } = createCanvas(1, 1, '2d', { willReadFrequently: true });
|
||||
this.activeMaskCanvas = activeMaskCanvas;
|
||||
const extraSpace = 2000;
|
||||
const newWidth = isIncreasingWidth ? width + extraSpace : Math.max(oldWidth, width + extraSpace);
|
||||
const newHeight = isIncreasingHeight ? height + extraSpace : Math.max(oldHeight, height + extraSpace);
|
||||
|
||||
Reference in New Issue
Block a user