159 lines
7.3 KiB
JavaScript
159 lines
7.3 KiB
JavaScript
import { app } from "../../scripts/app.js";
|
|
|
|
console.log("Loading Dynamic.js for Slider Stacker (Refactored)");
|
|
|
|
// --- Helper Functions --- (remain the same) ...
|
|
|
|
const findWidgetByName = (node, name) => {
|
|
return node.widgets ? node.widgets.find((w) => w.name === name) : null;
|
|
};
|
|
const getWidgetValue = (widget) => {
|
|
const val = widget?.value;
|
|
const num = Number(val);
|
|
return isNaN(num) ? 0 : num;
|
|
};
|
|
function interceptWidgetValue(node, widgetName, setterCallback) {
|
|
const widget = findWidgetByName(node, widgetName);
|
|
if (!widget) return;
|
|
let internalValueTracker = widget.value;
|
|
let originalDescriptor = Object.getOwnPropertyDescriptor(widget, 'value');
|
|
if (!originalDescriptor) {
|
|
let proto = Object.getPrototypeOf(widget);
|
|
while (proto && !originalDescriptor && proto !== Object.prototype) {
|
|
originalDescriptor = Object.getOwnPropertyDescriptor(proto, 'value');
|
|
proto = Object.getPrototypeOf(proto);
|
|
}
|
|
}
|
|
Object.defineProperty(widget, 'value', {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get() { /* ... */ return originalDescriptor?.get ? originalDescriptor.get.call(widget) : internalValueTracker; },
|
|
set(newValue) {
|
|
if (node._isUpdatingInternally) { /* ... */
|
|
if (originalDescriptor?.set) { originalDescriptor.set.call(widget, newValue); } else { internalValueTracker = newValue; }
|
|
if (widget.inputEl) { widget.inputEl.value = Number(newValue).toFixed(widget.options?.precision ?? 2); }
|
|
return;
|
|
}
|
|
const clampedNewValue = Math.max(widget.options?.min ?? -Infinity, Math.min(Number(newValue) || 0, widget.options?.max ?? Infinity));
|
|
if (originalDescriptor?.set) { originalDescriptor.set.call(widget, clampedNewValue); }
|
|
internalValueTracker = clampedNewValue;
|
|
if(widget.inputEl) { widget.inputEl.value = internalValueTracker.toFixed(widget.options?.precision ?? 2); }
|
|
setterCallback(clampedNewValue);
|
|
}
|
|
});
|
|
}
|
|
|
|
// --- Core Logic Functions --- (remain the same) ...
|
|
|
|
function recalculateCurrentMaxStrength(node) { /* ... */
|
|
const sliderCountWidget = findWidgetByName(node, "slider_count");
|
|
const count = getWidgetValue(sliderCountWidget);
|
|
let currentMaxValue = 0;
|
|
for (let i = 1; i <= count; i++) {
|
|
const wtWidget = findWidgetByName(node, `(${i})`);
|
|
if (wtWidget) {
|
|
currentMaxValue = Math.max(currentMaxValue, getWidgetValue(wtWidget));
|
|
}
|
|
}
|
|
const maxStrengthWidget = findWidgetByName(node, "slider_max_strength");
|
|
const overallMax = maxStrengthWidget?.options?.max ?? 2.0;
|
|
const overallMin = maxStrengthWidget?.options?.min ?? 0.0;
|
|
return Math.max(overallMin, Math.min(currentMaxValue, overallMax));
|
|
}
|
|
function updateNormalization(node, currentMaxStrength) { /* ... */
|
|
if (!node.normalizedSliderWeights) node.normalizedSliderWeights = {};
|
|
const sliderCountWidget = findWidgetByName(node, "slider_count");
|
|
const maxSliders = sliderCountWidget?.options?.max || 50;
|
|
for (let i = 1; i <= maxSliders; i++) {
|
|
const wtWidget = findWidgetByName(node, `(${i})`);
|
|
if (wtWidget) {
|
|
const currentWt = getWidgetValue(wtWidget);
|
|
node.normalizedSliderWeights[i] = (currentMaxStrength > 0) ? (currentWt / currentMaxStrength) : (node.normalizedSliderWeights[i] !== undefined ? node.normalizedSliderWeights[i] : 0);
|
|
}
|
|
}
|
|
}
|
|
function updateAllSliderDisplays(node, newMaxStrength) { /* ... */
|
|
if (!node.normalizedSliderWeights || node._isUpdatingInternally) return;
|
|
node._isUpdatingInternally = true;
|
|
const sliderCountWidget = findWidgetByName(node, "slider_count");
|
|
const count = getWidgetValue(sliderCountWidget);
|
|
for (let i = 1; i <= count; i++) {
|
|
const wtWidget = findWidgetByName(node, `(${i})`);
|
|
if (wtWidget) {
|
|
const normalizedValue = node.normalizedSliderWeights[i] || 0;
|
|
let newDisplayValue = normalizedValue * newMaxStrength;
|
|
const widgetMax = wtWidget.options?.max ?? 2.0;
|
|
const widgetMin = wtWidget.options?.min ?? 0.0;
|
|
newDisplayValue = Math.max(widgetMin, Math.min(newDisplayValue, widgetMax, newMaxStrength));
|
|
if (Math.abs(getWidgetValue(wtWidget) - newDisplayValue) > 0.001) {
|
|
wtWidget.value = newDisplayValue;
|
|
}
|
|
}
|
|
}
|
|
node.graph.setDirtyCanvas(true, true);
|
|
node._isUpdatingInternally = false;
|
|
}
|
|
|
|
// --- ComfyUI Extension ---
|
|
|
|
app.registerExtension({
|
|
// Updated extension name
|
|
name: "Comfy.DynamicSlidersStack.DynamicBehavior",
|
|
|
|
nodeCreated(node) {
|
|
const nodeTitle = node.getTitle ? node.getTitle() : node.title;
|
|
// Check for new display name
|
|
if (nodeTitle !== "Slider Stacker") return;
|
|
|
|
node.normalizedSliderWeights = {};
|
|
node._isUpdatingInternally = false;
|
|
|
|
const maxStrengthWidget = findWidgetByName(node, "slider_max_strength");
|
|
const sliderCountWidget = findWidgetByName(node, "slider_count");
|
|
|
|
if (!maxStrengthWidget || !sliderCountWidget) {
|
|
console.error("Slider Stacker Dynamic.js: Setup failed, required widgets not found.");
|
|
return;
|
|
}
|
|
|
|
// --- Initialize --- (remains the same) ...
|
|
setTimeout(() => { /* ... */
|
|
const initialMax = recalculateCurrentMaxStrength(node);
|
|
if (Math.abs(initialMax - getWidgetValue(maxStrengthWidget)) > 0.001) {
|
|
maxStrengthWidget.value = initialMax;
|
|
}
|
|
updateNormalization(node, initialMax);
|
|
updateAllSliderDisplays(node, initialMax);
|
|
}, 150);
|
|
|
|
|
|
// --- Set up Widget Interceptors --- (remain the same, logic relies on widget names)
|
|
|
|
interceptWidgetValue(node, "slider_max_strength", (newMax) => { /* ... */
|
|
updateAllSliderDisplays(node, newMax);
|
|
const actualMaxAfterUpdate = recalculateCurrentMaxStrength(node);
|
|
if (Math.abs(actualMaxAfterUpdate - newMax) > 0.001) {
|
|
node._isUpdatingInternally = true;
|
|
maxStrengthWidget.value = actualMaxAfterUpdate;
|
|
node._isUpdatingInternally = false;
|
|
}
|
|
});
|
|
|
|
const maxSlidersIntercept = sliderCountWidget?.options?.max || 50;
|
|
for (let i = 1; i <= maxSlidersIntercept; i++) {
|
|
interceptWidgetValue(node, `(${i})`, (newWt) => { /* ... */
|
|
const currentMaxStrengthWidget = findWidgetByName(node, "slider_max_strength");
|
|
const currentMaxDisplayed = getWidgetValue(currentMaxStrengthWidget);
|
|
const newCalculatedMax = recalculateCurrentMaxStrength(node);
|
|
updateNormalization(node, newCalculatedMax);
|
|
if (Math.abs(newCalculatedMax - currentMaxDisplayed) > 0.001) {
|
|
node._isUpdatingInternally = true;
|
|
currentMaxStrengthWidget.value = newCalculatedMax;
|
|
node._isUpdatingInternally = false;
|
|
} else {
|
|
updateAllSliderDisplays(node, currentMaxDisplayed);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|