Spaces:
Runtime error
Runtime error
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: 'drltdata.MaskRectAreaAdvanced', | |
async beforeRegisterNodeDef(nodeType, nodeData, app) { | |
if (nodeData.name === "MaskRectAreaAdvanced") { | |
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; | |
} | |