Files
ausboss-ComfyUI-AusBoss/js/shared/settle.mjs
ausboss 5bf037d9b9 Crop + Rotate + Pad: the amber note under the size keeps still while you drag
With Resize on, the note that says how much the rounding stretches the
picture came and went every few pixels of a drag, and each time the picture
area and the rows under it jumped by a line.

- No note appears or changes while a pointer is down. A note the drag makes
  untrue goes away, and the note for the new size comes once, 0.2 s after
  the release. A click, a typed number or a new picture still shows its
  note at once; a run of arrow clicks or a held arrow key shows the first
  value and the last.
- The note has a line of its own that is there whenever Resize is on, with
  text or empty, so a note that comes or goes moves nothing. The Even out
  button no longer makes that line a pixel taller.
- The size line only grows while you drag: a step that comes and goes
  ("round to 8") no longer wraps it in and out.
- The full editor's size box and status panel show the same settled note,
  and the status panel keeps its height mid-drag.

The image node and both video nodes share this code. Even out now works its
padding out at the click, because the note can be a moment behind the values.
2026-10-13 16:22:14 -05:00

54 lines
2.0 KiB
JavaScript

// When is a run of changes over? A face asks this so that a note which
// depends on the values can wait for the hand to stop, instead of coming and
// going with every pixel of a drag. No DOM and no ComfyUI imports in here,
// so it runs under node:test (tests/settle.test.mjs).
//
// const rest = createSettle({ delay: 200, held: () => pointerIsDown, onSettle: showTheNote });
// rest.touch() a value changed. True: nothing else is going on, show it
// now. False: wait, onSettle says when.
// rest.release() the pointer came up; call it whenever held() turns false.
// rest.cancel() stop waiting (the picture or the face is gone).
//
// The rules:
// - A change with the pointer up and nothing waiting shows at once: a click,
// a typed number, a new picture.
// - While a pointer is held nothing settles, however long the hand rests.
// - Then onSettle runs once, `delay` ms after the last change or after the
// release, whichever came later. A burst of changes with no pointer (a
// held arrow key) shows its first value at once and its last one after.
export function createSettle({ delay = 200, held = () => false, onSettle = null, setTimer = setTimeout, clearTimer = clearTimeout } = {}) {
let timer = null;
// The wait ran out while a pointer was still held: release() starts it again.
let waiting = false;
// A change was held back, so onSettle has something to show.
let owed = false;
const arm = () => {
if (timer !== null) clearTimer(timer);
waiting = false;
timer = setTimer(() => {
timer = null;
if (held()) { waiting = true; return; }
if (!owed) return;
owed = false;
onSettle?.();
}, delay);
};
return {
touch() {
const now = !held() && timer === null && !waiting;
if (!now) owed = true;
arm();
return now;
},
release() {
if (timer !== null || waiting) arm();
},
cancel() {
if (timer !== null) clearTimer(timer);
timer = null;
waiting = false;
owed = false;
},
};
}