gtauri viewer: mid-commit touch/key takes over the swipe (chained swipes)
A second swipe while the new image was still sliding in got dropped (pointerdown bailed while the commit tween was in flight). Now a touch — or arrow key — during a commit takes it over: the commit finishes instantly (roles swap at the settle positions, same dimension-adoption path as natural completion) and the input starts a fresh gesture on the landed image, so rapid successive swipes chain through multiple pictures. A plain tap during a commit simply settles it early. Verified on the emulator: two 100 ms flicks 120 ms apart (the second lands mid-commit) end on the exact same image — pixel-identical — as two deliberate slow swipes.
This commit is contained in:
parent
cd31b76889
commit
695e2417cc
43
harnesses/gtauri/frontend/dist/index.html
vendored
43
harnesses/gtauri/frontend/dist/index.html
vendored
|
|
@ -547,7 +547,8 @@ function tweenTo(tx, ty, ms, onDone) {
|
||||||
/// the incoming one slides home while the outgoing one slides off
|
/// the incoming one slides home while the outgoing one slides off
|
||||||
/// screen; only then do the roles swap (returns false at the edges).
|
/// screen; only then do the roles swap (returns false at the edges).
|
||||||
function navigate(delta, vel) {
|
function navigate(delta, vel) {
|
||||||
if (tween && tween.commit) return false; // commit already in flight
|
// Key nav during a commit takes it over the same way a touch does.
|
||||||
|
if (tween && tween.commit) takeover();
|
||||||
const i = ids.indexOf(viewerId);
|
const i = ids.indexOf(viewerId);
|
||||||
const ni = i + delta;
|
const ni = i + delta;
|
||||||
if (i < 0 || ni < 0 || ni >= ids.length) return false;
|
if (i < 0 || ni < 0 || ni >= ids.length) return false;
|
||||||
|
|
@ -585,15 +586,24 @@ function commitTo(ni, delta, vel) {
|
||||||
applyTransform();
|
applyTransform();
|
||||||
navLayout();
|
navLayout();
|
||||||
if (t < 1) {
|
if (t < 1) {
|
||||||
tween = { raf: requestAnimationFrame(step), commit: true };
|
tween = { raf: requestAnimationFrame(step), commit: true, target: ni };
|
||||||
} else {
|
} else {
|
||||||
const id = ids[ni];
|
|
||||||
tween = null;
|
tween = null;
|
||||||
|
finishCommit(ni);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tween = { raf: requestAnimationFrame(step), commit: true, target: ni };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Swap the elements' roles at the settled positions: vimg2 (the
|
||||||
|
/// incoming image) becomes primary at 0 with its own dimensions (see
|
||||||
|
/// the aspect note there), vimg shows it next paint, the old image is
|
||||||
|
/// gone. Called when the commit tween completes AND on mid-flight
|
||||||
|
/// takeover — a new touch/key during a commit finishes it instantly
|
||||||
|
/// so the new gesture acts on the landed image (swipes chain).
|
||||||
|
function finishCommit(ni) {
|
||||||
|
const id = ids[ni];
|
||||||
if (nav && nav.id === id && nav.ready) {
|
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;
|
const nw = nav.w, nh = nav.h, ns = nav.scale;
|
||||||
vimg.src = vimg2.src; // cached + decoded → paints immediately
|
vimg.src = vimg2.src; // cached + decoded → paints immediately
|
||||||
base.w = nw; base.h = nh;
|
base.w = nw; base.h = nh;
|
||||||
|
|
@ -606,17 +616,25 @@ function commitTo(ni, delta, vel) {
|
||||||
// Hide the preview only once the primary has the bytes.
|
// Hide the preview only once the primary has the bytes.
|
||||||
vimg.onload = () => { if (viewerId === id) navHide(); };
|
vimg.onload = () => { if (viewerId === id) navHide(); };
|
||||||
} else {
|
} else {
|
||||||
// Preview never made it (keyboard nav / slow thumb): plain
|
// Preview never made it (keyboard nav / slow thumb): plain open —
|
||||||
// open — the thumb round-trip sets the right dimensions.
|
// the thumb round-trip sets the right dimensions.
|
||||||
openViewer(id, false);
|
openViewer(id, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
tween = { raf: requestAnimationFrame(step), commit: true };
|
/// Instantly settle an in-flight commit (touch/key takeover).
|
||||||
|
function takeover() {
|
||||||
|
const target = tween.target;
|
||||||
|
cancelAnimationFrame(tween.raf);
|
||||||
|
tween = null;
|
||||||
|
finishCommit(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer.addEventListener("pointerdown", (e) => {
|
viewer.addEventListener("pointerdown", (e) => {
|
||||||
if (tween && tween.commit) return; // a swipe commit is in flight
|
// A touch during a swipe commit takes it over: finish the commit
|
||||||
|
// now and start this gesture on the landed image — a second swipe
|
||||||
|
// while the new image is sliding in acts as another swipe.
|
||||||
|
if (tween && tween.commit) takeover();
|
||||||
viewer.setPointerCapture(e.pointerId);
|
viewer.setPointerCapture(e.pointerId);
|
||||||
if (tween) { cancelAnimationFrame(tween.raf); tween = null; }
|
if (tween) { cancelAnimationFrame(tween.raf); tween = null; }
|
||||||
pts.set(e.pointerId, { x: e.clientX, y: e.clientY });
|
pts.set(e.pointerId, { x: e.clientX, y: e.clientY });
|
||||||
|
|
@ -716,7 +734,6 @@ const endPt = (e) => {
|
||||||
viewer.addEventListener("pointerup", endPt);
|
viewer.addEventListener("pointerup", endPt);
|
||||||
viewer.addEventListener("pointercancel", endPt);
|
viewer.addEventListener("pointercancel", endPt);
|
||||||
viewer.addEventListener("dblclick", () => {
|
viewer.addEventListener("dblclick", () => {
|
||||||
if (tween && tween.commit) return;
|
|
||||||
vScale = fitScale();
|
vScale = fitScale();
|
||||||
vTx = 0; vTy = 0; vApply();
|
vTx = 0; vTy = 0; vApply();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user