1+ /**
2+ * macOS-inspired scroll acceleration.
3+ *
4+ * The class measures the time between consecutive scroll events and keeps a short
5+ * moving window of the latest intervals. The average interval determines which
6+ * multiplier to apply so that quick bursts accelerate and slower gestures stay precise.
7+ *
8+ * Options:
9+ * - threshold1: upper bound (ms) of the "medium" band. Raise to delay fast mode.
10+ * - threshold2: upper bound (ms) of the "fast" band. Lower to require tighter bursts.
11+ * - multiplier1: scale for medium speed. Higher values feel more eager to accelerate.
12+ * - multiplier2: scale for fast speed. Higher values make flings jump further.
13+ * - baseMultiplier: scale for slow scrolling. Set to 1 for linear behaviour.
14+ *
15+ * Default tuning mirrors the gentle macOS-style curve: relaxed scrolling stays
16+ * close to 1×, while rapid consecutive ticks climb through the medium and fast
17+ * bands without sudden jumps.
18+ */
119export class MacOSScrollAccel {
220 private lastNow = 0
321 private velocityHistory : number [ ] = [ ]
4- private readonly historySize = 3
22+ private readonly historySize = 3 // three-sample window smooths jitter without masking bursts
523
624 constructor (
725 private opts : {
@@ -14,8 +32,8 @@ export class MacOSScrollAccel {
1432 ) { }
1533
1634 tick ( now = Date . now ( ) ) : number {
17- const threshold1 = this . opts . threshold1 ?? 150
18- const threshold2 = this . opts . threshold2 ?? 50
35+ const threshold1 = this . opts . threshold1 ?? 100
36+ const threshold2 = this . opts . threshold2 ?? 40
1937 const multiplier1 = this . opts . multiplier1 ?? 2
2038 const multiplier2 = this . opts . multiplier2 ?? 4
2139 const baseMultiplier = this . opts . baseMultiplier ?? 1
@@ -33,6 +51,7 @@ export class MacOSScrollAccel {
3351 const avgVelocity = this . velocityHistory . length > 0
3452 ? this . velocityHistory . reduce ( ( a , b ) => a + b , 0 ) / this . velocityHistory . length
3553 : Infinity
54+ // lower average interval ⇒ faster gestures ⇒ higher multiplier
3655
3756 if ( avgVelocity <= threshold2 ) {
3857 return multiplier2
@@ -47,4 +66,4 @@ export class MacOSScrollAccel {
4766 this . lastNow = 0
4867 this . velocityHistory = [ ]
4968 }
50- }
69+ }
0 commit comments