From ba646fb233d01ef871ed9309af56d8c33008ed2c Mon Sep 17 00:00:00 2001 From: Greg Pomerantz Date: Tue, 3 Nov 2026 13:15:55 -0500 Subject: [PATCH] gtauri viewer: adopt incoming dimensions at swipe commit (aspect fix) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- harnesses/gtauri/frontend/dist/index.html | 28 +++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/harnesses/gtauri/frontend/dist/index.html b/harnesses/gtauri/frontend/dist/index.html index a6e97bd..eccc433 100644 --- a/harnesses/gtauri/frontend/dist/index.html +++ b/harnesses/gtauri/frontend/dist/index.html @@ -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 };