Files
RomanKuschanow-ComfyUI-Adva…/js/offset.js
T
2024-04-04 18:03:25 +03:00

192 lines
5.1 KiB
JavaScript

import { app } from "/scripts/app.js";
import {addCanvas, computeCanvasSize, generatePattern, recursiveLinkUpstream, renameNodeInputs, removeNodeInputs} from "./utils.js";
function drawSquares(ctx, widgetX, widgetY, squareSize, pattern) {
const actualSquareSize = squareSize - Math.floor(squareSize / 16);
widgetY += Math.floor(squareSize / 16) / 2;
widgetX += Math.floor(squareSize / 16) / 2;
pattern.forEach((value, index) => {
const x = widgetX + index * squareSize;
ctx.fillStyle = value === 1 ? "#222223" : "#00000000";
ctx.strokeStyle = "#222223";
ctx.lineWidth = Math.floor(squareSize / 16);
if (value === 1) {
ctx.fillRect(x, widgetY, actualSquareSize, actualSquareSize);
}
ctx.strokeRect(x, widgetY, actualSquareSize, actualSquareSize);
if (squareSize >= 24) {
ctx.font = `bold ${squareSize/3}px Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.text
ctx.fillStyle = value === 1 ? "#dbdbdc" : "#222223";
ctx.fillText(value.toString(), x + actualSquareSize/2, widgetY + actualSquareSize/2);
}
});
}
const offsetWidget = {
type: "customCanvas",
name: "Offset-Canvas",
get value() {
return this.canvas.value;
},
set value(x) {
this.canvas.value = x;
},
draw: function (ctx, node, widgetWidth, widgetY) {
if (!node.canvasHeight) {
computeCanvasSize(node, node.size)
}
let patterns = []
if (node.type === "OffsetCombine") {
const connectedNodes = recursiveLinkUpstream(node, node.inputs[0].type, node.type, 0)
if (connectedNodes.length !== 0) {
for (let [node_ID, depth] of connectedNodes) {
const connectedNode = node.graph._nodes_by_id[node_ID]
if (connectedNode.type !== "OffsetCombine") {
const pattern = {
process_every: connectedNode.widgets[0].value,
offset: connectedNode.widgets[1].value + node.widgets[0].value,
mode: connectedNode.widgets[2].value
}
patterns.push(pattern)
}
}
}
} else {
const pattern = {
process_every: node.widgets[0].value,
offset: node.widgets[1].value,
mode: node.widgets[2].value}
patterns.push(pattern)
}
const pattern = generatePattern(patterns)
const visible = true
const t = ctx.getTransform();
const margin = 10
const widgetHeight = node.canvasHeight
const width = pattern.length * 32
const height = 32
const scale = Math.min((widgetWidth-margin*2)/width, (widgetHeight-margin*2)/height)
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
if (backgroundHeight < widgetHeight) {
yOffset += (widgetHeight-backgroundHeight)/2 - margin
}
let widgetX = xOffset
widgetY = widgetY + yOffset
const squareSize = backgroundWidth / pattern.length;
drawSquares(ctx, widgetX, widgetY, squareSize, pattern)
ctx.fillStyle = "#ffffff88"
ctx.fillRect(widgetX, widgetY, backgroundWidth, backgroundHeight);
},
};
app.registerExtension({
name: "Comfy.LatentControl.TransformOffset",
async beforeRegisterNodeDef (nodeType, nodeData, app){
if (nodeData.name === "TransformOffset") {
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
addCanvas(this, app, offsetWidget)
return r;
}
}
},
});
app.registerExtension({
name: "Comfy.LatentControl.OffsetCombine",
async beforeRegisterNodeDef (nodeType, nodeData, app){
if (nodeData.name === "OffsetCombine") {
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
addCanvas(this, app, offsetWidget)
this.getExtraMenuOptions = function(_, options) {
options.unshift(
{
content: `add offset`,
callback: () => {
this.addInput("offset", "OFFSET")
renameNodeInputs(this, "offset")
this.setDirtyCanvas(true);
},
},
{
content: `remove offset`,
callback: () => {
removeNodeInputs(this, [this.inputs.length-1])
renameNodeInputs(this, "offset")
},
},
{
content: "remove all unconnected offsets",
callback: () => {
let indexesToRemove = []
for (let i = 0; i < this.inputs.length; i++) {
if (!this.inputs[i].link) {
indexesToRemove.push(i)
}
}
if (indexesToRemove.length) {
removeNodeInputs(this, indexesToRemove)
}
renameNodeInputs(this, "offset")
},
},
);
}
return r;
}
}
},
});