125 lines
3.7 KiB
JavaScript
125 lines
3.7 KiB
JavaScript
import { app } from "../../../scripts/app.js";
|
|
|
|
function normalizeHexColor(value, fallback = "#000000") {
|
|
if (typeof value !== "string") {
|
|
return fallback;
|
|
}
|
|
|
|
const normalized = value.startsWith("#") ? value : `#${value}`;
|
|
return /^#[0-9a-fA-F]{6}$/.test(normalized) ? normalized : fallback;
|
|
}
|
|
|
|
function getBrightness(hexColor) {
|
|
const hex = normalizeHexColor(hexColor).slice(1);
|
|
const r = parseInt(hex.slice(0, 2), 16);
|
|
const g = parseInt(hex.slice(2, 4), 16);
|
|
const b = parseInt(hex.slice(4, 6), 16);
|
|
return (r * 299 + g * 587 + b * 114) / 1000;
|
|
}
|
|
|
|
function createColorWidget(name, value) {
|
|
const widget = {
|
|
name,
|
|
type: "SMART_COLOR",
|
|
value: normalizeHexColor(value),
|
|
options: { default: "#000000" },
|
|
draw(ctx, node, widgetWidth, widgetY, height) {
|
|
const border = 3;
|
|
|
|
ctx.fillStyle = "#000";
|
|
ctx.fillRect(0, widgetY, widgetWidth, height);
|
|
|
|
ctx.fillStyle = this.value;
|
|
ctx.fillRect(
|
|
border,
|
|
widgetY + border,
|
|
widgetWidth - border * 2,
|
|
height - border * 2
|
|
);
|
|
|
|
ctx.fillStyle = getBrightness(this.value) > 125 ? "#000" : "#fff";
|
|
ctx.font = "14px Arial";
|
|
ctx.textAlign = "center";
|
|
ctx.fillText(this.name, widgetWidth * 0.5, widgetY + 14);
|
|
},
|
|
mouse(event, pos, node) {
|
|
if (event.type !== "pointerdown") {
|
|
return false;
|
|
}
|
|
|
|
const widgets = node.widgets.filter((widgetItem) => widgetItem.type === "SMART_COLOR");
|
|
|
|
for (const colorWidget of widgets) {
|
|
const rect = [colorWidget.last_y, colorWidget.last_y + 32];
|
|
if (pos[1] <= rect[0] || pos[1] >= rect[1]) {
|
|
continue;
|
|
}
|
|
|
|
const picker = document.createElement("input");
|
|
picker.type = "color";
|
|
picker.value = normalizeHexColor(this.value);
|
|
|
|
Object.assign(picker.style, {
|
|
position: "fixed",
|
|
left: `${event.clientX}px`,
|
|
top: `${event.clientY}px`,
|
|
height: "0px",
|
|
width: "0px",
|
|
padding: "0px",
|
|
opacity: 0,
|
|
});
|
|
|
|
picker.addEventListener("blur", () => {
|
|
this.callback?.(this.value);
|
|
node.graph._version++;
|
|
picker.remove();
|
|
});
|
|
|
|
picker.addEventListener("input", () => {
|
|
if (!picker.value) {
|
|
return;
|
|
}
|
|
|
|
this.value = normalizeHexColor(picker.value, this.value);
|
|
app.canvas.setDirty(true);
|
|
});
|
|
|
|
document.body.appendChild(picker);
|
|
|
|
requestAnimationFrame(() => {
|
|
if (picker.showPicker) {
|
|
picker.showPicker();
|
|
} else {
|
|
picker.click();
|
|
}
|
|
picker.focus();
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
computeSize(width) {
|
|
return [width, 32];
|
|
},
|
|
};
|
|
|
|
return widget;
|
|
}
|
|
|
|
app.registerExtension({
|
|
name: "Comfy.SmartNodes.SmartColorWidget",
|
|
getCustomWidgets() {
|
|
return {
|
|
SMART_COLOR: (node, inputName, inputData) => ({
|
|
widget: node.addCustomWidget(
|
|
createColorWidget(inputName, inputData?.[1]?.default || "#000000")
|
|
),
|
|
minWidth: 150,
|
|
minHeight: 32,
|
|
}),
|
|
};
|
|
},
|
|
});
|