aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-12 05:32:52 -0700
committerAdam Soltys <[email protected]>2026-10-12 05:32:52 -0700
commit3ff588d439dbe86da3fd5b2f433f302078bb0222 (patch)
tree1b39836d41eababe83810ad589a88997a75bb895 /tools
parent2b83c3f46c0dc2da1bbd9854443d57de54b979ea (diff)
downloadcoinosv3-3ff588d439dbe86da3fd5b2f433f302078bb0222.tar.gz
coinosv3-3ff588d439dbe86da3fd5b2f433f302078bb0222.zip
Feed wheel: a turn back against the coast hunts, in short steps that grow. Flying down the feed and turning the wheel back for the post just passed used to send the page flying the other way (a full notch's coast, 300px) the moment it caught — the reader overshoots again, and hunts by overshooting. Now a reversal against a coast (or one that died within 400 ms) catches the page and takes that notch as a quarter of its travel, over a quick coast (110 ms, not 325); each notch on in the same direction grows the step — 0.35, 0.5, 0.7, 0.85 of a notch — and the sixth is a full push with the usual wind-up, so a few flicks have the wheel flying again. Another turn back while hunting starts the small steps over, and two seconds without a notch ends the hunt: a notch from rest is the push it has always been. Keys, a touch or a grab end it too. tools/feed-wheel-reverse-test.js (short step on reversal, the ramp, the restart, the pause, the just-died coast, the full push from rest); feed-momentum-test still passes.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'tools')
-rw-r--r--tools/feed-wheel-reverse-test.js25
1 files changed, 22 insertions, 3 deletions
diff --git a/tools/feed-wheel-reverse-test.js b/tools/feed-wheel-reverse-test.js
index d8cc44a..8a00b11 100644
--- a/tools/feed-wheel-reverse-test.js
+++ b/tools/feed-wheel-reverse-test.js
@@ -28,6 +28,7 @@ function fixture() {
frame(stamp = now) { const callbacks = [...frames.values()]; frames.clear(); for (const fn of callbacks) fn(stamp); },
};
}
+const settle = (f, n = 70) => { for (let i = 0; i < n; i++) { f.advance(17); f.frame(); } };
for (const dir of [1, -1]) {
const f = fixture();
f.wheel(dir); f.advance(17); f.frame();
@@ -44,7 +45,25 @@ for (const dir of [1, -1]) {
f.advance(17); f.frame();
assert((f.y - reversed) * dir < 0, 'next frame continues in the new direction');
assert(Math.abs(f.y - reversed) < 20, 'new velocity is not applied to the old frame delay');
- for (let i = 0; i < 100; i++) { f.advance(17); f.frame(); }
- assert(Math.abs(f.y - before) > 280 && Math.abs(f.y - before) < 330, 'one notch retains its coast distance');
+ settle(f);
+ // The turn back is a hunt: a quarter of a notch's travel, not a flight the other way.
+ const back = (before - f.y) * dir;
+ assert(back > 65 && back < 90, 'a reverse notch against a coast is a short step: ' + back);
+ // Each notch on grows the step back towards a full one; the sixth is a plain notch again.
+ const steps = [];
+ for (let i = 0; i < 5; i++) { f.advance(200); const y = f.y; f.wheel(-dir); settle(f); steps.push((y - f.y) * dir); }
+ assert(steps.every((s, i) => i === 0 || s > steps[i - 1] * 1.08), 'hunting steps grow notch by notch: ' + steps.map(Math.round));
+ assert(steps[0] > 95 && steps[0] < 125 && steps[3] > 240 && steps[3] < 285 && steps[4] > 280 && steps[4] < 330, 'from about a third of a notch to a full one: ' + steps.map(Math.round));
+ { f.advance(200); const y = f.y; f.wheel(-dir); settle(f); const s = (y - f.y) * dir; assert(s > 280 && s < 330, 'a few flicks on, the wheel flies again: ' + s); }
+ // A turn back while hunting starts the small steps over.
+ f.wheel(-dir); f.advance(17); f.frame(); f.advance(17); f.frame();
+ { const y = f.y; f.wheel(dir); settle(f); const s = (f.y - y) * dir; assert(s > 65 && s < 90, 'a reversal while hunting is a short step again: ' + s); }
+ { f.advance(300); const y = f.y; f.wheel(dir); settle(f); const s = (f.y - y) * dir; assert(s > 95 && s < 120, 'and the next grows from there: ' + s); }
+ // A pause ends the hunt: the next notch is the plain push from rest.
+ { f.advance(2200); const y = f.y; f.wheel(dir); settle(f); const s = (f.y - y) * dir; assert(s > 280 && s < 330, 'after a pause a notch is a full push: ' + s); }
+ // A turn back against a coast that only just died hunts too.
+ { f.wheel(dir); settle(f); f.advance(200); const y = f.y; f.wheel(-dir); settle(f); const s = (y - f.y) * dir; assert(s > 65 && s < 90, 'reversing right after the coast dies is a short step: ' + s); }
+ // ...but a notch from rest the other way, well after, is a full one.
+ { f.advance(2500); const y = f.y; f.wheel(dir); settle(f); const s = (f.y - y) * dir; assert(s > 280 && s < 330, 'from rest a notch either way is a full push: ' + s); }
}
-console.log('✓ immediate reversal both ways, stale frame timestamps, busy frame recovery, and coast distance');
+console.log('✓ immediate reversal both ways, stale frame timestamps, busy frame recovery, precision hunt after a reversal (short steps that grow, restart on another turn back, end on a pause)');