Files
ausboss-ComfyUI-AusBoss/js/shared/compare.mjs
T
ausboss c8099952e5 Clear the compare panel, and make the example workflow shippable
Image Compare A/B drew a chip over the top-left of the picture carrying the
resolution and a hint about how to use the panel - covering part of what you
came to look at in order to say something you need once. The resolution moved
to a caption centred under the stage, and when the two sides are different
sizes both are named there: the panel scales them to fit, so nothing else on
screen would reveal the mismatch. The empty and error states still take the
middle of the stage, where there is no picture to hide.

HOLD became an A/B toggle. Press-and-hold meant the comparison only existed
while a mouse button was down, so the two images could never be held side by
side in memory. Each click now swaps the panel and the button names the side
you are looking at; flicking between them in place is how a small difference
actually becomes visible. A workflow saved on "hold" opens on the toggle it
became rather than quietly dropping back to slide.

The example workflow was stale in ways that would have shipped to Civitai:
its overview credited SimpleWatermarkRemover - the deprecated compatibility
id, not the node the graph actually uses - still called the node Refine Mask,
and linked to github.com/auboss, which does not exist. It gained model-setup
and requirements sections, consistent node titles, and the mask settings its
single-frame test was missing: that path shipped with every Mask Refine
control at zero, so the frame it previewed was not the result the full run
would produce, which is the one thing that test exists to show.
2026-08-18 16:59:44 -05:00

60 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Pure decision logic for the Image Compare A/B panel. No DOM in here — the
// wiring lives in js/compare/index.js so this module stays testable
// under node:test.
export const COMPARE_MODES = ["slide", "toggle"];
// "hold" was the press-and-hold mode that toggle replaced. Mapping it keeps a
// workflow saved with it on the button it became, instead of quietly dropping
// back to slide - the panel would still work, but not the way it was left.
const LEGACY_MODES = { hold: "toggle" };
export function normalizeCompareMode(value) {
const mapped = LEGACY_MODES[value] ?? value;
return COMPARE_MODES.includes(mapped) ? mapped : COMPARE_MODES[0];
}
// The caption under the stage: the compared resolution, or "" when nothing
// has been loaded yet. Both sides are normally the same size, so A speaks for
// the pair; when they differ, both are named rather than one quietly winning.
export function compareSizeLabel(refs) {
const a = refs?.a;
const b = refs?.b;
if (!(a?.width > 0) || !(a?.height > 0)) return "";
if (b?.width > 0 && b?.height > 0 && (b.width !== a.width || b.height !== a.height)) {
return `A ${a.width}×${a.height} · B ${b.width}×${b.height}`;
}
return `${a.width}×${a.height}`;
}
// Fraction of the panel width covered by the pointer, clamped to 0..1.
// Degenerate rectangles and non-finite input resolve to 0 (all-A).
export function clipFraction(pointerX, rectLeft, rectWidth) {
const width = Number(rectWidth);
if (!Number.isFinite(width) || width <= 0) return 0;
const fraction = (Number(pointerX) - Number(rectLeft)) / width;
if (!Number.isFinite(fraction)) return 0;
return Math.max(0, Math.min(1, fraction));
}
// CSS for a given reveal fraction: image B keeps its left portion up to the
// seam, the rest is clipped away. The seam only shows while both images are
// partially visible.
export function compareClip(fraction) {
const value = Number(fraction);
const clamped = Number.isFinite(value) ? Math.max(0, Math.min(1, value)) : 0;
return {
clipPath: `inset(0 ${((1 - clamped) * 100).toFixed(2)}% 0 0)`,
seamLeft: `${(clamped * 100).toFixed(2)}%`,
seamVisible: clamped > 0 && clamped < 1,
};
}
// Pull the two preview references out of an onExecuted payload. Both must
// be present for the panel to have anything meaningful to show.
export function findCompareImages(message) {
const a = message?.a_images?.[0] ?? null;
const b = message?.b_images?.[0] ?? null;
return a?.filename && b?.filename ? { a, b } : null;
}