diff --git a/README.md b/README.md index 322a2bd..d316d6f 100644 --- a/README.md +++ b/README.md @@ -183,8 +183,8 @@ - Mask Floor Region: Return the lower most pixel values as white (255) - Mask Threshold Region: Apply a thresholded image between a black value and white value - Mask Gaussian Region: Apply a Gaussian blur to the mask - - Mask Rect Area: Create a rectangular mask defined by percentages, includes preview canvas. - - Mask Rect Area (Advanced): Create a rectangular mask defined by pixels and image size, includes preview canvas. + - Mask Rect Area: Create a rectangular mask defined by percentages. + - Mask Rect Area (Advanced): Create a rectangular mask defined by pixels and image size. - Masks Combine Masks: Combine 2 or more masks into one mask. - Masks Combine Batch: Combine batched masks into one mask. - Model Input Switch: Switch between two model inputs based on a boolean switch diff --git a/WAS_Node_Suite.py b/WAS_Node_Suite.py index 2eb9a0e..df908e2 100644 --- a/WAS_Node_Suite.py +++ b/WAS_Node_Suite.py @@ -8139,6 +8139,11 @@ class WAS_Mask_Rect_Area: def INPUT_TYPES(cls): return { "required": { + "x": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}), + "y": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}), + "w": ("INT", {"default": 50, "min": 0, "max": 100, "step": 1}), + "h": ("INT", {"default": 50, "min": 0, "max": 100, "step": 1}), + "blur_radius": ("INT", {"default": 0, "min": 0, "max": 255, "step": 1}), }, "hidden": {"extra_pnginfo": "EXTRA_PNGINFO", "unique_id": "UNIQUE_ID"} } @@ -8151,20 +8156,12 @@ class WAS_Mask_Rect_Area: FUNCTION = "rect_mask" def rect_mask(self, extra_pnginfo, unique_id, **kwargs): - # search for node - node_found = False - for node in extra_pnginfo["workflow"]["nodes"]: - if node["id"] == int(unique_id): - min_x = node["properties"].get("x", 0) / 100 - min_y = node["properties"].get("y", 0) / 100 - width = node["properties"].get("w", 0) / 100 - height = node["properties"].get("h", 0) / 100 - blur_radius = node["properties"].get("blur_radius", 0) - node_found = True - break - - if not node_found: - raise ValueError("No node found with unique_id {unique_id}.") + # Get node values + min_x = kwargs["x"] / 100 + min_y = kwargs["y"] / 100 + width = kwargs["w"] / 100 + height = kwargs["h"] / 100 + blur_radius = kwargs["blur_radius"] # Create a mask with standard resolution (e.g., 512x512) resolution = 512 @@ -8209,6 +8206,13 @@ class WAS_Mask_Rect_Area_Advanced: def INPUT_TYPES(cls): return { "required": { + "x": ("INT", {"default": 0, "min": 0, "max": 4096, "step": 64}), + "y": ("INT", {"default": 0, "min": 0, "max": 4096, "step": 64}), + "w": ("INT", {"default": 256, "min": 0, "max": 4096, "step": 64}), + "h": ("INT", {"default": 256, "min": 0, "max": 4096, "step": 64}), + "image_width": ("INT", {"default": 512, "min": 64, "max": 4096, "step": 64}), + "image_height": ("INT", {"default": 512, "min": 64, "max": 4096, "step": 64}), + "blur_radius": ("INT", {"default": 0, "min": 0, "max": 255, "step": 1}), }, "hidden": {"extra_pnginfo": "EXTRA_PNGINFO", "unique_id": "UNIQUE_ID"} } @@ -8221,22 +8225,14 @@ class WAS_Mask_Rect_Area_Advanced: FUNCTION = "rect_mask_adv" def rect_mask_adv(self, extra_pnginfo, unique_id, **kwargs): - # search for node - node_found = False - for node in extra_pnginfo["workflow"]["nodes"]: - if node["id"] == int(unique_id): - min_x = node["properties"]["x"] - min_y = node["properties"]["y"] - width = node["properties"]["w"] - height = node["properties"]["h"] - image_width = node["properties"]["width"] - image_height = node["properties"]["height"] - blur_radius = node["properties"]["blur_radius"] - node_found = True - break - - if not node_found: - raise ValueError("No node found with unique_id {unique_id}.") + # Get node values + min_x = kwargs["x"] + min_y = kwargs["y"] + width = kwargs["w"] + height = kwargs["h"] + image_width = kwargs["image_width"] + image_height = kwargs["image_height"] + blur_radius = kwargs["blur_radius"] # Calculate maximum coordinates max_x = min_x + width diff --git a/js/was_mask_rect_area.js b/js/was_mask_rect_area.js deleted file mode 100644 index cd90855..0000000 --- a/js/was_mask_rect_area.js +++ /dev/null @@ -1,366 +0,0 @@ -import { app } from "/scripts/app.js"; -function showPreviewCanvas(node, app) { - - const widget = { - type: "customCanvas", - name: "mask-rect-area-canvas", - get value() { - return this.canvas.value; - }, - set value(x) { - this.canvas.value = x; - }, - draw: function (ctx, node, widgetWidth, widgetY) { - - // If we are initially offscreen when created we wont have received a resize event - // Calculate it here instead - if (!node.canvasHeight) { - computeCanvasSize(node, node.size); - } - - const visible = true; - const t = ctx.getTransform(); - const margin = 12; - const border = 2; - const widgetHeight = node.canvasHeight; - const width = 512; - const height = 512; - const scale = Math.min((widgetWidth - margin * 3) / width, (widgetHeight - margin * 3) / height); - const blurRadius = node.properties["blur_radius"] || 0; - const index = 0; - - Object.assign(this.canvas.style, { - left: `${t.e}px`, - top: `${t.f + (widgetY * t.d)}px`, - width: `${widgetWidth * t.a}px`, - height: `${widgetHeight * t.d}px`, - position: "absolute", - zIndex: 1, - fontSize: `${t.d * 10.0}px`, - pointerEvents: "none" - }); - - this.canvas.hidden = !visible; - - let backgroundWidth = width * scale; - let backgroundHeight = height * scale; - let xOffset = margin; - if (backgroundWidth < widgetWidth) { - xOffset += (widgetWidth - backgroundWidth) / 2 - margin; - } - let yOffset = (margin / 2); - if (backgroundHeight < widgetHeight) { - yOffset += (widgetHeight - backgroundHeight) / 2 - margin; - } - - let widgetX = xOffset; - widgetY = widgetY + yOffset; - - // Draw the background border - ctx.fillStyle = globalThis.LiteGraph.WIDGET_OUTLINE_COLOR; - ctx.fillRect(widgetX - border, widgetY - border, backgroundWidth + border * 2, backgroundHeight + border * 2); - - // Draw the main background area - ctx.fillStyle = globalThis.LiteGraph.WIDGET_BGCOLOR; - ctx.fillRect(widgetX, widgetY, backgroundWidth, backgroundHeight); - - // Draw the conditioning zone - let [x, y, w, h] = getDrawArea(node, backgroundWidth, backgroundHeight); - - ctx.fillStyle = getDrawColor(0, "80"); - ctx.fillRect(widgetX + x, widgetY + y, w, h); - ctx.beginPath(); - ctx.lineWidth = 1; - - // Draw grid lines - for (let x = 0; x <= width / 64; x += 1) { - ctx.moveTo(widgetX + x * 64 * scale, widgetY); - ctx.lineTo(widgetX + x * 64 * scale, widgetY + backgroundHeight); - } - - for (let y = 0; y <= height / 64; y += 1) { - ctx.moveTo(widgetX, widgetY + y * 64 * scale); - ctx.lineTo(widgetX + backgroundWidth, widgetY + y * 64 * scale); - } - - ctx.strokeStyle = "#66666650"; - ctx.stroke(); - ctx.closePath(); - - // Draw current zone - let [sx, sy, sw, sh] = getDrawArea(node, backgroundWidth, backgroundHeight); - - ctx.fillStyle = getDrawColor(0, "80"); - ctx.fillRect(widgetX + sx, widgetY + sy, sw, sh); - - ctx.fillStyle = getDrawColor(0, "40"); - ctx.fillRect(widgetX + sx + border, widgetY + sy + border, sw - border * 2, sh - border * 2); - - // Draw white border around the current zone - ctx.strokeStyle = globalThis.LiteGraph.NODE_SELECTED_TITLE_COLOR; - ctx.lineWidth = 2; - ctx.strokeRect(widgetX + sx, widgetY + sy, sw, sh); - //ctx.strokeRect(finalSX, finalSY, finalSW, finalSH); - - // Display - ctx.beginPath(); - - ctx.arc(LiteGraph.NODE_SLOT_HEIGHT * 0.5, LiteGraph.NODE_SLOT_HEIGHT * (index + 0.5) + 4, 4, 0, Math.PI * 2); - ctx.fill(); - - ctx.lineWidth = 1; - ctx.strokeStyle = "white"; - ctx.stroke(); - ctx.lineWidth = 1; - ctx.closePath(); - - // Draw progress bar canvas - if (backgroundWidth < widgetWidth) { - xOffset += (widgetWidth - backgroundWidth) / 2 - margin; - } - - const barHeight = 8; - let widgetYBar = widgetY + backgroundHeight + margin; - - // Draw progress bar border - ctx.fillStyle = globalThis.LiteGraph.WIDGET_OUTLINE_COLOR; - ctx.fillRect( - widgetX - border, - widgetYBar - border, - backgroundWidth + border * 2, - barHeight + border * 2 - ); - - // Draw progress bar area - ctx.fillStyle = globalThis.LiteGraph.WIDGET_BGCOLOR; // Mismo color de fondo que el canvas - ctx.fillRect( - widgetX, - widgetYBar, - backgroundWidth, - barHeight - ); - - // Draw progress bar grid - ctx.beginPath(); - ctx.lineWidth = 1; - ctx.strokeStyle = "#66666650"; - - // Determine max lines - const numLines = Math.floor(backgroundWidth / 64); - - // Draw progress bar grid - for (let x = 0; x <= width / 64; x += 1) { - ctx.moveTo(widgetX + x * 64 * scale, widgetYBar); - ctx.lineTo(widgetX + x * 64 * scale, widgetYBar + barHeight); - } - ctx.stroke(); - ctx.closePath(); - - // Draw progress bar - const progress = Math.min(blurRadius / 255, 1); - ctx.fillStyle = "rgba(0, 120, 255, 0.5)"; - - ctx.fillRect( - widgetX, - widgetYBar, - backgroundWidth * progress, - barHeight - ); - } - }; - - widget.canvas = document.createElement("canvas"); - widget.canvas.className = "mask-rect-area-canvas"; - widget.parent = node; - - document.body.appendChild(widget.canvas); - node.addCustomWidget(widget); - - app.canvas.onDrawBackground = function () { - // Draw node isnt fired once the node is off the screen - // if it goes off screen quickly, the input may not be removed - // this shifts it off screen so it can be moved back if the node is visible. - for (let n in app.graph._nodes) { - n = app.graph._nodes[n]; - for (let w in n.widgets) { - let wid = n.widgets[w]; - if (Object.hasOwn(wid, "canvas")) { - wid.canvas.style.left = -8000 + "px"; - wid.canvas.style.position = "absolute"; - } - } - } - }; - - node.onResize = function (size) { - computeCanvasSize(node, size); - }; - - return {minWidth: 200, minHeight: 200, widget}; -} - -app.registerExtension({ - name: 'was.WAS_Mask_Rect_Area', - async beforeRegisterNodeDef(nodeType, nodeData, app) { - if (nodeData.name === "Mask Rect Area") { - const onNodeCreated = nodeType.prototype.onNodeCreated; - nodeType.prototype.onNodeCreated = function () { - const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined; - - this.setProperty("width", 512); - this.setProperty("height", 512); - this.setProperty("x", 0); - this.setProperty("y", 0); - this.setProperty("w", 50); - this.setProperty("h", 50); - this.setProperty("blur_radius", 0); - - this.selected = false; - this.index = 3; - this.serialize_widgets = true; - - CUSTOM_INT(this, "x", 0, function (v, _, node) { - this.value = Math.max(0, Math.min(100, Math.round(v))); // Limitar entre 0 y 100 - node.properties["x"] = this.value; - }); - CUSTOM_INT(this, "y", 0, function (v, _, node) { - this.value = Math.max(0, Math.min(100, Math.round(v))); - node.properties["y"] = this.value; - }); - CUSTOM_INT(this, "w", 50, function (v, _, node) { - this.value = Math.max(0, Math.min(100, Math.round(v))); - node.properties["w"] = this.value; - }); - CUSTOM_INT(this, "h", 50, function (v, _, node) { - this.value = Math.max(0, Math.min(100, Math.round(v))); - node.properties["h"] = this.value; - }); - CUSTOM_INT(this, "blur_radius", 0, function (v, _, node) { - this.value = Math.round(v) || 0; - node.properties["blur_radius"] = this.value; - }, - {"min": 0, "max": 255, "step": 10} - ); - - showPreviewCanvas(this, app); - - this.onSelected = function () { - this.selected = true; - }; - this.onDeselected = function () { - this.selected = false; - }; - - return r; - }; - } - } -}); - -// Calculate the drawing area using percentage-based properties. -function getDrawArea(node, backgroundWidth, backgroundHeight) { - // Convert percentages to actual pixel values based on the background dimensions - let x = (node.properties["x"] / 100) * backgroundWidth; - let y = (node.properties["y"] / 100) * backgroundHeight; - let w = (node.properties["w"] / 100) * backgroundWidth; - let h = (node.properties["h"] / 100) * backgroundHeight; - - // Ensure the values do not exceed the background boundaries - if (x > backgroundWidth) { - x = backgroundWidth; - } - if (y > backgroundHeight) { - y = backgroundHeight; - } - - // Adjust width and height to fit within the background dimensions - if (x + w > backgroundWidth) { - w = Math.max(0, backgroundWidth - x); - } - if (y + h > backgroundHeight) { - h = Math.max(0, backgroundHeight - y); - } - - return [x, y, w, h]; -} - -function CUSTOM_INT(node, inputName, val, func, config = {}) { - return { - widget: node.addWidget( - "number", - inputName, - val, - func, - Object.assign({}, {min: 0, max: 100, step: 10, precision: 0}, config) - ) - }; -} - -function getDrawColor(percent, alpha) { - let h = 360 * percent; - let s = 50; - let l = 50; - l /= 100; - const a = s * Math.min(l, 1 - l) / 100; - const f = n => { - const k = (n + h / 30) % 12; - const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); - return Math.round(255 * color).toString(16).padStart(2, '0'); // convert to Hex and prefix "0" if needed - }; - return `#${f(0)}${f(8)}${f(4)}${alpha}`; -} - -function computeCanvasSize(node, size) { - if (node.widgets[0].last_y == null) { - return; - } - - const MIN_HEIGHT = 200; - const MIN_WIDTH = 200; - - let y = LiteGraph.NODE_WIDGET_HEIGHT * Math.max(node.inputs.length, node.outputs.length) + 5; - let freeSpace = size[1] - y; - - // Compute the height of all non-customCanvas widgets - let widgetHeight = 0; - for (let i = 0; i < node.widgets.length; i++) { - const w = node.widgets[i]; - if (w.type !== "customCanvas") { - if (w.computeSize) { - widgetHeight += w.computeSize()[1] + 4; - } else { - widgetHeight += LiteGraph.NODE_WIDGET_HEIGHT + 5; - } - } - } - - // Ensure there is enough vertical space - freeSpace -= widgetHeight; - - // Adjust the height of the node if needed - if (freeSpace < MIN_HEIGHT) { - freeSpace = MIN_HEIGHT; - node.size[1] = y + widgetHeight + freeSpace; - node.graph.setDirtyCanvas(true); - } - - // Ensure the node width meets the minimum width requirement - if (node.size[0] < MIN_WIDTH) { - node.size[0] = MIN_WIDTH; - node.graph.setDirtyCanvas(true); - } - - // Position each of the widgets - for (const w of node.widgets) { - w.y = y; - if (w.type === "customCanvas") { - y += freeSpace; - } else if (w.computeSize) { - y += w.computeSize()[1] + 4; - } else { - y += LiteGraph.NODE_WIDGET_HEIGHT + 4; - } - } - - node.canvasHeight = freeSpace; -} diff --git a/js/was_mask_rect_area_advanced.js b/js/was_mask_rect_area_advanced.js deleted file mode 100644 index a2332d7..0000000 --- a/js/was_mask_rect_area_advanced.js +++ /dev/null @@ -1,381 +0,0 @@ -import { app } from "/scripts/app.js"; -function showPreviewCanvas(node, app) { - - const widget = { - type: "customCanvas", - name: "mask-rect-area-canvas", - get value() { - return this.canvas.value; - }, - set value(x) { - this.canvas.value = x; - }, - draw: function (ctx, node, widgetWidth, widgetY) { - - // If we are initially offscreen when created we wont have received a resize event - // Calculate it here instead - if (!node.canvasHeight) { - computeCanvasSize(node, node.size); - } - - const visible = true; - const t = ctx.getTransform(); - const margin = 12; - const border = 2; - const widgetHeight = node.canvasHeight; - const width = Math.round(node.properties["width"]); - const height = Math.round(node.properties["height"]); - const scale = Math.min((widgetWidth - margin * 3) / width, (widgetHeight - margin * 3) / height); - const blurRadius = node.properties["blur_radius"] || 0; - const index = 0; - - Object.assign(this.canvas.style, { - left: `${t.e}px`, - top: `${t.f + (widgetY * t.d)}px`, - width: `${widgetWidth * t.a}px`, - height: `${widgetHeight * t.d}px`, - position: "absolute", - zIndex: 1, - fontSize: `${t.d * 10.0}px`, - pointerEvents: "none" - }); - - this.canvas.hidden = !visible; - - let backgroundWidth = width * scale; - let backgroundHeight = height * scale; - - let xOffset = margin; - if (backgroundWidth < widgetWidth) { - xOffset += (widgetWidth - backgroundWidth) / 2 - margin; - } - let yOffset = (margin / 2); - if (backgroundHeight < widgetHeight) { - yOffset += (widgetHeight - backgroundHeight) / 2 - margin; - } - - let widgetX = xOffset; - widgetY = widgetY + yOffset; - - // Draw the background border - ctx.fillStyle = globalThis.LiteGraph.WIDGET_OUTLINE_COLOR; - ctx.fillRect(widgetX - border, widgetY - border, backgroundWidth + border * 2, backgroundHeight + border * 2) - - // Draw the main background area - ctx.fillStyle = globalThis.LiteGraph.WIDGET_BGCOLOR; - ctx.fillRect(widgetX, widgetY, backgroundWidth, backgroundHeight); - - // Draw the conditioning zone - let [x, y, w, h] = getDrawArea(node, backgroundWidth, backgroundHeight); - - ctx.fillStyle = getDrawColor(0, "80"); - ctx.fillRect(widgetX + x, widgetY + y, w, h); - ctx.beginPath(); - ctx.lineWidth = 1; - - // Draw grid lines - for (let x = 0; x <= width / 64; x += 1) { - ctx.moveTo(widgetX + x * 64 * scale, widgetY); - ctx.lineTo(widgetX + x * 64 * scale, widgetY + backgroundHeight); - } - - for (let y = 0; y <= height / 64; y += 1) { - ctx.moveTo(widgetX, widgetY + y * 64 * scale); - ctx.lineTo(widgetX + backgroundWidth, widgetY + y * 64 * scale); - } - - ctx.strokeStyle = "#66666650"; - ctx.stroke(); - ctx.closePath(); - - // Draw current zone - let [sx, sy, sw, sh] = getDrawArea(node, backgroundWidth, backgroundHeight); - - ctx.fillStyle = getDrawColor(0, "80"); - ctx.fillRect(widgetX + sx, widgetY + sy, sw, sh); - - ctx.fillStyle = getDrawColor(0, "40"); - ctx.fillRect(widgetX + sx + border, widgetY + sy + border, sw - border * 2, sh - border * 2); - - // Draw white border around the current zone - ctx.strokeStyle = globalThis.LiteGraph.NODE_SELECTED_TITLE_COLOR; - ctx.lineWidth = 2; - ctx.strokeRect(widgetX + sx, widgetY + sy, sw, sh); - - // Display - ctx.beginPath(); - - ctx.arc(LiteGraph.NODE_SLOT_HEIGHT * 0.5, LiteGraph.NODE_SLOT_HEIGHT * (index + 0.5) + 4, 4, 0, Math.PI * 2); - ctx.fill(); - - ctx.lineWidth = 1; - ctx.strokeStyle = "white"; - ctx.stroke(); - - ctx.lineWidth = 1; - ctx.closePath(); - - // Draw progress bar canvas - if (backgroundWidth < widgetWidth) { - xOffset += (widgetWidth - backgroundWidth) / 2 - margin; - } - - // Ajustar las coordenadas X e Y - const barHeight = 8; - let widgetYBar = widgetY + backgroundHeight + margin; - - // Dibujar el borde negro alrededor de la barra - ctx.fillStyle = globalThis.LiteGraph.WIDGET_OUTLINE_COLOR; - ctx.fillRect( - widgetX - border, - widgetYBar - border, - backgroundWidth + border * 2, - barHeight + border * 2 - ); - - // Dibujar el área principal de la barra (fondo) - ctx.fillStyle = globalThis.LiteGraph.WIDGET_BGCOLOR; // Mismo color de fondo que el canvas - ctx.fillRect( - widgetX, - widgetYBar, - backgroundWidth, - barHeight - ); - - - // Draw progress bar grid - ctx.beginPath(); - ctx.lineWidth = 1; - ctx.strokeStyle = "#66666650"; - - // Calcular el número de líneas en función del tamaño de la barra - const numLines = Math.floor(backgroundWidth / 64); - - // Dibujar líneas del grid - for (let x = 0; x <= width / 64; x += 1) { - ctx.moveTo(widgetX + x * 64 * scale, widgetYBar); - ctx.lineTo(widgetX + x * 64 * scale, widgetYBar + barHeight); - } - ctx.stroke(); - ctx.closePath(); - - // Dibujar progreso (basado en blur_radius) - const progress = Math.min(blurRadius / 255, 1); - ctx.fillStyle = "rgba(0, 120, 255, 0.5)"; - - ctx.fillRect( - widgetX, - widgetYBar, - backgroundWidth * progress, - barHeight - ); - } - }; - - widget.canvas = document.createElement("canvas"); - widget.canvas.className = "mask-rect-area-canvas"; - widget.parent = node; - - document.body.appendChild(widget.canvas); - node.addCustomWidget(widget); - - app.canvas.onDrawBackground = function () { - // Draw node isnt fired once the node is off the screen - // if it goes off screen quickly, the input may not be removed - // this shifts it off screen so it can be moved back if the node is visible. - for (let n in app.graph._nodes) { - n = app.graph._nodes[n]; - for (let w in n.widgets) { - let wid = n.widgets[w]; - if (Object.hasOwn(wid, "canvas")) { - wid.canvas.style.left = -8000 + "px"; - wid.canvas.style.position = "absolute"; - } - } - } - }; - - node.onResize = function (size) { - computeCanvasSize(node, size); - }; - - return {minWidth: 200, minHeight: 200, widget}; -} - -app.registerExtension({ - name: 'was.WAS_Mask_Rect_Area_Advanced', - async beforeRegisterNodeDef(nodeType, nodeData, app) { - if (nodeData.name === "Mask Rect Area (Advanced)") { - const onNodeCreated = nodeType.prototype.onNodeCreated; - nodeType.prototype.onNodeCreated = function () { - const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined; - - this.setProperty("width", 512); - this.setProperty("height", 512); - this.setProperty("x", 0); - this.setProperty("y", 0); - this.setProperty("w", 256); - this.setProperty("h", 256); - this.setProperty("blur_radius", 0); - - this.selected = false; - this.index = 3; - this.serialize_widgets = true; - - CUSTOM_INT(this, "x", 0, function (v, _, node) { - const s = this.options.step / 10; - this.value = Math.round(v / s) * s; - node.properties["x"] = this.value; - }); - CUSTOM_INT(this, "y", 0, function (v, _, node) { - const s = this.options.step / 10; - this.value = Math.round(v / s) * s; - node.properties["y"] = this.value; - }); - CUSTOM_INT(this, "width", 256, function (v, _, node) { - const s = this.options.step / 10; - this.value = Math.round(v / s) * s; - node.properties["w"] = this.value; - }); - CUSTOM_INT(this, "height", 256, function (v, _, node) { - const s = this.options.step / 10; - this.value = Math.round(v / s) * s; - node.properties["h"] = this.value; - }); - CUSTOM_INT(this, "image_width", 512, function (v, _, node) { - const s = this.options.step / 10; - this.value = Math.round(v / s) * s; - node.properties["width"] = this.value; - }); - CUSTOM_INT(this, "image_height", 512, function (v, _, node) { - const s = this.options.step / 10; - this.value = Math.round(v / s) * s; - node.properties["height"] = this.value; - }); - CUSTOM_INT(this, "blur_radius", 0, function (v, _, node) { - this.value = Math.round(v) || 0; - node.properties["blur_radius"] = this.value; - }, - {"min": 0, "max": 255, "step": 10} - ); - - showPreviewCanvas(this, app); - - this.onSelected = function () { - this.selected = true; - }; - this.onDeselected = function () { - this.selected = false; - }; - - return r; - }; - } - } -}); - -// Calculate the drawing area using individual properties. -function getDrawArea(node, backgroundWidth, backgroundHeight) { - let x = node.properties["x"] * backgroundWidth / node.properties["width"]; - let y = node.properties["y"] * backgroundHeight / node.properties["height"]; - let w = node.properties["w"] * backgroundWidth / node.properties["width"]; - let h = node.properties["h"] * backgroundHeight / node.properties["height"]; - - if (x > backgroundWidth) { - x = backgroundWidth; - } - if (y > backgroundHeight) { - y = backgroundHeight; - } - - if (x + w > backgroundWidth) { - w = Math.max(0, backgroundWidth - x); - } - - if (y + h > backgroundHeight) { - h = Math.max(0, backgroundHeight - y); - } - - return [x, y, w, h]; -} - -function CUSTOM_INT(node, inputName, val, func, config = {}) { - return { - widget: node.addWidget( - "number", - inputName, - val, - func, - Object.assign({}, {min: 0, max: 4096, step: 640, precision: 0}, config) - ) - }; -} - -function getDrawColor(percent, alpha) { - let h = 360 * percent; - let s = 50; - let l = 50; - l /= 100; - const a = s * Math.min(l, 1 - l) / 100; - const f = n => { - const k = (n + h / 30) % 12; - const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); - return Math.round(255 * color).toString(16).padStart(2, '0'); // convert to Hex and prefix "0" if needed - }; - return `#${f(0)}${f(8)}${f(4)}${alpha}`; -} - -function computeCanvasSize(node, size) { - if (node.widgets[0].last_y == null) { - return; - } - - const MIN_HEIGHT = 220; - const MIN_WIDTH = 240; - - let y = LiteGraph.NODE_WIDGET_HEIGHT * Math.max(node.inputs.length, node.outputs.length) + 5; - let freeSpace = size[1] - y; - - // Compute the height of all non-customCanvas widgets - let widgetHeight = 0; - for (let i = 0; i < node.widgets.length; i++) { - const w = node.widgets[i]; - if (w.type !== "customCanvas") { - if (w.computeSize) { - widgetHeight += w.computeSize()[1] + 4; - } else { - widgetHeight += LiteGraph.NODE_WIDGET_HEIGHT + 5; - } - } - } - - // Ensure there is enough vertical space - freeSpace -= widgetHeight; - - // Adjust the height of the node if needed - if (freeSpace < MIN_HEIGHT) { - freeSpace = MIN_HEIGHT; - node.size[1] = y + widgetHeight + freeSpace; - node.graph.setDirtyCanvas(true); - } - - // Ensure the node width meets the minimum width requirement - if (node.size[0] < MIN_WIDTH) { - node.size[0] = MIN_WIDTH; - node.graph.setDirtyCanvas(true); - } - - // Position each of the widgets - for (const w of node.widgets) { - w.y = y; - if (w.type === "customCanvas") { - y += freeSpace; - } else if (w.computeSize) { - y += w.computeSize()[1] + 4; - } else { - y += LiteGraph.NODE_WIDGET_HEIGHT + 4; - } - } - - node.canvasHeight = freeSpace; -}