Table of Contents

Struct ScrollZoomFilter

Device-agnostic filter between raw per-frame scroll input and a zoom-gesture's target math. Compresses a sustained raw scroll rate toward a shared ceiling before bounding the felt zoom rate with a token bucket (a burst budget plus a wall-clock refill rate), and separates "the map should move now" from "the gesture is still meaningfully in progress" so a trackpad's inertia tail cannot indefinitely defer an end-of-gesture snap.

public struct ScrollZoomFilter
Inherited Members

Remarks

Takes one raw scroll sample per call and returns an accepted delta for immediate application every time - the accepted delta is never held back waiting for a threshold. Only SignificantEvent, meant to drive a caller's own quiet-period timer, is gated by a minimum magnitude accumulated from recent samples.

Fields

BurstCapacityNotches

public const double BurstCapacityNotches = 2

Field Value

double

MaxZoomRateLevelsPerSecond

public const double MaxZoomRateLevelsPerSecond = 8

Field Value

double

PhantomDecayTauSeconds

public const double PhantomDecayTauSeconds = 0.2

Field Value

double

PhantomFloorNotches

public const double PhantomFloorNotches = 0.05

Field Value

double

RateEmaTauSeconds

[Obsolete("ScrollZoomFilter.Step no longer keeps a rate estimate; this constant drives nothing.")]
public const double RateEmaTauSeconds = 0.2

Field Value

double

SustainedRateCeilingNotchesPerSecond

public const double SustainedRateCeilingNotchesPerSecond = 6

Field Value

double

Methods

Step(double, double)

Filters one raw scroll sample for a zoom gesture.

public (double AcceptedDelta, bool SignificantEvent) Step(double rawNotches, double dtSeconds)

Parameters

rawNotches double

Raw scroll delta for this call, in wheel-notch units (1.0 = one detent).

dtSeconds double

Wall-clock seconds elapsed since the PREVIOUS Step(double, double) call (refill time for the token bucket, and this sample's own compression allowance), not the time this call itself covers. NaN or negative skips compression, refill and phantom decay for this call but still processes the sample - there is no early-return. dt == 0 (back-to-back calls) is legal and expected, and its zero allowance compresses the sample to zero (a real, no-memory consequence of dtSeconds being the only clock this filter reads - a genuinely simultaneous second call has zero elapsed time to have earned any allowance in).

Returns

(double AcceptedDelta, bool SignificantEvent)

The accepted delta (burst/rate-capped, safe to apply to the zoom target immediately) and whether decaying recent motion has crossed PhantomFloorNotches.