Files
melMass-comfy_mtb/web/color_widget.js
T
melMass 4c41fe7af9 chore: 🚀 push leftovers
this PR is mostly done
2023-07-06 00:11:52 +02:00

195 lines
6.5 KiB
JavaScript

// Define the Color Picker widget class
import parseCss from '/extensions/mtb/extern/parse-css.js'
import { app } from "/scripts/app.js";
import { ComfyWidgets } from "/scripts/widgets.js";
export 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)
),
};
}
const dumb_call = (v, d, node) => {
console.log("dumb_call", { v, d, node });
}
function isColorBright(rgb, threshold = 240) {
const brightess = getBrightness(rgb)
return brightess > threshold
}
function getBrightness(rgbObj) {
return Math.round(((parseInt(rgbObj[0]) * 299) + (parseInt(rgbObj[1]) * 587) + (parseInt(rgbObj[2]) * 114)) / 1000)
}
/**
* @returns {import("/types/litegraph").IWidget} widget
*/
const custom = (key, val, compute = false) => {
/** @type {import("/types/litegraph").IWidget} */
const widget = {}
// widget.y = 0;
widget.name = key;
widget.type = "COLOR";
widget.options = { default: "#ff0000" };
widget.value = val || "#ff0000";
widget.draw = function (ctx,
node,
widgetWidth,
widgetY,
height) {
const border = 3;
// draw a rect with a border and a fill color
ctx.fillStyle = "#000";
ctx.fillRect(0, widgetY, widgetWidth, height);
ctx.fillStyle = this.value;
ctx.fillRect(border, widgetY + border, widgetWidth - border * 2, height - border * 2);
// write the input name
// choose the fill based on the luminoisty of this.value color
const color = parseCss(this.value.default || this.value)
if (!color) {
return
}
ctx.fillStyle = isColorBright(color.values, 125) ? "#000" : "#fff";
ctx.font = "14px Arial";
ctx.textAlign = "center";
ctx.fillText(this.name, widgetWidth * 0.5, widgetY + 14);
// ctx.strokeStyle = "#fff";
// ctx.strokeRect(border, widgetY + border, widgetWidth - border * 2, height - border * 2);
// ctx.fillStyle = "#000";
// ctx.fillRect(widgetWidth/2 - border / 2 , widgetY + border / 2 , widgetWidth/2 + border / 2, height + border / 2);
// ctx.fillStyle = this.value;
// ctx.fillRect(widgetWidth/2, widgetY, widgetWidth/2, height);
}
widget.mouse = function (e, pos, node) {
if (e.type === "pointerdown") {
// get widgets of type type : "COLOR"
const widgets = node.widgets.filter(w => w.type === "COLOR");
for (const w of widgets) {
// color picker
const rect = [w.last_y, w.last_y + 32];
if (pos[1] > rect[0] && pos[1] < rect[1]) {
console.log("color picker", node)
const picker = document.createElement("input");
picker.type = "color";
picker.value = this.value;
// picker.style.position = "absolute";
// picker.style.left = ( pos[0]) + "px";
// picker.style.top = ( pos[1]) + "px";
// place at screen center
// picker.style.position = "absolute";
// picker.style.left = (window.innerWidth / 2) + "px";
// picker.style.top = (window.innerHeight / 2) + "px";
// picker.style.transform = "translate(-50%, -50%)";
// picker.style.zIndex = 1000;
document.body.appendChild(picker);
picker.addEventListener("change", () => {
this.value = picker.value;
node.graph._version++;
node.setDirtyCanvas(true, true);
document.body.removeChild(picker);
});
// simulate click with screen center
const pointer_event = new MouseEvent('click', {
bubbles: false,
// cancelable: true,
pointerType: "mouse",
clientX: window.innerWidth / 2,
clientY: window.innerHeight / 2,
x: window.innerWidth / 2,
y: window.innerHeight / 2,
offsetX: window.innerWidth / 2,
offsetY: window.innerHeight / 2,
screenX: window.innerWidth / 2,
screenY: window.innerHeight / 2,
});
console.log(e)
picker.dispatchEvent(pointer_event);
}
}
}
}
widget.computeSize = function (width) {
return [width, 32];
}
return widget;
}
app.registerExtension({
name: "mtb.ColorPicker",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
//console.log("mtb.ColorPicker", { nodeType, nodeData, app });
const rinputs = nodeData.input?.required; // object with key/value pairs, "0" is the type
// console.log(nodeData.name, { nodeType, nodeData, app });
if (!rinputs) return;
let has_color = false;
for (const [key, input] of Object.entries(rinputs)) {
if (input[0] === "COLOR") {
has_color = true;
// input[1] = { default: "#ff0000" };
}
}
if (!has_color) return;
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
this.serialize_widgets = true;
// if (rinputs[0] === "COLOR") {
// console.log(nodeData.name, { nodeType, nodeData, app });
// loop through the inputs to find the color inputs
for (const [key, input] of Object.entries(rinputs)) {
if (input[0] === "COLOR") {
let widget = custom(key, input[1])
this.addCustomWidget(widget)
}
// }
}
this.onRemoved = function () {
// When removing this node we need to remove the input from the DOM
for (let y in this.widgets) {
if (this.widgets[y].canvas) {
this.widgets[y].canvas.remove();
}
}
};
}
}
});