gtauri viewer: adopt incoming dimensions at swipe commit (aspect fix)

Settling on a different-aspect neighbor (e.g. landscape → portrait)
stretched: vimg kept the OLD image's width/height styles while showing
the new thumbnail, so the new pixels rendered in the old box until
full-res landed and fitViewer() reset the dimensions — a visible
vertical stretch then snap-back.

At the commit swap, adopt the incoming image's dimensions from the
drag preview (nav already knows w/h/scale from its loaded thumb):
base/vScale/width/height/transform are all set consistently in the
same task as the src swap, so the first settled frame is correct.
Fallback: if the preview never loaded (keyboard nav / slow thumb),
use the plain openViewer path where the thumb round-trip sets the
dimensions before first paint.

Verified on the emulator with a 4:3 landscape + 3:4 portrait pair:
settled content box 1439x1921 (0.749 = exact 3:4) from the first
settled frame, unchanged after the full-res swap.
This commit is contained in:
Greg Pomerantz 2026-11-03 13:15:55 -05:00
parent 029780cc09
commit ba646fb233

View File

@ -573,15 +573,29 @@ function commitTo(ni, delta) {
if (t < 1) {
tween = { raf: requestAnimationFrame(step), commit: true };
} else {
// vimg2 (incoming) is exactly at 0: it becomes primary.
const id = ids[ni];
vimg.src = vimg2.src; // cached + decoded → paints immediately
vTx = 0;
applyTransform();
tween = null;
openViewer(id, true);
// Hide the outgoing preview only once the primary has the bytes.
vimg.onload = () => { if (viewerId === id) navHide(); };
if (nav && nav.id === id && nav.ready) {
// vimg2 (incoming) is exactly at 0: it becomes primary. Adopt
// its dimensions NOW — otherwise the new pixels render in the
// OLD image's width/height box (wrong aspect) until full-res
// lands and fitViewer() fixes it (visible stretch → snap).
const nw = nav.w, nh = nav.h, ns = nav.scale;
vimg.src = vimg2.src; // cached + decoded → paints immediately
base.w = nw; base.h = nh;
vScale = ns;
vimg.style.width = nw + "px";
vimg.style.height = nh + "px";
vTx = 0; vTy = 0;
applyTransform();
openViewer(id, true);
// Hide the preview only once the primary has the bytes.
vimg.onload = () => { if (viewerId === id) navHide(); };
} else {
// Preview never made it (keyboard nav / slow thumb): plain
// open — the thumb round-trip sets the right dimensions.
openViewer(id, false);
}
}
};
tween = { raf: requestAnimationFrame(step), commit: true };