1export interface AccelerationSample {
2 /** Acceleration per axis in g, gravity included. */
3 readonly x: number;
4 readonly y: number;
5 readonly z: number;
6 readonly timestamp: number;
7}
8
9export function createShakeDetector({
10 threshold = 1.8,
11 window = 600,
12 cooldown = 1_000,
13}: { threshold?: number; window?: number; cooldown?: number } = {}) {
14 let jolts: number[] = [];
15 let lastShake = Number.NEGATIVE_INFINITY;
16 return (sample: AccelerationSample) => {
17 if (sample.timestamp - lastShake < cooldown) return false;
18 if (Math.hypot(sample.x, sample.y, sample.z) < threshold) return false;
19 jolts = [...jolts.filter((time) => sample.timestamp - time <= window), sample.timestamp];
20 if (jolts.length < 2) return false;
21 jolts = [];
22 lastShake = sample.timestamp;
23 return true;
24 };
25}