gtauri viewer: velocity-scaled swipe commit (faster flicks)
Flicks now continue the finger's motion instead of taking a fixed 200 ms: commit duration = remaining distance / release velocity (15 % snappier), clamped 80-240 ms, ease-out. A full-speed flick releasing past half the screen commits in ~80 ms (was 200). Slow releases past the 25 % threshold still settle gently (180 ms smoothstep; 150 ms for keyboard nav). Verified on the emulator: a 100 ms flick is fully settled before the first post-release screencap (~150 ms), with only a 5 px edge artifact between consecutive frames (no residual motion).
This commit is contained in:
parent
ba646fb233
commit
cd31b76889
30
harnesses/gtauri/frontend/dist/index.html
vendored
30
harnesses/gtauri/frontend/dist/index.html
vendored
|
|
@ -546,26 +546,40 @@ function tweenTo(tx, ty, ms, onDone) {
|
||||||
/// Both images stay on the page strip for the whole animation:
|
/// Both images stay on the page strip for the whole animation:
|
||||||
/// 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) {
|
function navigate(delta, vel) {
|
||||||
if (tween && tween.commit) return false; // commit already in flight
|
if (tween && tween.commit) return false; // commit already in flight
|
||||||
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;
|
||||||
commitTo(ni, delta);
|
commitTo(ni, delta, vel || 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commit a swipe: animate vTx to the outgoing offset (the incoming
|
/// Commit a swipe: animate vTx to the outgoing offset (the incoming
|
||||||
/// preview tracks at vTx + delta*W and lands exactly on 0), then swap
|
/// preview tracks at vTx + delta*W and lands exactly on 0), then swap
|
||||||
/// the elements' roles. The commit tween is locked: input is ignored
|
/// the elements' roles. The commit tween is locked: input is ignored
|
||||||
/// until it finishes (~200 ms).
|
/// until it finishes. `vel` = release velocity in px/ms: a flick
|
||||||
function commitTo(ni, delta) {
|
/// continues the finger's motion (duration scales with the remaining
|
||||||
|
/// distance at that velocity, ease-out — fast flicks are fast), a
|
||||||
|
/// slow release settles gently.
|
||||||
|
function commitTo(ni, delta, vel) {
|
||||||
navSet(ids[ni], delta); // the incoming (no-op if the drag showed it)
|
navSet(ids[ni], delta); // the incoming (no-op if the drag showed it)
|
||||||
const out = -delta * innerWidth;
|
const out = -delta * innerWidth;
|
||||||
const x0 = vTx, t0 = performance.now(), ms = 200;
|
const x0 = vTx, t0 = performance.now();
|
||||||
|
let ms, ease;
|
||||||
|
if (vel > 0.35) {
|
||||||
|
const remain = Math.abs(out - x0);
|
||||||
|
// Time to cover the remaining distance at the release velocity,
|
||||||
|
// 15 % snappier than the raw continuation, clamped 80–240 ms.
|
||||||
|
ms = Math.max(80, Math.min(240, remain / vel * 0.85));
|
||||||
|
ease = (t) => 1 - Math.pow(1 - t, 3); // ease-out: land soft
|
||||||
|
} else {
|
||||||
|
ms = vel > 0 ? 180 : 150; // drag-settle / keyboard
|
||||||
|
ease = (t) => t * t * (3 - 2 * t);
|
||||||
|
}
|
||||||
const step = (now) => {
|
const step = (now) => {
|
||||||
const t = Math.min(1, (now - t0) / ms);
|
const t = Math.min(1, (now - t0) / ms);
|
||||||
const e = t * t * (3 - 2 * t); // smoothstep: pick up, land soft
|
const e = ease(t);
|
||||||
vTx = x0 + (out - x0) * e;
|
vTx = x0 + (out - x0) * e;
|
||||||
vTy = 0;
|
vTy = 0;
|
||||||
applyTransform();
|
applyTransform();
|
||||||
|
|
@ -690,9 +704,9 @@ const endPt = (e) => {
|
||||||
// Commit past the threshold; at the library edges navigate
|
// Commit past the threshold; at the library edges navigate
|
||||||
// refuses (nothing to commit to) and we snap back instead.
|
// refuses (nothing to commit to) and we snap back instead.
|
||||||
if (dx < -w * 0.25 || g.vx < -0.35) {
|
if (dx < -w * 0.25 || g.vx < -0.35) {
|
||||||
if (!navigate(+1)) tweenTo(0, 0, 120, navHide);
|
if (!navigate(+1, Math.abs(g.vx))) tweenTo(0, 0, 120, navHide);
|
||||||
} else if (dx > w * 0.25 || g.vx > 0.35) {
|
} else if (dx > w * 0.25 || g.vx > 0.35) {
|
||||||
if (!navigate(-1)) tweenTo(0, 0, 120, navHide);
|
if (!navigate(-1, Math.abs(g.vx))) tweenTo(0, 0, 120, navHide);
|
||||||
} else {
|
} else {
|
||||||
tweenTo(0, 0, 120, navHide); // not far enough: snap back
|
tweenTo(0, 0, 120, navHide); // not far enough: snap back
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user