diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/app.js | 56 |
1 files changed, 39 insertions, 17 deletions
@@ -6657,18 +6657,27 @@ if (INTENT_URI) { if (!raf && v) { last = performance.now(); raf = requestAnimationFrame(tick); } }; // ---- the wheel - // A turn back against the coast catches the page at once and is a gentler - // push the other way — half a notch's travel, at half the speed — so the - // reader who overshot a post settles back onto it instead of flying past - // it the other way. The next notch the same way is a plain one, winding - // up from whatever speed the half push left, so a spin on after a - // reversal gets going again at once. (A spell of quarter-size "hunting" - // notches ramping back up over five turns was tried here and felt like a - // stutter and a slow patch; a full notch then two without wind-up felt - // like an overshoot — Adam, 2026-10-16: "could the first coast in the - // opposite direction be smaller/slower than usual? then speed up if we - // scroll again in the same direction".) - const REVERSE = 0.5; // of a notch: the first push back against a coast + // A turn back against a page that is flying is a brake: that notch only + // eases the coast to a stop (a quick easing, not a dead halt), and goes + // nowhere the other way. The next notch the same way is a gentle start + // back — half a notch's travel at half the speed — and the ones after + // wind up as usual. So the reader flying past a post stops on the first + // turn back, creeps back on the second, and gets going on the third. + // Against a coast that is merely strolling, or one that only just died, + // there is nothing worth braking: that turn back is the gentle start + // itself. (A spell of quarter-size "hunting" notches ramping back up over + // five turns was tried here and felt like a stutter and a slow patch; a + // full notch then two without wind-up felt like an overshoot; a gentle + // push straight away from a flight still overshot — Adam, 2026-10-16: + // "the first click of the wheel should just stop the coasting/flying + // maybe with a quick easing rather than a sudden stop and then the next + // notch should start going slowly in reverse and the next ones should + // start speeding up".) + const REVERSE = 0.5; // of a notch: the gentle start back + const BRAKE_V = 1.2; // px/ms: flying, worth a brake (a notch from rest peaks near 0.9) + const BRAKE_TAU = 40; // ms: the brake's easing (a flight at 8 px/ms stops within ~300 px) + const BRAKE_FOR = 2500; // ms: how long after a brake the next notch that way is the gentle start + let brake = null; // { dir, until }: the turn back that braked, awaiting its gentle start // (lastDir/lastMoveAt: the tick's, above) let smoothUntil = 0; // a trackpad's events were just seen: hands off window.addEventListener('wheel', (e) => { @@ -6683,18 +6692,31 @@ if (INTENT_URI) { const now = e.timeStamp; // the way the page is going: its coast, or the coast that only just died const going = v ? Math.sign(v) : now - lastMoveAt < 400 ? lastDir : 0; - if (going && dir !== going) { - // A reversal catches the old coast immediately. Discard its fractional - // step and frame clock too: after a busy frame, applying the NEW velocity - // to the OLD elapsed time made the first reverse step jump. Give the - // notch a small response now, then coast the rest of its (half) travel. + const gentle = () => { + // The gentle start back catches whatever coast is left immediately. + // Discard its fractional step and frame clock too: after a busy frame, + // applying the NEW velocity to the OLD elapsed time made the first + // reverse step jump. A small response now, then the rest of its + // (half) travel coasts. stop(); + brake = null; const travel = px * 3 * REVERSE; const first = dir * Math.min(16, Math.abs(travel / TAU) * 16); window.scrollBy({ top: first, behavior: 'instant' }); lastDir = dir; lastMoveAt = now; coast((travel - first) / TAU, TAU); + }; + if (going && dir !== going && Math.abs(v) >= BRAKE_V) { + // flying: this notch only brakes — the coast eases out over a few + // frames (from now: the frames a busy thread missed don't travel first) + tau = BRAKE_TAU; acc = 0; last = performance.now(); + brake = { dir, until: now + BRAKE_FOR }; + } else if (going && dir !== going) { + gentle(); + } else if (brake && brake.dir === dir && now < brake.until) { + gentle(); // the notch after a brake: the gentle start back } else { + brake = null; // A notch into a page already moving pushes harder: the faster it // goes, the more each turn adds (up to 2.5x), so keeping the wheel // turning winds the speed up instead of settling at a stroll. From |
