import { api } from "../../../scripts/api.js"; import { app } from "../../../scripts/app.js"; import { allow_debug } from "./js_shared.js"; class ValueClass { constructor(value) { this.name = "counter"; this.value = value; } } app.registerExtension({ name: "iTools.domNode", async beforeRegisterNodeDef(nodeType, nodeData, app) { if (nodeData.name !== "iToolsDomNode") { return; } const onExecuted = nodeType.prototype.onExecuted; nodeType.prototype.onExecuted = async function (message) { onExecuted?.apply(this, arguments); if (allow_debug) console.log("iToolsDomNode executed", message); }; }, async nodeCreated(node) { if (node.comfyClass !== "iToolsDomNode") { return; } // wait for init const timeout = 3000; // 3 seconds const startTime = Date.now(); while (!node.graph) { if (Date.now() - startTime > timeout) { if (allow_debug) console.error("Timeout: Failed to load graph."); break; } if (allow_debug) console.log("loading ..."); await new Promise((resolve) => setTimeout(resolve, 200)); } function styleButton(button) { button.style.backgroundColor = "#4CAF50"; // Green background button.style.border = "none"; button.style.color = "white"; button.style.padding = "5px 12px"; button.style.textAlign = "center"; button.style.textDecoration = "none"; button.style.display = "inline-block"; button.style.fontSize = "0.8em"; button.style.margin = "4px 2px"; button.style.cursor = "pointer"; button.style.borderRadius = "4px"; } function createDiv() { const div = document.createElement("div"); div.style.visibility = "hidden"; div.id = `node-${node.id}`; div.style.width = "50px"; div.style.height = "50px"; div.style.position = "absolute"; div.style.top = "0px"; div.style.left = "0px"; div.style.backgroundColor = "crimson"; // Neutral background div.style.display = "flex"; div.style.flexDirection = "column"; div.style.alignItems = "center"; div.style.justifyContent = "center"; div.style.border = "none"; // Removed border div.style.borderRadius = "12px"; // Increased border radius div.style.padding = "5px"; // Increased padding const label0 = document.createElement("label"); label0.textContent = "HTML DOM Elements in Comfy Node"; label0.style.fontSize = "0.8em"; // Increased font size label0.style.fontWeight = "bold"; // Added font weight label0.style.marginBottom = "5px"; // Added margin bottom const label1 = document.createElement("label"); label1.textContent = "CounterApp example using vanilla js"; label1.style.fontSize = "0.7em"; // Increased font size label1.style.fontWeight = "bold"; // Added font weight label1.style.marginBottom = "5px"; // Added margin bottom const label = document.createElement("label"); label.textContent = "0"; label.style.fontSize = "2em"; // Increased font size label.style.marginBottom = "5px"; // Added margin bottom const buttonContainer = document.createElement("div"); // Container for buttons buttonContainer.style.display = "flex"; buttonContainer.style.gap = "10px"; // Added gap between buttons const btnIncrease = document.createElement("button"); btnIncrease.textContent = "+"; styleButton(btnIncrease); // Apply button styles const btnDecrease = document.createElement("button"); btnDecrease.textContent = "-"; styleButton(btnDecrease); const btnReset = document.createElement("button"); btnReset.textContent = "Reset"; styleButton(btnReset); btnIncrease.addEventListener("click", () => { label.textContent = parseInt(label.textContent) + 1; vc.value = vc.value + 1; }); btnDecrease.addEventListener("click", () => { label.textContent = parseInt(label.textContent) - 1; vc.value = vc.value - 1; }); btnReset.addEventListener("click", () => { label.textContent = "0"; vc.value = 0; }); buttonContainer.appendChild(btnIncrease); buttonContainer.appendChild(btnDecrease); buttonContainer.appendChild(btnReset); div.appendChild(label0); div.appendChild(label1); div.appendChild(label); div.appendChild(buttonContainer); document.body.appendChild(div); } function updateDivPosition(node, offsetX = 40, offsetY = 0) { if (!node || !node.pos || !node.size || !app.canvas.ds) return; const div = document.getElementById(`node-${node.id}`); if (!div) return; div.style.visibility = "visible"; const zoom = app.canvas.ds.scale || 1; const canvasOffsetX = app.canvas.ds.offset[0] || 0; const canvasOffsetY = app.canvas.ds.offset[1] || 0; // Calculate scaled dimensions with margin const scaledWidth = (node.size[0] * zoom * 95) / 100; const scaledHeight = (node.size[1] * zoom * 70) / 100; // Apply translation (include offsets) let screenX = (node.pos[0] + canvasOffsetX + offsetX / zoom) * zoom; let screenY = (node.pos[1] + canvasOffsetY + offsetY / zoom) * zoom; // Center horizontally and align to bottom screenX = screenX + (node.size[0] * zoom - scaledWidth) / 2; // Center in x-axis screenY = screenY - 10 + node.size[1] * zoom - scaledHeight; // Align to bottom div.style.width = `${scaledWidth}px`; div.style.height = `${scaledHeight}px`; div.style.transform = `translate(${screenX}px, ${screenY}px)`; div.style.borderRadius = `${zoom * 8}px`; // Disable rendering of div *content* if zoom is below a value const children = div.children; // Get all children of the div for (let i = 0; i < children.length; i++) { if (zoom < 0.6) { children[i].style.visibility = "hidden"; // Hide each child } else { children[i].style.visibility = "visible"; // Show each child } } } function deleteDiv() { // Construct the div's id based on the node's id const divId = `node-${node.id+1}`; // Retrieve the div element const div = document.getElementById(divId); // If the div exists, remove it from its parent if (div) { div.remove(); } else { console.warn(`Div with id ${divId} not found.`); } } function mousePos(node) { const graphMouse = app.canvas.graph_mouse; return { x: graphMouse[0] - node.pos[0], y: graphMouse[1] - node.pos[1], }; } function createCounterApp() { let count = 0; // Create elements const container = document.createElement("div"); container.id = `node-${node.id}`; container.style.position = "absolute"; container.style.top = "80px"; container.style.left = "80px"; const counter = document.createElement("p"); const incrementBtn = document.createElement("button"); const decrementBtn = document.createElement("button"); // Set text content counter.textContent = `Count: ${count}`; incrementBtn.textContent = "+"; decrementBtn.textContent = "-"; // Style elements container.style.display = "flex"; container.style.alignItems = "center"; container.style.gap = "10px"; counter.style.fontSize = "20px"; incrementBtn.style.padding = decrementBtn.style.padding = "5px 10px"; // Button actions incrementBtn.addEventListener("click", () => { count++; counter.textContent = `Count: ${count}`; }); decrementBtn.addEventListener("click", () => { count--; counter.textContent = `Count: ${count}`; }); // Append elements container.appendChild(decrementBtn); container.appendChild(counter); container.appendChild(incrementBtn); document.body.appendChild(container); } //START POINT node.size = [300, 300]; //init size const vc = new ValueClass(0); node.addCustomWidget(vc); //createDiv(); // Create an input element // const inputElement = document.createElement("input"); // inputElement.type = "text"; // inputElement.placeholder = "Enter text"; // // Add the input as a DOM widget // node.addDOMWidget("Text Input", "input", inputElement, { // getValue: () => inputElement.value, // setValue: (v) => (inputElement.value = v), // }); // Create a container div const counterDiv = document.createElement("div"); counterDiv.style.width = "100%"; counterDiv.style.height = "100%"; counterDiv.style.display = "flex"; counterDiv.style.alignItems = "center"; counterDiv.style.flexDirection = "column"; counterDiv.style.justifyContent = "center"; counterDiv.style.gap = "10px"; counterDiv.style.padding = "5px"; counterDiv.style.backgroundColor = "crimson"; // Create a label const label = document.createElement("label"); label.textContent = "addDOMWidget" // Create a wrapper const wrapper = document.createElement("div"); wrapper.id = `node-${node.id+1}`; wrapper.style.width = "100%"; wrapper.style.display = "flex"; wrapper.style.justifyContent = "center"; wrapper.appendChild(counterDiv); // Create a button to decrease the counter const minusButton = document.createElement("button"); minusButton.textContent = "-"; minusButton.onclick = () => updateCounter(-1); // Create a span to display the counter value const counterValue = document.createElement("span"); counterValue.textContent = "0"; // Create a button to increase the counter const plusButton = document.createElement("button"); plusButton.textContent = "+"; plusButton.onclick = () => updateCounter(1); // Append elements to the container counterDiv.appendChild(label); counterDiv.appendChild(minusButton); counterDiv.appendChild(counterValue); counterDiv.appendChild(plusButton); // Function to update the counter function updateCounter(delta) { counterValue.textContent = String(parseInt(counterValue.textContent) + delta); } // Add the counter as a DOM widget node.addDOMWidget("counter", "div", wrapper, { getValue: () => parseInt(counterValue.textContent), setValue: (v) => (counterValue.textContent = String(v)), }); //createCounterApp() node.setDirtyCanvas(true, false); if (allow_debug) console.log("node", node); if (allow_debug) console.log("app", app); //BINDING app.canvas.onMouseDown = (e) => { const nodes = app.graph.nodes; nodes.forEach((n) => { if (n.type === "iToolsDomNode") { } }); }; app.canvas.onDrawForeground = (ctx) => { const nodes = app.graph.nodes; nodes.forEach((n) => { if (n.type === "iToolsDomNode") { updateDivPosition(n); } }); }; app.canvas.canvas.onclick = (e) => { const nodes = app.graph.nodes; nodes.forEach((n) => { if (n.type === "iToolsDomNode") { } }); }; node.onRemoved = () => { deleteDiv(); }; }, });