gesturx 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +64 -67
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +1 -1
- package/dist/index.umd.cjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -86,7 +86,7 @@ export declare class Recognizable<T extends Recognizer<any, any>[]> implements R
|
|
|
86
86
|
recognizers: T;
|
|
87
87
|
afterEventReceived?: (event: PointerEvent) => PointerEvent;
|
|
88
88
|
});
|
|
89
|
-
|
|
89
|
+
update(options: RecognizerConfig<unknown>): void;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
declare interface RecognizableInterface<T extends Recognizer<any, any>[]> {
|
|
@@ -113,7 +113,7 @@ declare interface RecognizableInterface<T extends Recognizer<any, any>[]> {
|
|
|
113
113
|
* You can only initialize one element per instance but you can
|
|
114
114
|
* change the element and call the method again if needed.
|
|
115
115
|
*/
|
|
116
|
-
|
|
116
|
+
update(options: RecognizerConfig<unknown>): void;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
declare type RecognizableState = {
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
var ee = Object.defineProperty;
|
|
2
2
|
var te = (t, s, e) => s in t ? ee(t, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[s] = e;
|
|
3
3
|
var h = (t, s, e) => (te(t, typeof s != "symbol" ? s + "" : s, e), e);
|
|
4
|
-
import { filter as l, mergeMap as T, defer as ne, of as b, merge as m, takeWhile as N, scan as O, map as
|
|
4
|
+
import { filter as l, mergeMap as T, defer as ne, of as b, merge as m, takeWhile as N, scan as O, map as $, fromEvent as S, BehaviorSubject as B, switchMap as v, NEVER as se, shareReplay as w, exhaustMap as G, first as Y, share as M, timer as H, withLatestFrom as j, takeUntil as k, skip as ie, tap as pe, ignoreElements as oe, buffer as re, debounceTime as ae, startWith as le, pairwise as he, combineLatest as ce } from "rxjs";
|
|
5
5
|
function ue(t, s) {
|
|
6
6
|
return Math.sqrt(
|
|
7
7
|
Math.pow(s.x - t.x, 2) + Math.pow(s.y - t.y, 2)
|
|
8
8
|
);
|
|
9
9
|
}
|
|
10
|
-
function
|
|
10
|
+
function $e(t) {
|
|
11
11
|
const s = t.length;
|
|
12
12
|
if (s < 2)
|
|
13
13
|
return 0;
|
|
@@ -18,10 +18,10 @@ function U(t, s) {
|
|
|
18
18
|
const e = s.x - t.x, i = s.y - t.y;
|
|
19
19
|
return Math.atan2(i, e);
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function ge(t, s) {
|
|
22
22
|
return U(t, s) * (180 / Math.PI);
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function C(t) {
|
|
25
25
|
const s = t.reduce(
|
|
26
26
|
(i, n) => (i.x += n.x, i.y += n.y, i),
|
|
27
27
|
{ x: 0, y: 0 }
|
|
@@ -34,7 +34,7 @@ function z(t) {
|
|
|
34
34
|
function de(t, s) {
|
|
35
35
|
if (t.length !== s.length)
|
|
36
36
|
throw new Error("Initial and new points arrays must have the same length.");
|
|
37
|
-
const e =
|
|
37
|
+
const e = C(t), i = C(s);
|
|
38
38
|
let n = 0;
|
|
39
39
|
for (let p = 0; p < t.length; p++) {
|
|
40
40
|
const o = U(
|
|
@@ -55,7 +55,7 @@ function ve(t) {
|
|
|
55
55
|
}
|
|
56
56
|
const ye = (t) => t.length > 0, me = (t) => t.pipe(l(ye));
|
|
57
57
|
function J(t, s, e) {
|
|
58
|
-
const i =
|
|
58
|
+
const i = C([t]), n = C([s]);
|
|
59
59
|
return Math.abs(n.x - i.x) >= e || Math.abs(n.y - i.y) >= e;
|
|
60
60
|
}
|
|
61
61
|
const De = (t, s, e) => {
|
|
@@ -74,7 +74,7 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
74
74
|
container: t,
|
|
75
75
|
afterEventReceived: s = (e) => e
|
|
76
76
|
}) => S(t, "pointerdown").pipe(
|
|
77
|
-
|
|
77
|
+
$(s)
|
|
78
78
|
), Q = ({
|
|
79
79
|
pointerEvent$: t
|
|
80
80
|
}) => (s) => {
|
|
@@ -114,7 +114,7 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
116
|
}, void 0),
|
|
117
|
-
|
|
117
|
+
$(({ event: p, pointers: o }) => ({
|
|
118
118
|
event: p,
|
|
119
119
|
pointers: Object.values(o).filter(ve)
|
|
120
120
|
}))
|
|
@@ -126,7 +126,7 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
126
126
|
deltaY: r
|
|
127
127
|
};
|
|
128
128
|
}, Z = (t) => {
|
|
129
|
-
const s = (e) =>
|
|
129
|
+
const s = (e) => C(
|
|
130
130
|
e.latestActivePointers.length ? e.latestActivePointers : [e.event]
|
|
131
131
|
);
|
|
132
132
|
return t.pipe(
|
|
@@ -134,7 +134,7 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
134
134
|
var d, x;
|
|
135
135
|
const n = s(i), r = (e == null ? void 0 : e.center) ?? n, a = (e == null ? void 0 : e.deltaX) ?? 0, p = (e == null ? void 0 : e.deltaY) ?? 0, o = ((d = e == null ? void 0 : e.latestActivePointers) == null ? void 0 : d.length) ?? 1, c = ((x = i.latestActivePointers) == null ? void 0 : x.length) ?? 1, u = ["pointerdown", "pointercancel", "pointerleave", "pointerup"].includes(
|
|
136
136
|
i.event.type
|
|
137
|
-
) && o !== c,
|
|
137
|
+
) && o !== c, E = c > 0, { deltaX: g, deltaY: P } = u && E ? _(n, n, a, p) : _(n, r, a, p), { degreesDelta: D } = o === c && o >= 2 && c >= 2 ? de(
|
|
138
138
|
(e == null ? void 0 : e.latestActivePointers) ?? [],
|
|
139
139
|
i.latestActivePointers ?? []
|
|
140
140
|
) : { degreesDelta: 0 };
|
|
@@ -143,12 +143,12 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
143
143
|
...e,
|
|
144
144
|
...i,
|
|
145
145
|
center: n,
|
|
146
|
-
deltaX:
|
|
146
|
+
deltaX: g,
|
|
147
147
|
deltaY: P,
|
|
148
148
|
deltaPointersAngle: D
|
|
149
149
|
};
|
|
150
150
|
}, void 0),
|
|
151
|
-
|
|
151
|
+
$((e) => {
|
|
152
152
|
const {
|
|
153
153
|
deltaX: i,
|
|
154
154
|
deltaY: n,
|
|
@@ -157,13 +157,13 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
157
157
|
center: p,
|
|
158
158
|
event: o,
|
|
159
159
|
deltaPointersAngle: c
|
|
160
|
-
} = e, u = r ?? [],
|
|
160
|
+
} = e, u = r ?? [], g = Date.now() - a, { velocityX: P, velocityY: D } = De(g, i, n), d = $e(r);
|
|
161
161
|
return {
|
|
162
162
|
deltaX: i,
|
|
163
163
|
deltaY: n,
|
|
164
164
|
velocityX: P,
|
|
165
165
|
velocityY: D,
|
|
166
|
-
delay:
|
|
166
|
+
delay: g,
|
|
167
167
|
center: p,
|
|
168
168
|
pointers: u,
|
|
169
169
|
startTime: a,
|
|
@@ -182,15 +182,15 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
182
182
|
afterEventReceived: s = (e) => e
|
|
183
183
|
}) => {
|
|
184
184
|
const e = Pe({ afterEventReceived: s, container: t }), i = S(t, "pointerup").pipe(
|
|
185
|
-
|
|
185
|
+
$(s)
|
|
186
186
|
), n = S(t, "pointermove").pipe(
|
|
187
|
-
|
|
187
|
+
$(s)
|
|
188
188
|
), r = S(t, "pointerleave").pipe(
|
|
189
|
-
|
|
189
|
+
$(s)
|
|
190
190
|
), a = S(
|
|
191
191
|
t,
|
|
192
192
|
"pointercancel"
|
|
193
|
-
).pipe(
|
|
193
|
+
).pipe($(s));
|
|
194
194
|
return m(
|
|
195
195
|
e,
|
|
196
196
|
a,
|
|
@@ -199,7 +199,7 @@ const K = (t) => t.type === "pointerleave" || t.type === "pointercancel" || t.ty
|
|
|
199
199
|
n
|
|
200
200
|
);
|
|
201
201
|
};
|
|
202
|
-
class
|
|
202
|
+
class z {
|
|
203
203
|
constructor(s, e) {
|
|
204
204
|
h(this, "configSubject", new B({}));
|
|
205
205
|
h(this, "panEvent$");
|
|
@@ -237,8 +237,8 @@ class C {
|
|
|
237
237
|
), this.panEvent$ = this.configSubject.pipe(
|
|
238
238
|
q,
|
|
239
239
|
v((n) => {
|
|
240
|
-
var
|
|
241
|
-
const r = Math.max(1, ((
|
|
240
|
+
var E, g, P;
|
|
241
|
+
const r = Math.max(1, ((E = n.panConfig) == null ? void 0 : E.numInputs) ?? 1), a = Math.max(0, ((g = n.panConfig) == null ? void 0 : g.posThreshold) ?? 0), p = Math.max(0, ((P = n.panConfig) == null ? void 0 : P.delay) ?? 0), o = this.pointerDown$.pipe(
|
|
242
242
|
Q({
|
|
243
243
|
pointerEvent$: this.pointerEvent$,
|
|
244
244
|
trackMove: !0
|
|
@@ -264,9 +264,9 @@ class C {
|
|
|
264
264
|
(y) => m(this.pointerMove$, b(y)).pipe(
|
|
265
265
|
F(y),
|
|
266
266
|
l(
|
|
267
|
-
(
|
|
267
|
+
(f) => J(
|
|
268
268
|
y,
|
|
269
|
-
|
|
269
|
+
f,
|
|
270
270
|
a
|
|
271
271
|
)
|
|
272
272
|
)
|
|
@@ -276,10 +276,10 @@ class C {
|
|
|
276
276
|
).pipe(
|
|
277
277
|
v(() => x),
|
|
278
278
|
j(o),
|
|
279
|
-
|
|
279
|
+
$(([, { event: y, pointers: f }]) => ({
|
|
280
280
|
type: "panStart",
|
|
281
281
|
event: y,
|
|
282
|
-
latestActivePointers:
|
|
282
|
+
latestActivePointers: f
|
|
283
283
|
})),
|
|
284
284
|
w({
|
|
285
285
|
bufferSize: 1,
|
|
@@ -290,10 +290,10 @@ class C {
|
|
|
290
290
|
T(
|
|
291
291
|
() => o.pipe(
|
|
292
292
|
ie(1),
|
|
293
|
-
|
|
293
|
+
$(({ event: y, pointers: f }) => ({
|
|
294
294
|
type: "panMove",
|
|
295
295
|
event: y,
|
|
296
|
-
latestActivePointers:
|
|
296
|
+
latestActivePointers: f
|
|
297
297
|
}))
|
|
298
298
|
)
|
|
299
299
|
),
|
|
@@ -301,10 +301,10 @@ class C {
|
|
|
301
301
|
), L = I.pipe(
|
|
302
302
|
T(
|
|
303
303
|
() => d.pipe(
|
|
304
|
-
|
|
304
|
+
$(({ event: y, pointers: f }) => ({
|
|
305
305
|
type: "panEnd",
|
|
306
306
|
event: y,
|
|
307
|
-
latestActivePointers:
|
|
307
|
+
latestActivePointers: f
|
|
308
308
|
}))
|
|
309
309
|
)
|
|
310
310
|
)
|
|
@@ -314,9 +314,9 @@ class C {
|
|
|
314
314
|
return R.pipe(
|
|
315
315
|
Z,
|
|
316
316
|
j(R),
|
|
317
|
-
|
|
317
|
+
$(([y, { type: f }]) => ({
|
|
318
318
|
...y,
|
|
319
|
-
type:
|
|
319
|
+
type: f
|
|
320
320
|
}))
|
|
321
321
|
);
|
|
322
322
|
})
|
|
@@ -348,7 +348,7 @@ class C {
|
|
|
348
348
|
this.updateInternal(s, e);
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
|
-
class Ie extends
|
|
351
|
+
class Ie extends z {
|
|
352
352
|
constructor(e) {
|
|
353
353
|
var i;
|
|
354
354
|
super(e, {
|
|
@@ -366,10 +366,10 @@ class Ie extends C {
|
|
|
366
366
|
super.update(e, e.options);
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
|
-
const
|
|
369
|
+
const fe = (t) => (s) => s.pipe(
|
|
370
370
|
l((e) => Math.abs(e.velocityX) >= t || Math.abs(e.velocityY) >= t)
|
|
371
371
|
);
|
|
372
|
-
class Te extends
|
|
372
|
+
class Te extends z {
|
|
373
373
|
constructor(e) {
|
|
374
374
|
super(e, {
|
|
375
375
|
posThreshold: 0,
|
|
@@ -383,10 +383,10 @@ class Te extends C {
|
|
|
383
383
|
), a = this.panEvent$.pipe(l((p) => p.type === "panEnd"));
|
|
384
384
|
return r.pipe(
|
|
385
385
|
v((p) => a.pipe(
|
|
386
|
-
|
|
387
|
-
|
|
386
|
+
fe(n),
|
|
387
|
+
$(({ type: o, ...c }) => ({
|
|
388
388
|
type: "swipe",
|
|
389
|
-
angle:
|
|
389
|
+
angle: ge(
|
|
390
390
|
p.event,
|
|
391
391
|
c.event
|
|
392
392
|
),
|
|
@@ -402,7 +402,7 @@ class Te extends C {
|
|
|
402
402
|
super.update(e);
|
|
403
403
|
}
|
|
404
404
|
}
|
|
405
|
-
const
|
|
405
|
+
const Ee = ({
|
|
406
406
|
timeout: t,
|
|
407
407
|
pointerEvent$: s
|
|
408
408
|
}) => (e) => e.pipe(
|
|
@@ -428,7 +428,7 @@ const fe = ({
|
|
|
428
428
|
)
|
|
429
429
|
)
|
|
430
430
|
);
|
|
431
|
-
class be extends
|
|
431
|
+
class be extends z {
|
|
432
432
|
constructor(e) {
|
|
433
433
|
super(e);
|
|
434
434
|
h(this, "events$");
|
|
@@ -446,8 +446,8 @@ class be extends C {
|
|
|
446
446
|
}),
|
|
447
447
|
w(1)
|
|
448
448
|
), c = o.pipe(
|
|
449
|
-
l(({ pointers:
|
|
450
|
-
), u = (
|
|
449
|
+
l(({ pointers: g }) => g.length > 1)
|
|
450
|
+
), u = (g) => g.pipe(
|
|
451
451
|
re(this.pointerUp$.pipe(ae(n))),
|
|
452
452
|
Y()
|
|
453
453
|
);
|
|
@@ -455,18 +455,18 @@ class be extends C {
|
|
|
455
455
|
this.pointerDown$,
|
|
456
456
|
o.pipe(oe())
|
|
457
457
|
).pipe(
|
|
458
|
-
G((
|
|
458
|
+
G((g) => {
|
|
459
459
|
const P = m(
|
|
460
|
-
b(
|
|
460
|
+
b(g),
|
|
461
461
|
this.pointerDown$
|
|
462
462
|
).pipe(w(1)), D = P.pipe(u), d = P.pipe(
|
|
463
463
|
we({
|
|
464
|
-
initialPointerEvent:
|
|
464
|
+
initialPointerEvent: g,
|
|
465
465
|
pointerEvent$: this.pointerEvent$,
|
|
466
466
|
tolerance: p
|
|
467
467
|
})
|
|
468
468
|
), x = P.pipe(
|
|
469
|
-
|
|
469
|
+
Ee({
|
|
470
470
|
pointerEvent$: this.pointerEvent$,
|
|
471
471
|
timeout: r
|
|
472
472
|
})
|
|
@@ -479,7 +479,7 @@ class be extends C {
|
|
|
479
479
|
), I = D.pipe(
|
|
480
480
|
me,
|
|
481
481
|
l((A) => A.length <= a),
|
|
482
|
-
|
|
482
|
+
$((A) => ({
|
|
483
483
|
type: "tap",
|
|
484
484
|
taps: A.length,
|
|
485
485
|
latestActivePointers: A,
|
|
@@ -490,7 +490,7 @@ class be extends C {
|
|
|
490
490
|
return I.pipe(
|
|
491
491
|
Z,
|
|
492
492
|
j(I),
|
|
493
|
-
|
|
493
|
+
$(([A, { type: L, taps: R }]) => ({
|
|
494
494
|
...A,
|
|
495
495
|
type: L,
|
|
496
496
|
taps: R
|
|
@@ -507,7 +507,7 @@ class be extends C {
|
|
|
507
507
|
super.update(e);
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
|
-
class Se extends
|
|
510
|
+
class Se extends z {
|
|
511
511
|
constructor(e = {}) {
|
|
512
512
|
super(e, {
|
|
513
513
|
numInputs: 2,
|
|
@@ -519,7 +519,7 @@ class Se extends C {
|
|
|
519
519
|
v(() => {
|
|
520
520
|
const i = this.panEvent$.pipe(
|
|
521
521
|
l((p) => p.type === "panStart"),
|
|
522
|
-
|
|
522
|
+
$((p) => ({
|
|
523
523
|
...p,
|
|
524
524
|
type: "rotateStart",
|
|
525
525
|
angle: 0,
|
|
@@ -543,10 +543,10 @@ class Se extends C {
|
|
|
543
543
|
M()
|
|
544
544
|
), r = n.pipe(
|
|
545
545
|
l((p) => p.type === "panMove"),
|
|
546
|
-
|
|
546
|
+
$((p) => ({ ...p, type: "rotateMove" }))
|
|
547
547
|
), a = n.pipe(
|
|
548
548
|
l((p) => p.type === "panEnd"),
|
|
549
|
-
|
|
549
|
+
$((p) => ({ ...p, type: "rotateEnd" }))
|
|
550
550
|
);
|
|
551
551
|
return m(i, r, a);
|
|
552
552
|
}),
|
|
@@ -562,7 +562,7 @@ const X = ({
|
|
|
562
562
|
initialEvent: s
|
|
563
563
|
}) => (e) => e.pipe(
|
|
564
564
|
O((i, n) => {
|
|
565
|
-
const a = ((i == null ? void 0 : i.pointers.length) ?? 0) !== n.pointers.length, p = (i == null ? void 0 : i.pointersAverageDistance) ?? n.pointersAverageDistance, o = a ? n.pointersAverageDistance : i && "initialPointersAverageDistance" in i ? i.initialPointersAverageDistance : n.pointersAverageDistance, c = o === 0 ? 1 : n.pointersAverageDistance / o, u = n.pointersAverageDistance - o,
|
|
565
|
+
const a = ((i == null ? void 0 : i.pointers.length) ?? 0) !== n.pointers.length, p = (i == null ? void 0 : i.pointersAverageDistance) ?? n.pointersAverageDistance, o = a ? n.pointersAverageDistance : i && "initialPointersAverageDistance" in i ? i.initialPointersAverageDistance : n.pointersAverageDistance, c = o === 0 ? 1 : n.pointersAverageDistance / o, u = n.pointersAverageDistance - o, E = n.pointersAverageDistance - o, g = a || p === 0 ? 1 : n.pointersAverageDistance / p;
|
|
566
566
|
return {
|
|
567
567
|
...i,
|
|
568
568
|
...n,
|
|
@@ -570,13 +570,13 @@ const X = ({
|
|
|
570
570
|
initialPointersAverageDistance: o,
|
|
571
571
|
scale: c,
|
|
572
572
|
distance: u,
|
|
573
|
-
deltaDistance:
|
|
574
|
-
deltaDistanceScale:
|
|
573
|
+
deltaDistance: E,
|
|
574
|
+
deltaDistanceScale: g
|
|
575
575
|
};
|
|
576
576
|
}, s),
|
|
577
|
-
|
|
577
|
+
$(({ initialPointersAverageDistance: i, ...n }) => n)
|
|
578
578
|
);
|
|
579
|
-
class
|
|
579
|
+
class Ce extends z {
|
|
580
580
|
constructor(e) {
|
|
581
581
|
super(e, {
|
|
582
582
|
...e == null ? void 0 : e.options,
|
|
@@ -631,7 +631,7 @@ class ze extends C {
|
|
|
631
631
|
super.update(e, e.options);
|
|
632
632
|
}
|
|
633
633
|
}
|
|
634
|
-
class
|
|
634
|
+
class ze {
|
|
635
635
|
constructor(s) {
|
|
636
636
|
h(this, "events$");
|
|
637
637
|
h(this, "recognizers");
|
|
@@ -641,27 +641,24 @@ class Ce {
|
|
|
641
641
|
).pipe(M()), this.state$ = ce(
|
|
642
642
|
this.recognizers.map((e) => e.state$)
|
|
643
643
|
).pipe(
|
|
644
|
-
|
|
644
|
+
$(
|
|
645
645
|
(e) => e.reduce((i, n) => ({
|
|
646
646
|
fingers: Math.max(i.fingers, n.fingers)
|
|
647
647
|
}))
|
|
648
648
|
)
|
|
649
649
|
);
|
|
650
650
|
}
|
|
651
|
-
|
|
652
|
-
s.style.touchAction = "none", s.style.userSelect = "none", this.options.recognizers.forEach((e) => {
|
|
653
|
-
|
|
654
|
-
container: s,
|
|
655
|
-
afterEventReceived: this.options.afterEventReceived
|
|
656
|
-
});
|
|
651
|
+
update(s) {
|
|
652
|
+
s.container && (s.container.style.touchAction = "none", s.container.style.userSelect = "none"), this.options.recognizers.forEach((e) => {
|
|
653
|
+
e.update(s);
|
|
657
654
|
});
|
|
658
655
|
}
|
|
659
656
|
}
|
|
660
657
|
export {
|
|
661
658
|
Ie as PanRecognizer,
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
659
|
+
Ce as PinchRecognizer,
|
|
660
|
+
ze as Recognizable,
|
|
661
|
+
z as Recognizer,
|
|
665
662
|
Se as RotateRecognizer,
|
|
666
663
|
Te as SwipeRecognizer,
|
|
667
664
|
be as TapRecognizer
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/core/utils/geometry.ts","../src/core/utils/utils.ts","../src/core/utils/events.ts","../src/core/recognizer/scanToRecognizerEvent.ts","../src/core/recognizer/operators.ts","../src/core/recognizer/utils.ts","../src/core/recognizer/Recognizer.ts","../src/core/pan/PanRecognizer.ts","../src/core/swipe/operators.ts","../src/core/swipe/SwipeRecognizer.ts","../src/core/tap/operators.ts","../src/core/tap/TapRecognizer.ts","../src/core/rotate/RotateRecognizer.ts","../src/core/pinch/mapPanEventToPinchEvent.ts","../src/core/pinch/PinchRecognizer.ts","../src/core/recognizable/Recognizable.ts"],"sourcesContent":["type Point = { x: number; y: number }\n\nexport function calculateDistance(pointA: Point, pointB: Point): number {\n return Math.sqrt(\n Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2),\n )\n}\n\nexport function calculateAverageDistance(pointerEvents: Point[]): number {\n const n = pointerEvents.length\n if (n < 2) return 0 // No distance if fewer than 2 pointers\n\n const totalDistance = pointerEvents.reduce((sum, event1, i) => {\n return (\n sum +\n pointerEvents.slice(i + 1).reduce((innerSum, event2) => {\n return innerSum + calculateDistance(event1, event2)\n }, 0)\n )\n }, 0)\n\n // Number of pairs is n choose 2: n * (n - 1) / 2\n const numberOfPairs = (n * (n - 1)) / 2\n return totalDistance / numberOfPairs\n}\n\nexport function calculateRadianAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the differences in coordinates\n const deltaX = pointerB.x - pointerA.x\n const deltaY = pointerB.y - pointerA.y\n\n // Calculate the angle in radians\n const angleInRadians = Math.atan2(deltaY, deltaX)\n\n // Return the angle in degrees\n return angleInRadians\n}\n\nexport function calculateDegreeAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the angle in radians\n const angleInRadians = calculateRadianAngleBetweenPoints(pointerA, pointerB)\n\n // Convert the angle to degrees (optional)\n const angleInDegrees = angleInRadians * (180 / Math.PI)\n\n // Return the angle in degrees\n return angleInDegrees\n}\n\nexport function calculateCentroid(points: Point[]) {\n const sum = points.reduce(\n (acc, point) => {\n acc.x += point.x\n acc.y += point.y\n\n return acc\n },\n { x: 0, y: 0 },\n )\n\n const numPoints = points.length || 1\n\n return {\n x: sum.x / numPoints,\n y: sum.y / numPoints,\n }\n}\n\nexport function calculateAngleDelta(\n initialPoints: Point[],\n newPoints: Point[],\n) {\n if (initialPoints.length !== newPoints.length) {\n throw new Error(\"Initial and new points arrays must have the same length.\")\n }\n\n const initialCentroid = calculateCentroid(initialPoints)\n const newCentroid = calculateCentroid(newPoints)\n\n let totalAngleDelta = 0\n\n for (let i = 0; i < initialPoints.length; i++) {\n const initialAngle = calculateRadianAngleBetweenPoints(\n initialCentroid,\n initialPoints[i]!,\n )\n const newAngle = calculateRadianAngleBetweenPoints(\n newCentroid,\n newPoints[i]!,\n )\n\n let angleDelta = newAngle - initialAngle\n\n // Normalize the angle delta to be within [-PI, PI]\n if (angleDelta > Math.PI) {\n angleDelta -= 2 * Math.PI\n } else if (angleDelta < -Math.PI) {\n angleDelta += 2 * Math.PI\n }\n\n totalAngleDelta += angleDelta\n }\n\n // Return the average angle delta\n const radianDelta = totalAngleDelta / initialPoints.length\n const degreesDelta = radianDelta * (180 / Math.PI)\n\n return { radianDelta, degreesDelta }\n}\n","import {\n Observable,\n filter,\n} from \"rxjs\"\nimport { calculateCentroid } from \"./geometry\"\n\nexport function isDefined<T>(\n arg: T | null | undefined,\n): arg is T extends null | undefined ? never : T {\n return arg !== null && arg !== undefined\n}\n\nexport const hasAtLeastOneItem = <T>(events: T[]): events is [T, ...T[]] =>\n events.length > 0\n\nexport const filterNotEmpty = <T>(\n stream: Observable<T[]>,\n): Observable<[T, ...T[]]> => stream.pipe(filter(hasAtLeastOneItem))\n\nexport function isWithinPosThreshold(\n startEvent: PointerEvent,\n endEvent: PointerEvent,\n posThreshold: number,\n) {\n const start = calculateCentroid([startEvent])\n const end = calculateCentroid([endEvent])\n\n // Determines if the movement qualifies as a drag\n return (\n Math.abs(end.x - start.x) >= posThreshold ||\n Math.abs(end.y - start.y) >= posThreshold\n )\n}\n\n/**\n * Avoid division by zero\n * Calculate velocity in pixels per second\n */\nexport const calculateVelocity = (\n delay: number,\n deltaX: number,\n deltaY: number,\n) => {\n const velocityX = delay > 0 ? deltaX / delay : 0\n const velocityY = delay > 0 ? deltaY / delay : 0\n\n return {\n velocityX,\n velocityY,\n }\n}\n","import {\n Observable,\n defer,\n filter,\n fromEvent,\n map,\n merge,\n mergeMap,\n of,\n scan,\n takeWhile,\n} from \"rxjs\"\nimport { isDefined } from \"./utils\"\n\nexport function matchPointer(pointer: PointerEvent) {\n return (stream: Observable<PointerEvent>) =>\n stream.pipe(\n filter((newPointer) => newPointer.pointerId === pointer.pointerId),\n )\n}\n\nexport const isPointerOffEvent = (pointerEvent: PointerEvent) =>\n pointerEvent.type === \"pointerleave\" ||\n pointerEvent.type === \"pointercancel\" ||\n pointerEvent.type === \"pointerup\"\n\nexport const fromPointerDown = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) =>\n fromEvent<PointerEvent>(container, \"pointerdown\").pipe(\n map(afterEventReceived),\n )\n\n/**\n * Track all pointerEvent for active fingers\n */\nexport const trackPointers =\n ({\n pointerEvent$,\n }: {\n pointerEvent$: Observable<PointerEvent>\n /**\n * Setting this value to false will not update the list\n * on pointer move. Use it if you only need to track number of active\n * fingers.\n */\n trackMove: boolean\n }) =>\n (stream: Observable<PointerEvent>) => {\n type PointersState = {\n event: PointerEvent\n pointers: Record<number, PointerEvent | undefined>\n }\n\n const pointerUp$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n const pointerLeave$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerleave\"),\n )\n const pointerCancel$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n const pointerMove$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n const isPointerRemoved = (event: PointerEvent) =>\n [\"pointercancel\", \"pointerleave\", \"pointerup\"].includes(event.type)\n\n return stream.pipe(\n mergeMap((pointerDown) => {\n const pointerDown$ = defer(() => of(pointerDown))\n\n const tracking$ = merge(\n pointerDown$,\n merge(pointerMove$, pointerCancel$, pointerLeave$, pointerUp$),\n ).pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerRemoved(event), true),\n )\n\n return tracking$\n }),\n scan<PointerEvent, PointersState, undefined>((acc, event) => {\n if (isPointerRemoved(event)) {\n const { [event.pointerId]: _deleted, ...rest } = acc?.pointers ?? {}\n\n return {\n event,\n pointers: rest,\n }\n }\n\n return {\n event,\n pointers: {\n ...(acc?.pointers ?? {}),\n [event.pointerId]: event,\n },\n }\n }, undefined),\n map(({ event, pointers }) => ({\n event,\n pointers: Object.values(pointers).filter(isDefined),\n })),\n )\n }\n","import { Observable, map, scan } from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { calculateVelocity } from \"../utils/utils\"\nimport {\n calculateAngleDelta,\n calculateAverageDistance,\n calculateCentroid,\n} from \"../utils/geometry\"\n\nexport interface RecognizerEventInput {\n event: PointerEvent\n latestActivePointers: PointerEvent[]\n}\n\ninterface RecognizerEventState extends RecognizerEventInput {\n startTime: number\n center: { x: number; y: number }\n deltaX: number\n deltaY: number\n deltaPointersAngle: number\n}\n\nconst calculateNewDelta = (\n newCenter: { x: number; y: number },\n prevCenter: { x: number; y: number },\n prevDeltaX: number,\n prevDeltaY: number,\n) => {\n const deltaX = newCenter.x - prevCenter.x + prevDeltaX\n const deltaY = newCenter.y - prevCenter.y + prevDeltaY\n\n return {\n deltaX,\n deltaY,\n }\n}\n\nexport const scanToRecognizerEvent = <T extends RecognizerEventInput>(\n stream: Observable<T>,\n): Observable<RecognizerEvent> => {\n const getCenterFromData = (data: T) =>\n calculateCentroid(\n !data.latestActivePointers.length\n ? [data.event]\n : data.latestActivePointers,\n )\n\n return stream.pipe(\n scan<T, RecognizerEventState, undefined>((acc, curr) => {\n const newCenter = getCenterFromData(curr)\n const prevCenter = acc?.center ?? newCenter\n const prevDeltaX = acc?.deltaX ?? 0\n const prevDeltaY = acc?.deltaY ?? 0\n const prevActivePointersNumber = acc?.latestActivePointers?.length ?? 1\n const currActivePointersNumber = curr.latestActivePointers?.length ?? 1\n\n const hasAddedOrRemovedAFinger =\n [\"pointerdown\", \"pointercancel\", \"pointerleave\", \"pointerup\"].includes(\n curr.event.type,\n ) && prevActivePointersNumber !== currActivePointersNumber\n\n const hasAtLeastOneFinger = currActivePointersNumber > 0\n\n const { deltaX, deltaY } =\n hasAddedOrRemovedAFinger && hasAtLeastOneFinger\n ? calculateNewDelta(newCenter, newCenter, prevDeltaX, prevDeltaY)\n : calculateNewDelta(newCenter, prevCenter, prevDeltaX, prevDeltaY)\n\n const { degreesDelta: deltaPointersAngle } =\n prevActivePointersNumber === currActivePointersNumber &&\n prevActivePointersNumber >= 2 &&\n currActivePointersNumber >= 2\n ? calculateAngleDelta(\n acc?.latestActivePointers ?? [],\n curr.latestActivePointers ?? [],\n )\n : { degreesDelta: 0 }\n\n return {\n startTime: new Date().getTime(),\n ...acc,\n ...curr,\n center: newCenter,\n deltaX,\n deltaY,\n deltaPointersAngle,\n }\n }, undefined),\n map((data) => {\n const {\n deltaX,\n deltaY,\n latestActivePointers,\n startTime,\n center,\n event,\n deltaPointersAngle,\n } = data\n const events = latestActivePointers ?? []\n\n // Calculate the change in time\n const now = Date.now()\n const delay = now - startTime\n\n const { velocityX, velocityY } = calculateVelocity(delay, deltaX, deltaY)\n const pointersAverageDistance =\n calculateAverageDistance(latestActivePointers)\n\n return {\n deltaX,\n deltaY,\n velocityX,\n velocityY,\n delay,\n center,\n pointers: events,\n startTime,\n event,\n deltaPointersAngle,\n pointersAverageDistance,\n } satisfies RecognizerEvent\n }),\n )\n}\n","import { Observable, filter } from \"rxjs\"\nimport { isPointerOffEvent } from \"../utils/events\"\n\nexport const isValidConfig = <T extends { container?: HTMLElement }>(\n stream: Observable<T>,\n) =>\n stream.pipe(\n filter(\n (config): config is T & { container: HTMLElement } => !!config.container,\n ),\n )\n\nexport const filterPointerOff = (stream: Observable<PointerEvent>) =>\n stream.pipe(filter(isPointerOffEvent))\n","import { fromEvent, map, merge } from \"rxjs\"\nimport { fromPointerDown } from \"../utils/events\"\n\nexport const getPointerEvents = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) => {\n const pointerDown$ = fromPointerDown({ afterEventReceived, container })\n const pointerUp$ = fromEvent<PointerEvent>(container, \"pointerup\").pipe(\n map(afterEventReceived),\n )\n const pointerMove$ = fromEvent<PointerEvent>(container, \"pointermove\").pipe(\n map(afterEventReceived),\n )\n /**\n * Mostly used to handle cursor leaving window on mouse pointers.\n */\n const pointerLeave$ = fromEvent<PointerEvent>(container, \"pointerleave\").pipe(\n map(afterEventReceived),\n )\n /**\n * Handle things such as contextual menu popup or\n * native swipe navigation conflict.\n */\n const pointerCancel$ = fromEvent<PointerEvent>(\n container,\n \"pointercancel\",\n ).pipe(map(afterEventReceived))\n\n return merge(\n pointerDown$,\n pointerCancel$,\n pointerLeave$,\n pointerUp$,\n pointerMove$,\n )\n}\n","import {\n BehaviorSubject,\n NEVER,\n Observable,\n exhaustMap,\n filter,\n first,\n map,\n merge,\n mergeMap,\n of,\n share,\n shareReplay,\n skip,\n switchMap,\n takeUntil,\n tap,\n timer,\n withLatestFrom,\n} from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { trackPointers, matchPointer } from \"../utils/events\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"./scanToRecognizerEvent\"\nimport { filterPointerOff, isValidConfig } from \"./operators\"\nimport { getPointerEvents } from \"./utils\"\n\ntype PanConfig = {\n posThreshold?: number\n delay?: number\n /**\n * Number of inputs to trigger the event.\n * Default to 1\n */\n numInputs?: number\n}\n\nexport type RecognizerConfig<Options> = {\n container?: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n options?: Options\n failWith?: { start$: Observable<unknown> }[]\n}\n\nexport interface PanEvent extends RecognizerEvent {\n type: \"panStart\" | \"panMove\" | \"panEnd\"\n}\n\nexport type State = {\n fingers: number\n}\n\nexport abstract class Recognizer<\n Options extends Record<any, any>,\n Event extends RecognizerEvent,\n> {\n protected configSubject = new BehaviorSubject<\n RecognizerConfig<Options> & {\n panConfig?: PanConfig\n }\n >({})\n protected panEvent$: Observable<PanEvent>\n protected pointerEvent$: Observable<PointerEvent>\n protected pointerDown$: Observable<PointerEvent>\n protected pointerUp$: Observable<PointerEvent>\n protected pointerCancel$: Observable<PointerEvent>\n protected pointerMove$: Observable<PointerEvent>\n protected pointerOff$: Observable<PointerEvent>\n\n public state$: Observable<State>\n\n abstract events$: Observable<Event>\n\n protected failWith$: Observable<unknown>\n\n protected config$ = this.configSubject.pipe(isValidConfig)\n\n constructor(config?: RecognizerConfig<Options>, panConfig?: PanConfig) {\n const stateSubject = new BehaviorSubject<State>({\n fingers: 0,\n })\n\n this.pointerEvent$ = this.config$.pipe(\n switchMap(({ container, afterEventReceived }) =>\n getPointerEvents({\n container,\n afterEventReceived,\n }),\n ),\n )\n\n this.pointerDown$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerdown\"),\n )\n\n this.pointerUp$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n\n this.pointerMove$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n this.pointerCancel$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n\n this.pointerOff$ = this.pointerEvent$.pipe(filterPointerOff)\n\n this.failWith$ = this.config$.pipe(\n switchMap(({ failWith }) =>\n !failWith?.length\n ? NEVER\n : merge(...(failWith?.map(({ start$ }) => start$) ?? [])),\n ),\n )\n\n this.panEvent$ = this.configSubject.pipe(\n isValidConfig,\n switchMap((config) => {\n const numInputs = Math.max(1, config.panConfig?.numInputs ?? 1)\n const posThreshold = Math.max(0, config.panConfig?.posThreshold ?? 0)\n const delay = Math.max(0, config.panConfig?.delay ?? 0)\n\n const trackPointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasEnoughFingers = (\n stream: Observable<{ event: PointerEvent; pointers: PointerEvent[] }>,\n ) =>\n stream.pipe(\n filter(\n (\n events,\n ): events is { event: PointerEvent; pointers: [PointerEvent] } =>\n events.pointers.length >= numInputs,\n ),\n )\n\n const hasNotEnoughFingers = (\n stream: Observable<{\n event: PointerEvent\n pointers: PointerEvent[]\n }>,\n ) => stream.pipe(filter((events) => events.pointers.length < numInputs))\n\n return trackPointers$.pipe(\n hasEnoughFingers,\n exhaustMap(({ pointers: initialPointerEvents }) => {\n const panReleased$ = trackPointers$.pipe(\n hasNotEnoughFingers,\n first(),\n share(),\n )\n\n const delay$ = timer(delay)\n\n const pointerDownPassingThreshold$ = merge(\n ...initialPointerEvents.map((pointerEvent) => of(pointerEvent)),\n this.pointerDown$,\n ).pipe(\n mergeMap((pointerDown) =>\n merge(this.pointerMove$, of(pointerDown)).pipe(\n matchPointer(pointerDown),\n filter((pointerEvent) =>\n isWithinPosThreshold(\n pointerDown,\n pointerEvent,\n posThreshold,\n ),\n ),\n ),\n ),\n first(),\n )\n\n const panStart$ = pointerDownPassingThreshold$.pipe(\n switchMap(() => delay$),\n withLatestFrom(trackPointers$),\n map(([, { event, pointers }]) => ({\n type: \"panStart\" as const,\n event,\n latestActivePointers: pointers,\n })),\n shareReplay({\n bufferSize: 1,\n refCount: false,\n }),\n takeUntil(panReleased$),\n )\n\n const panUpdate$ = panStart$.pipe(\n mergeMap(() =>\n trackPointers$.pipe(\n skip(1),\n map(({ event, pointers }) => ({\n type: \"panMove\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n takeUntil(panReleased$),\n )\n\n const panEnd$ = panStart$.pipe(\n mergeMap(() =>\n panReleased$.pipe(\n map(({ event, pointers }) => ({\n type: \"panEnd\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n )\n\n const rawEvent$ = merge(panStart$, panUpdate$, panEnd$).pipe(\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type }]) => ({\n ...recognizerEvent,\n type,\n })),\n )\n }),\n )\n }),\n tap((event) => {\n stateSubject.next({\n fingers: event.pointers.length,\n })\n }),\n share(),\n )\n\n this.state$ = stateSubject.asObservable()\n\n this.updateInternal(config ?? {}, panConfig)\n }\n\n private updateInternal(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n const existingConfig = this.configSubject.getValue()\n\n this.configSubject.next({\n ...existingConfig,\n ...config,\n ...(config.options && {\n options: { ...existingConfig.options, ...config.options },\n }),\n panConfig: {\n ...existingConfig.panConfig,\n ...panConfig,\n },\n })\n }\n\n public update(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n this.updateInternal(config, panConfig)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n PanRecognizerInterface,\n PanRecognizerOptions,\n} from \"./PanRecognizerInterface\"\n\nexport class PanRecognizer\n extends Recognizer<PanRecognizerOptions, PanEvent>\n implements PanRecognizerInterface\n{\n public events$: Observable<PanEvent>\n public start$: Observable<PanEvent>\n public end$: Observable<PanEvent>\n\n constructor(config?: RecognizerConfig<PanRecognizerOptions>) {\n super(config, {\n ...config,\n posThreshold: config?.options?.posThreshold ?? 15,\n })\n\n this.events$ = this.panEvent$\n\n this.start$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n )\n\n this.end$ = this.events$.pipe(filter((event) => event.type === \"panEnd\"))\n }\n\n public update(config: RecognizerConfig<PanRecognizerOptions>) {\n super.update(config, config.options)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\n\nexport const isRecognizedAsSwipe =\n (escapeVelocity: number) => (stream: Observable<PanEvent>) =>\n stream.pipe(\n filter((event) => {\n return (\n Math.abs(event.velocityX) >= escapeVelocity ||\n Math.abs(event.velocityY) >= escapeVelocity\n )\n }),\n )\n","import {\n Observable,\n filter,\n map,\n share,\n switchMap,\n} from \"rxjs\"\nimport { calculateDegreeAngleBetweenPoints } from \"../utils/geometry\"\nimport { isRecognizedAsSwipe } from \"./operators\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n SwipeEvent,\n SwipeRecognizerInterface,\n SwipeRecognizerOptions,\n} from \"./SwipeRecognizerInterface\"\n\nexport class SwipeRecognizer\n extends Recognizer<SwipeRecognizerOptions, SwipeEvent>\n implements SwipeRecognizerInterface\n{\n public events$: Observable<SwipeEvent>\n\n constructor(config?: RecognizerConfig<SwipeRecognizerOptions>) {\n super(config, {\n posThreshold: 0,\n numInputs: 1,\n })\n\n this.events$ = this.config$.pipe(\n switchMap((initializedWith) => {\n const { escapeVelocity = 0.9 } = initializedWith.options ?? {}\n\n const panStart$ = this.panEvent$.pipe(\n filter((e) => e.type === \"panStart\"),\n )\n\n const panEnd$ = this.panEvent$.pipe(filter((e) => e.type === \"panEnd\"))\n\n return panStart$.pipe(\n switchMap((startEvent) => {\n return panEnd$.pipe(\n isRecognizedAsSwipe(escapeVelocity),\n map(({ type, ...rest }) => {\n return {\n type: \"swipe\" as const,\n angle: calculateDegreeAngleBetweenPoints(\n startEvent.event,\n rest.event,\n ),\n ...rest,\n }\n }),\n )\n }),\n share(),\n )\n }),\n )\n }\n\n public update(config: RecognizerConfig<SwipeRecognizerOptions>) {\n super.update(config)\n }\n}\n","import { Observable, filter, mergeMap, takeUntil, takeWhile, timer } from \"rxjs\"\nimport { isPointerOffEvent, matchPointer } from \"../utils/events\"\nimport { filterPointerOff } from \"../recognizer/operators\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\n\nexport const takeWhenPressedTooLong =\n ({\n timeout,\n pointerEvent$,\n }: {\n timeout: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n timer(timeout).pipe(\n takeUntil(\n pointerEvent$.pipe(filterPointerOff, matchPointer(pointerDown)),\n ),\n ),\n ),\n )\n\nexport const takeWhenOutsideThreshold =\n ({\n initialPointerEvent,\n pointerEvent$,\n tolerance,\n }: {\n initialPointerEvent: PointerEvent\n tolerance: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n pointerEvent$.pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerOffEvent(event), true),\n filter((event) =>\n isWithinPosThreshold(initialPointerEvent, event, tolerance),\n ),\n ),\n ),\n )\n","import {\n Observable,\n buffer,\n debounceTime,\n exhaustMap,\n filter,\n first,\n ignoreElements,\n map,\n merge,\n of,\n share,\n shareReplay,\n switchMap,\n takeUntil,\n withLatestFrom,\n} from \"rxjs\"\nimport { filterNotEmpty } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"../recognizer/scanToRecognizerEvent\"\nimport { trackPointers } from \"../utils/events\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n TapEvent,\n TapRecognizerInterface,\n TapRecognizerOptions,\n} from \"./TapRecognizerInterface\"\nimport { takeWhenOutsideThreshold, takeWhenPressedTooLong } from \"./operators\"\n\nexport class TapRecognizer\n extends Recognizer<TapRecognizerOptions, TapEvent>\n implements TapRecognizerInterface\n{\n public events$: Observable<TapEvent>\n\n constructor(options?: RecognizerConfig<TapRecognizerOptions>) {\n super(options)\n\n this.events$ = this.config$.pipe(\n switchMap((config) => {\n const {\n multiTapThreshold = 0,\n maximumPressTime = 150,\n maxTaps = 1,\n tolerance = 10,\n } = config.options ?? {}\n\n const activePointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasMoreThanOneActivePointer$ = activePointers$.pipe(\n filter(({ pointers }) => pointers.length > 1),\n )\n\n const bufferPointerDowns = (stream: Observable<PointerEvent>) =>\n stream.pipe(\n buffer(this.pointerUp$.pipe(debounceTime(multiTapThreshold))),\n first(),\n )\n\n const tap$ = merge(\n this.pointerDown$,\n activePointers$.pipe(ignoreElements()),\n ).pipe(\n exhaustMap((initialPointerEvent) => {\n const pointerDowns$ = merge(\n of(initialPointerEvent),\n this.pointerDown$,\n ).pipe(shareReplay(1))\n\n const pointerDownsBuffered$ = pointerDowns$.pipe(bufferPointerDowns)\n\n /**\n * Exit condition for `tolerance`\n */\n const clickedTooFarFromOriginalTap$ = pointerDowns$.pipe(\n takeWhenOutsideThreshold({\n initialPointerEvent,\n pointerEvent$: this.pointerEvent$,\n tolerance,\n }),\n )\n\n /**\n * Exit condition for `maximumPressTime`\n */\n const hasFingersPressedForTooLong$ = pointerDowns$.pipe(\n takeWhenPressedTooLong({\n pointerEvent$: this.pointerEvent$,\n timeout: maximumPressTime,\n }),\n )\n\n const takeUntil$ = merge(\n this.failWith$,\n this.pointerCancel$,\n hasMoreThanOneActivePointer$,\n clickedTooFarFromOriginalTap$,\n hasFingersPressedForTooLong$,\n )\n\n const rawEvent$ = pointerDownsBuffered$.pipe(\n filterNotEmpty,\n filter((events) => events.length <= maxTaps),\n map((events) => ({\n type: \"tap\" as const,\n taps: events.length,\n latestActivePointers: events,\n event: events[0],\n })),\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type, taps }]) => ({\n ...recognizerEvent,\n type,\n taps,\n })),\n takeUntil(takeUntil$),\n )\n }),\n )\n\n return tap$\n }),\n share(),\n )\n }\n\n public update(config: RecognizerConfig<TapRecognizerOptions>): void {\n super.update(config)\n }\n}\n","import {\n Observable,\n filter,\n map,\n merge,\n scan,\n share,\n shareReplay,\n switchMap,\n} from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n RotateEvent,\n RotateRecognizerInterface,\n RotateRecognizerOptions,\n} from \"./RotateRecognizerInterface\"\n\nexport class RotateRecognizer\n extends Recognizer<RotateRecognizerOptions, RotateEvent>\n implements RotateRecognizerInterface\n{\n public events$: Observable<RotateEvent>\n\n constructor(config: RecognizerConfig<RotateRecognizerOptions> = {}) {\n super(config, {\n numInputs: 2,\n posThreshold: 15,\n ...config.options,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const rotateStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n map((event) => ({\n ...event,\n type: \"rotateStart\" as const,\n angle: 0,\n deltaAngle: 0,\n })),\n shareReplay(1),\n )\n\n const rotate$ = rotateStart$.pipe(\n switchMap(() =>\n this.panEvent$.pipe(\n scan<\n PanEvent,\n PanEvent & { angle: number; deltaAngle: number },\n undefined\n >((acc, current) => {\n const angle = (acc?.angle ?? 0) + current.deltaPointersAngle\n\n return {\n ...acc,\n ...current,\n angle,\n deltaAngle: current.deltaPointersAngle,\n }\n }, undefined),\n ),\n ),\n share(),\n )\n\n const rotateMove$ = rotate$.pipe(\n filter((event) => event.type === \"panMove\"),\n map((event) => ({ ...event, type: \"rotateMove\" as const })),\n )\n\n const rotateEnd$ = rotate$.pipe(\n filter((event) => event.type === \"panEnd\"),\n map((event) => ({ ...event, type: \"rotateEnd\" as const })),\n )\n\n return merge(rotateStart$, rotateMove$, rotateEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<RotateRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import { Observable, map, scan } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\nimport { PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport const mapPanEventToPinchEvent =\n ({\n type,\n initialEvent,\n }: {\n type: PinchEvent[\"type\"]\n initialEvent: PinchEvent | PanEvent | undefined\n }) =>\n (stream: Observable<PanEvent | PinchEvent>) =>\n stream.pipe(\n scan<\n PanEvent | PinchEvent,\n PinchEvent & {\n initialPointersAverageDistance: number\n },\n PinchEvent | PanEvent | undefined\n >((acc, curr) => {\n const previousPointersLength = acc?.pointers.length ?? 0\n const hasChangedFingers =\n previousPointersLength !== curr.pointers.length\n const previousPointersAverageDistance =\n acc?.pointersAverageDistance ?? curr.pointersAverageDistance\n\n /**\n * initial average distance is reset every time we change fingers\n * @important in case of 1 finger, distance will be 0\n */\n const initialPointersAverageDistance = hasChangedFingers\n ? curr.pointersAverageDistance\n : !!acc && \"initialPointersAverageDistance\" in acc\n ? acc.initialPointersAverageDistance\n : curr.pointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n */\n const scale =\n initialPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / initialPointersAverageDistance\n\n const distance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n const deltaDistance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n * Same when fingers change\n */\n const deltaDistanceScale =\n hasChangedFingers || previousPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / previousPointersAverageDistance\n\n return {\n ...acc,\n ...curr,\n type,\n initialPointersAverageDistance,\n scale,\n distance,\n deltaDistance,\n deltaDistanceScale,\n }\n }, initialEvent),\n map(({ initialPointersAverageDistance, ...rest }): PinchEvent => rest),\n )\n","import {\n Observable,\n filter,\n merge,\n of,\n pairwise,\n share,\n shareReplay,\n startWith,\n switchMap,\n takeWhile,\n} from \"rxjs\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport { mapPanEventToPinchEvent } from \"./mapPanEventToPinchEvent\"\nimport {\n PinchEvent,\n PinchRecognizerInterface,\n PinchRecognizerOptions,\n} from \"./PinchRecognizerInterface\"\n\nexport { type PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport class PinchRecognizer\n extends Recognizer<PinchRecognizerOptions, PinchEvent>\n implements PinchRecognizerInterface\n{\n public events$: Observable<PinchEvent>\n\n constructor(config?: RecognizerConfig<PinchRecognizerOptions>) {\n super(config, {\n ...config?.options,\n numInputs: 2,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const pinchStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n switchMap((event) =>\n of(event).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchStart\",\n initialEvent: undefined,\n }),\n ),\n ),\n shareReplay(1),\n )\n\n const pinchMove$ = pinchStart$.pipe(\n switchMap((initialEvent) => {\n return this.panEvent$.pipe(\n takeWhile((event) => event.type !== \"panEnd\"),\n mapPanEventToPinchEvent({\n type: \"pinchMove\",\n initialEvent,\n }),\n )\n }),\n )\n\n const pinchEnd$ = pinchStart$.pipe(\n switchMap((pinchStartEvent) =>\n this.panEvent$.pipe(\n // we cannot have a panEnd without a previous event so it will always emit\n startWith(pinchStartEvent),\n pairwise(),\n filter(([_, currEvent]) => currEvent.type === \"panEnd\"),\n switchMap(([previousEvent, currEvent]) =>\n of(currEvent).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchEnd\",\n initialEvent: previousEvent,\n }),\n ),\n ),\n ),\n ),\n )\n\n return merge(pinchStart$, pinchMove$, pinchEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<PinchRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import {\n Observable,\n ObservedValueOf,\n combineLatest,\n map,\n merge,\n share,\n} from \"rxjs\"\nimport { Recognizer } from \"../recognizer/Recognizer\"\nimport {\n RecognizableInterface,\n RecognizableState,\n} from \"./RecognizableInterface\"\n\nexport class Recognizable<T extends Recognizer<any, any>[]>\n implements RecognizableInterface<T>\n{\n events$: Observable<ObservedValueOf<T[number][\"events$\"]>>\n recognizers: T\n state$: Observable<RecognizableState>\n\n constructor(\n protected options: {\n recognizers: T\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n },\n ) {\n this.recognizers = options.recognizers\n this.events$ = merge(\n ...options.recognizers.map((recognizer) => recognizer.events$),\n ).pipe(share())\n\n this.state$ = combineLatest(\n this.recognizers.map((recognizer) => recognizer.state$),\n ).pipe(\n map((states) =>\n states.reduce((acc, state) => ({\n fingers: Math.max(acc.fingers, state.fingers),\n })),\n ),\n )\n }\n\n public initialize(container: HTMLElement) {\n /**\n * We have to disable touch-action otherwise every events will be followed\n * by a cancel event since the browser will try to handle touch.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action\n */\n container.style.touchAction = `none`\n\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n */\n container.style.userSelect = `none`\n\n this.options.recognizers.forEach((recognizer) => {\n console.log(\"recognizable update\")\n recognizer.update({\n container,\n afterEventReceived: this.options.afterEventReceived,\n })\n })\n }\n}\n"],"names":["calculateDistance","pointA","pointB","calculateAverageDistance","pointerEvents","n","totalDistance","sum","event1","i","innerSum","event2","numberOfPairs","calculateRadianAngleBetweenPoints","pointerA","pointerB","deltaX","deltaY","calculateDegreeAngleBetweenPoints","calculateCentroid","points","acc","point","numPoints","calculateAngleDelta","initialPoints","newPoints","initialCentroid","newCentroid","totalAngleDelta","initialAngle","angleDelta","radianDelta","degreesDelta","isDefined","arg","hasAtLeastOneItem","events","filterNotEmpty","stream","filter","isWithinPosThreshold","startEvent","endEvent","posThreshold","start","end","calculateVelocity","delay","velocityX","velocityY","matchPointer","pointer","newPointer","isPointerOffEvent","pointerEvent","fromPointerDown","container","afterEventReceived","event","fromEvent","map","trackPointers","pointerEvent$","pointerUp$","pointerLeave$","pointerCancel$","pointerMove$","isPointerRemoved","mergeMap","pointerDown","pointerDown$","defer","of","merge","takeWhile","scan","_deleted","rest","pointers","calculateNewDelta","newCenter","prevCenter","prevDeltaX","prevDeltaY","scanToRecognizerEvent","getCenterFromData","data","curr","prevActivePointersNumber","_a","currActivePointersNumber","_b","hasAddedOrRemovedAFinger","hasAtLeastOneFinger","deltaPointersAngle","latestActivePointers","startTime","center","pointersAverageDistance","isValidConfig","config","filterPointerOff","getPointerEvents","Recognizer","panConfig","__publicField","BehaviorSubject","stateSubject","switchMap","failWith","start$","NEVER","numInputs","trackPointers$","shareReplay","hasEnoughFingers","hasNotEnoughFingers","exhaustMap","initialPointerEvents","panReleased$","first","share","delay$","timer","panStart$","withLatestFrom","takeUntil","panUpdate$","skip","panEnd$","rawEvent$","recognizerEvent","type","tap","existingConfig","PanRecognizer","isRecognizedAsSwipe","escapeVelocity","SwipeRecognizer","initializedWith","e","takeWhenPressedTooLong","timeout","takeWhenOutsideThreshold","initialPointerEvent","tolerance","TapRecognizer","options","multiTapThreshold","maximumPressTime","maxTaps","activePointers$","hasMoreThanOneActivePointer$","bufferPointerDowns","buffer","debounceTime","ignoreElements","pointerDowns$","pointerDownsBuffered$","clickedTooFarFromOriginalTap$","hasFingersPressedForTooLong$","takeUntil$","taps","RotateRecognizer","rotateStart$","rotate$","current","angle","rotateMove$","rotateEnd$","mapPanEventToPinchEvent","initialEvent","hasChangedFingers","previousPointersAverageDistance","initialPointersAverageDistance","scale","distance","deltaDistance","deltaDistanceScale","PinchRecognizer","pinchStart$","pinchMove$","pinchEnd$","pinchStartEvent","startWith","pairwise","_","currEvent","previousEvent","Recognizable","recognizer","combineLatest","states","state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/core/utils/geometry.ts","../src/core/utils/utils.ts","../src/core/utils/events.ts","../src/core/recognizer/scanToRecognizerEvent.ts","../src/core/recognizer/operators.ts","../src/core/recognizer/utils.ts","../src/core/recognizer/Recognizer.ts","../src/core/pan/PanRecognizer.ts","../src/core/swipe/operators.ts","../src/core/swipe/SwipeRecognizer.ts","../src/core/tap/operators.ts","../src/core/tap/TapRecognizer.ts","../src/core/rotate/RotateRecognizer.ts","../src/core/pinch/mapPanEventToPinchEvent.ts","../src/core/pinch/PinchRecognizer.ts","../src/core/recognizable/Recognizable.ts"],"sourcesContent":["type Point = { x: number; y: number }\n\nexport function calculateDistance(pointA: Point, pointB: Point): number {\n return Math.sqrt(\n Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2),\n )\n}\n\nexport function calculateAverageDistance(pointerEvents: Point[]): number {\n const n = pointerEvents.length\n if (n < 2) return 0 // No distance if fewer than 2 pointers\n\n const totalDistance = pointerEvents.reduce((sum, event1, i) => {\n return (\n sum +\n pointerEvents.slice(i + 1).reduce((innerSum, event2) => {\n return innerSum + calculateDistance(event1, event2)\n }, 0)\n )\n }, 0)\n\n // Number of pairs is n choose 2: n * (n - 1) / 2\n const numberOfPairs = (n * (n - 1)) / 2\n return totalDistance / numberOfPairs\n}\n\nexport function calculateRadianAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the differences in coordinates\n const deltaX = pointerB.x - pointerA.x\n const deltaY = pointerB.y - pointerA.y\n\n // Calculate the angle in radians\n const angleInRadians = Math.atan2(deltaY, deltaX)\n\n // Return the angle in degrees\n return angleInRadians\n}\n\nexport function calculateDegreeAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the angle in radians\n const angleInRadians = calculateRadianAngleBetweenPoints(pointerA, pointerB)\n\n // Convert the angle to degrees (optional)\n const angleInDegrees = angleInRadians * (180 / Math.PI)\n\n // Return the angle in degrees\n return angleInDegrees\n}\n\nexport function calculateCentroid(points: Point[]) {\n const sum = points.reduce(\n (acc, point) => {\n acc.x += point.x\n acc.y += point.y\n\n return acc\n },\n { x: 0, y: 0 },\n )\n\n const numPoints = points.length || 1\n\n return {\n x: sum.x / numPoints,\n y: sum.y / numPoints,\n }\n}\n\nexport function calculateAngleDelta(\n initialPoints: Point[],\n newPoints: Point[],\n) {\n if (initialPoints.length !== newPoints.length) {\n throw new Error(\"Initial and new points arrays must have the same length.\")\n }\n\n const initialCentroid = calculateCentroid(initialPoints)\n const newCentroid = calculateCentroid(newPoints)\n\n let totalAngleDelta = 0\n\n for (let i = 0; i < initialPoints.length; i++) {\n const initialAngle = calculateRadianAngleBetweenPoints(\n initialCentroid,\n initialPoints[i]!,\n )\n const newAngle = calculateRadianAngleBetweenPoints(\n newCentroid,\n newPoints[i]!,\n )\n\n let angleDelta = newAngle - initialAngle\n\n // Normalize the angle delta to be within [-PI, PI]\n if (angleDelta > Math.PI) {\n angleDelta -= 2 * Math.PI\n } else if (angleDelta < -Math.PI) {\n angleDelta += 2 * Math.PI\n }\n\n totalAngleDelta += angleDelta\n }\n\n // Return the average angle delta\n const radianDelta = totalAngleDelta / initialPoints.length\n const degreesDelta = radianDelta * (180 / Math.PI)\n\n return { radianDelta, degreesDelta }\n}\n","import {\n Observable,\n filter,\n} from \"rxjs\"\nimport { calculateCentroid } from \"./geometry\"\n\nexport function isDefined<T>(\n arg: T | null | undefined,\n): arg is T extends null | undefined ? never : T {\n return arg !== null && arg !== undefined\n}\n\nexport const hasAtLeastOneItem = <T>(events: T[]): events is [T, ...T[]] =>\n events.length > 0\n\nexport const filterNotEmpty = <T>(\n stream: Observable<T[]>,\n): Observable<[T, ...T[]]> => stream.pipe(filter(hasAtLeastOneItem))\n\nexport function isWithinPosThreshold(\n startEvent: PointerEvent,\n endEvent: PointerEvent,\n posThreshold: number,\n) {\n const start = calculateCentroid([startEvent])\n const end = calculateCentroid([endEvent])\n\n // Determines if the movement qualifies as a drag\n return (\n Math.abs(end.x - start.x) >= posThreshold ||\n Math.abs(end.y - start.y) >= posThreshold\n )\n}\n\n/**\n * Avoid division by zero\n * Calculate velocity in pixels per second\n */\nexport const calculateVelocity = (\n delay: number,\n deltaX: number,\n deltaY: number,\n) => {\n const velocityX = delay > 0 ? deltaX / delay : 0\n const velocityY = delay > 0 ? deltaY / delay : 0\n\n return {\n velocityX,\n velocityY,\n }\n}\n","import {\n Observable,\n defer,\n filter,\n fromEvent,\n map,\n merge,\n mergeMap,\n of,\n scan,\n takeWhile,\n} from \"rxjs\"\nimport { isDefined } from \"./utils\"\n\nexport function matchPointer(pointer: PointerEvent) {\n return (stream: Observable<PointerEvent>) =>\n stream.pipe(\n filter((newPointer) => newPointer.pointerId === pointer.pointerId),\n )\n}\n\nexport const isPointerOffEvent = (pointerEvent: PointerEvent) =>\n pointerEvent.type === \"pointerleave\" ||\n pointerEvent.type === \"pointercancel\" ||\n pointerEvent.type === \"pointerup\"\n\nexport const fromPointerDown = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) =>\n fromEvent<PointerEvent>(container, \"pointerdown\").pipe(\n map(afterEventReceived),\n )\n\n/**\n * Track all pointerEvent for active fingers\n */\nexport const trackPointers =\n ({\n pointerEvent$,\n }: {\n pointerEvent$: Observable<PointerEvent>\n /**\n * Setting this value to false will not update the list\n * on pointer move. Use it if you only need to track number of active\n * fingers.\n */\n trackMove: boolean\n }) =>\n (stream: Observable<PointerEvent>) => {\n type PointersState = {\n event: PointerEvent\n pointers: Record<number, PointerEvent | undefined>\n }\n\n const pointerUp$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n const pointerLeave$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerleave\"),\n )\n const pointerCancel$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n const pointerMove$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n const isPointerRemoved = (event: PointerEvent) =>\n [\"pointercancel\", \"pointerleave\", \"pointerup\"].includes(event.type)\n\n return stream.pipe(\n mergeMap((pointerDown) => {\n const pointerDown$ = defer(() => of(pointerDown))\n\n const tracking$ = merge(\n pointerDown$,\n merge(pointerMove$, pointerCancel$, pointerLeave$, pointerUp$),\n ).pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerRemoved(event), true),\n )\n\n return tracking$\n }),\n scan<PointerEvent, PointersState, undefined>((acc, event) => {\n if (isPointerRemoved(event)) {\n const { [event.pointerId]: _deleted, ...rest } = acc?.pointers ?? {}\n\n return {\n event,\n pointers: rest,\n }\n }\n\n return {\n event,\n pointers: {\n ...(acc?.pointers ?? {}),\n [event.pointerId]: event,\n },\n }\n }, undefined),\n map(({ event, pointers }) => ({\n event,\n pointers: Object.values(pointers).filter(isDefined),\n })),\n )\n }\n","import { Observable, map, scan } from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { calculateVelocity } from \"../utils/utils\"\nimport {\n calculateAngleDelta,\n calculateAverageDistance,\n calculateCentroid,\n} from \"../utils/geometry\"\n\nexport interface RecognizerEventInput {\n event: PointerEvent\n latestActivePointers: PointerEvent[]\n}\n\ninterface RecognizerEventState extends RecognizerEventInput {\n startTime: number\n center: { x: number; y: number }\n deltaX: number\n deltaY: number\n deltaPointersAngle: number\n}\n\nconst calculateNewDelta = (\n newCenter: { x: number; y: number },\n prevCenter: { x: number; y: number },\n prevDeltaX: number,\n prevDeltaY: number,\n) => {\n const deltaX = newCenter.x - prevCenter.x + prevDeltaX\n const deltaY = newCenter.y - prevCenter.y + prevDeltaY\n\n return {\n deltaX,\n deltaY,\n }\n}\n\nexport const scanToRecognizerEvent = <T extends RecognizerEventInput>(\n stream: Observable<T>,\n): Observable<RecognizerEvent> => {\n const getCenterFromData = (data: T) =>\n calculateCentroid(\n !data.latestActivePointers.length\n ? [data.event]\n : data.latestActivePointers,\n )\n\n return stream.pipe(\n scan<T, RecognizerEventState, undefined>((acc, curr) => {\n const newCenter = getCenterFromData(curr)\n const prevCenter = acc?.center ?? newCenter\n const prevDeltaX = acc?.deltaX ?? 0\n const prevDeltaY = acc?.deltaY ?? 0\n const prevActivePointersNumber = acc?.latestActivePointers?.length ?? 1\n const currActivePointersNumber = curr.latestActivePointers?.length ?? 1\n\n const hasAddedOrRemovedAFinger =\n [\"pointerdown\", \"pointercancel\", \"pointerleave\", \"pointerup\"].includes(\n curr.event.type,\n ) && prevActivePointersNumber !== currActivePointersNumber\n\n const hasAtLeastOneFinger = currActivePointersNumber > 0\n\n const { deltaX, deltaY } =\n hasAddedOrRemovedAFinger && hasAtLeastOneFinger\n ? calculateNewDelta(newCenter, newCenter, prevDeltaX, prevDeltaY)\n : calculateNewDelta(newCenter, prevCenter, prevDeltaX, prevDeltaY)\n\n const { degreesDelta: deltaPointersAngle } =\n prevActivePointersNumber === currActivePointersNumber &&\n prevActivePointersNumber >= 2 &&\n currActivePointersNumber >= 2\n ? calculateAngleDelta(\n acc?.latestActivePointers ?? [],\n curr.latestActivePointers ?? [],\n )\n : { degreesDelta: 0 }\n\n return {\n startTime: new Date().getTime(),\n ...acc,\n ...curr,\n center: newCenter,\n deltaX,\n deltaY,\n deltaPointersAngle,\n }\n }, undefined),\n map((data) => {\n const {\n deltaX,\n deltaY,\n latestActivePointers,\n startTime,\n center,\n event,\n deltaPointersAngle,\n } = data\n const events = latestActivePointers ?? []\n\n // Calculate the change in time\n const now = Date.now()\n const delay = now - startTime\n\n const { velocityX, velocityY } = calculateVelocity(delay, deltaX, deltaY)\n const pointersAverageDistance =\n calculateAverageDistance(latestActivePointers)\n\n return {\n deltaX,\n deltaY,\n velocityX,\n velocityY,\n delay,\n center,\n pointers: events,\n startTime,\n event,\n deltaPointersAngle,\n pointersAverageDistance,\n } satisfies RecognizerEvent\n }),\n )\n}\n","import { Observable, filter } from \"rxjs\"\nimport { isPointerOffEvent } from \"../utils/events\"\n\nexport const isValidConfig = <T extends { container?: HTMLElement }>(\n stream: Observable<T>,\n) =>\n stream.pipe(\n filter(\n (config): config is T & { container: HTMLElement } => !!config.container,\n ),\n )\n\nexport const filterPointerOff = (stream: Observable<PointerEvent>) =>\n stream.pipe(filter(isPointerOffEvent))\n","import { fromEvent, map, merge } from \"rxjs\"\nimport { fromPointerDown } from \"../utils/events\"\n\nexport const getPointerEvents = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) => {\n const pointerDown$ = fromPointerDown({ afterEventReceived, container })\n const pointerUp$ = fromEvent<PointerEvent>(container, \"pointerup\").pipe(\n map(afterEventReceived),\n )\n const pointerMove$ = fromEvent<PointerEvent>(container, \"pointermove\").pipe(\n map(afterEventReceived),\n )\n /**\n * Mostly used to handle cursor leaving window on mouse pointers.\n */\n const pointerLeave$ = fromEvent<PointerEvent>(container, \"pointerleave\").pipe(\n map(afterEventReceived),\n )\n /**\n * Handle things such as contextual menu popup or\n * native swipe navigation conflict.\n */\n const pointerCancel$ = fromEvent<PointerEvent>(\n container,\n \"pointercancel\",\n ).pipe(map(afterEventReceived))\n\n return merge(\n pointerDown$,\n pointerCancel$,\n pointerLeave$,\n pointerUp$,\n pointerMove$,\n )\n}\n","import {\n BehaviorSubject,\n NEVER,\n Observable,\n exhaustMap,\n filter,\n first,\n map,\n merge,\n mergeMap,\n of,\n share,\n shareReplay,\n skip,\n switchMap,\n takeUntil,\n tap,\n timer,\n withLatestFrom,\n} from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { trackPointers, matchPointer } from \"../utils/events\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"./scanToRecognizerEvent\"\nimport { filterPointerOff, isValidConfig } from \"./operators\"\nimport { getPointerEvents } from \"./utils\"\n\ntype PanConfig = {\n posThreshold?: number\n delay?: number\n /**\n * Number of inputs to trigger the event.\n * Default to 1\n */\n numInputs?: number\n}\n\nexport type RecognizerConfig<Options> = {\n container?: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n options?: Options\n failWith?: { start$: Observable<unknown> }[]\n}\n\nexport interface PanEvent extends RecognizerEvent {\n type: \"panStart\" | \"panMove\" | \"panEnd\"\n}\n\nexport type State = {\n fingers: number\n}\n\nexport abstract class Recognizer<\n Options extends Record<any, any>,\n Event extends RecognizerEvent,\n> {\n protected configSubject = new BehaviorSubject<\n RecognizerConfig<Options> & {\n panConfig?: PanConfig\n }\n >({})\n protected panEvent$: Observable<PanEvent>\n protected pointerEvent$: Observable<PointerEvent>\n protected pointerDown$: Observable<PointerEvent>\n protected pointerUp$: Observable<PointerEvent>\n protected pointerCancel$: Observable<PointerEvent>\n protected pointerMove$: Observable<PointerEvent>\n protected pointerOff$: Observable<PointerEvent>\n\n public state$: Observable<State>\n\n abstract events$: Observable<Event>\n\n protected failWith$: Observable<unknown>\n\n protected config$ = this.configSubject.pipe(isValidConfig)\n\n constructor(config?: RecognizerConfig<Options>, panConfig?: PanConfig) {\n const stateSubject = new BehaviorSubject<State>({\n fingers: 0,\n })\n\n this.pointerEvent$ = this.config$.pipe(\n switchMap(({ container, afterEventReceived }) =>\n getPointerEvents({\n container,\n afterEventReceived,\n }),\n ),\n )\n\n this.pointerDown$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerdown\"),\n )\n\n this.pointerUp$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n\n this.pointerMove$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n this.pointerCancel$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n\n this.pointerOff$ = this.pointerEvent$.pipe(filterPointerOff)\n\n this.failWith$ = this.config$.pipe(\n switchMap(({ failWith }) =>\n !failWith?.length\n ? NEVER\n : merge(...(failWith?.map(({ start$ }) => start$) ?? [])),\n ),\n )\n\n this.panEvent$ = this.configSubject.pipe(\n isValidConfig,\n switchMap((config) => {\n const numInputs = Math.max(1, config.panConfig?.numInputs ?? 1)\n const posThreshold = Math.max(0, config.panConfig?.posThreshold ?? 0)\n const delay = Math.max(0, config.panConfig?.delay ?? 0)\n\n const trackPointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasEnoughFingers = (\n stream: Observable<{ event: PointerEvent; pointers: PointerEvent[] }>,\n ) =>\n stream.pipe(\n filter(\n (\n events,\n ): events is { event: PointerEvent; pointers: [PointerEvent] } =>\n events.pointers.length >= numInputs,\n ),\n )\n\n const hasNotEnoughFingers = (\n stream: Observable<{\n event: PointerEvent\n pointers: PointerEvent[]\n }>,\n ) => stream.pipe(filter((events) => events.pointers.length < numInputs))\n\n return trackPointers$.pipe(\n hasEnoughFingers,\n exhaustMap(({ pointers: initialPointerEvents }) => {\n const panReleased$ = trackPointers$.pipe(\n hasNotEnoughFingers,\n first(),\n share(),\n )\n\n const delay$ = timer(delay)\n\n const pointerDownPassingThreshold$ = merge(\n ...initialPointerEvents.map((pointerEvent) => of(pointerEvent)),\n this.pointerDown$,\n ).pipe(\n mergeMap((pointerDown) =>\n merge(this.pointerMove$, of(pointerDown)).pipe(\n matchPointer(pointerDown),\n filter((pointerEvent) =>\n isWithinPosThreshold(\n pointerDown,\n pointerEvent,\n posThreshold,\n ),\n ),\n ),\n ),\n first(),\n )\n\n const panStart$ = pointerDownPassingThreshold$.pipe(\n switchMap(() => delay$),\n withLatestFrom(trackPointers$),\n map(([, { event, pointers }]) => ({\n type: \"panStart\" as const,\n event,\n latestActivePointers: pointers,\n })),\n shareReplay({\n bufferSize: 1,\n refCount: false,\n }),\n takeUntil(panReleased$),\n )\n\n const panUpdate$ = panStart$.pipe(\n mergeMap(() =>\n trackPointers$.pipe(\n skip(1),\n map(({ event, pointers }) => ({\n type: \"panMove\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n takeUntil(panReleased$),\n )\n\n const panEnd$ = panStart$.pipe(\n mergeMap(() =>\n panReleased$.pipe(\n map(({ event, pointers }) => ({\n type: \"panEnd\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n )\n\n const rawEvent$ = merge(panStart$, panUpdate$, panEnd$).pipe(\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type }]) => ({\n ...recognizerEvent,\n type,\n })),\n )\n }),\n )\n }),\n tap((event) => {\n stateSubject.next({\n fingers: event.pointers.length,\n })\n }),\n share(),\n )\n\n this.state$ = stateSubject.asObservable()\n\n this.updateInternal(config ?? {}, panConfig)\n }\n\n private updateInternal(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n const existingConfig = this.configSubject.getValue()\n\n this.configSubject.next({\n ...existingConfig,\n ...config,\n ...(config.options && {\n options: { ...existingConfig.options, ...config.options },\n }),\n panConfig: {\n ...existingConfig.panConfig,\n ...panConfig,\n },\n })\n }\n\n public update(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n this.updateInternal(config, panConfig)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n PanRecognizerInterface,\n PanRecognizerOptions,\n} from \"./PanRecognizerInterface\"\n\nexport class PanRecognizer\n extends Recognizer<PanRecognizerOptions, PanEvent>\n implements PanRecognizerInterface\n{\n public events$: Observable<PanEvent>\n public start$: Observable<PanEvent>\n public end$: Observable<PanEvent>\n\n constructor(config?: RecognizerConfig<PanRecognizerOptions>) {\n super(config, {\n ...config,\n posThreshold: config?.options?.posThreshold ?? 15,\n })\n\n this.events$ = this.panEvent$\n\n this.start$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n )\n\n this.end$ = this.events$.pipe(filter((event) => event.type === \"panEnd\"))\n }\n\n public update(config: RecognizerConfig<PanRecognizerOptions>) {\n super.update(config, config.options)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\n\nexport const isRecognizedAsSwipe =\n (escapeVelocity: number) => (stream: Observable<PanEvent>) =>\n stream.pipe(\n filter((event) => {\n return (\n Math.abs(event.velocityX) >= escapeVelocity ||\n Math.abs(event.velocityY) >= escapeVelocity\n )\n }),\n )\n","import {\n Observable,\n filter,\n map,\n share,\n switchMap,\n} from \"rxjs\"\nimport { calculateDegreeAngleBetweenPoints } from \"../utils/geometry\"\nimport { isRecognizedAsSwipe } from \"./operators\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n SwipeEvent,\n SwipeRecognizerInterface,\n SwipeRecognizerOptions,\n} from \"./SwipeRecognizerInterface\"\n\nexport class SwipeRecognizer\n extends Recognizer<SwipeRecognizerOptions, SwipeEvent>\n implements SwipeRecognizerInterface\n{\n public events$: Observable<SwipeEvent>\n\n constructor(config?: RecognizerConfig<SwipeRecognizerOptions>) {\n super(config, {\n posThreshold: 0,\n numInputs: 1,\n })\n\n this.events$ = this.config$.pipe(\n switchMap((initializedWith) => {\n const { escapeVelocity = 0.9 } = initializedWith.options ?? {}\n\n const panStart$ = this.panEvent$.pipe(\n filter((e) => e.type === \"panStart\"),\n )\n\n const panEnd$ = this.panEvent$.pipe(filter((e) => e.type === \"panEnd\"))\n\n return panStart$.pipe(\n switchMap((startEvent) => {\n return panEnd$.pipe(\n isRecognizedAsSwipe(escapeVelocity),\n map(({ type, ...rest }) => {\n return {\n type: \"swipe\" as const,\n angle: calculateDegreeAngleBetweenPoints(\n startEvent.event,\n rest.event,\n ),\n ...rest,\n }\n }),\n )\n }),\n share(),\n )\n }),\n )\n }\n\n public update(config: RecognizerConfig<SwipeRecognizerOptions>) {\n super.update(config)\n }\n}\n","import { Observable, filter, mergeMap, takeUntil, takeWhile, timer } from \"rxjs\"\nimport { isPointerOffEvent, matchPointer } from \"../utils/events\"\nimport { filterPointerOff } from \"../recognizer/operators\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\n\nexport const takeWhenPressedTooLong =\n ({\n timeout,\n pointerEvent$,\n }: {\n timeout: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n timer(timeout).pipe(\n takeUntil(\n pointerEvent$.pipe(filterPointerOff, matchPointer(pointerDown)),\n ),\n ),\n ),\n )\n\nexport const takeWhenOutsideThreshold =\n ({\n initialPointerEvent,\n pointerEvent$,\n tolerance,\n }: {\n initialPointerEvent: PointerEvent\n tolerance: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n pointerEvent$.pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerOffEvent(event), true),\n filter((event) =>\n isWithinPosThreshold(initialPointerEvent, event, tolerance),\n ),\n ),\n ),\n )\n","import {\n Observable,\n buffer,\n debounceTime,\n exhaustMap,\n filter,\n first,\n ignoreElements,\n map,\n merge,\n of,\n share,\n shareReplay,\n switchMap,\n takeUntil,\n withLatestFrom,\n} from \"rxjs\"\nimport { filterNotEmpty } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"../recognizer/scanToRecognizerEvent\"\nimport { trackPointers } from \"../utils/events\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n TapEvent,\n TapRecognizerInterface,\n TapRecognizerOptions,\n} from \"./TapRecognizerInterface\"\nimport { takeWhenOutsideThreshold, takeWhenPressedTooLong } from \"./operators\"\n\nexport class TapRecognizer\n extends Recognizer<TapRecognizerOptions, TapEvent>\n implements TapRecognizerInterface\n{\n public events$: Observable<TapEvent>\n\n constructor(options?: RecognizerConfig<TapRecognizerOptions>) {\n super(options)\n\n this.events$ = this.config$.pipe(\n switchMap((config) => {\n const {\n multiTapThreshold = 0,\n maximumPressTime = 150,\n maxTaps = 1,\n tolerance = 10,\n } = config.options ?? {}\n\n const activePointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasMoreThanOneActivePointer$ = activePointers$.pipe(\n filter(({ pointers }) => pointers.length > 1),\n )\n\n const bufferPointerDowns = (stream: Observable<PointerEvent>) =>\n stream.pipe(\n buffer(this.pointerUp$.pipe(debounceTime(multiTapThreshold))),\n first(),\n )\n\n const tap$ = merge(\n this.pointerDown$,\n activePointers$.pipe(ignoreElements()),\n ).pipe(\n exhaustMap((initialPointerEvent) => {\n const pointerDowns$ = merge(\n of(initialPointerEvent),\n this.pointerDown$,\n ).pipe(shareReplay(1))\n\n const pointerDownsBuffered$ = pointerDowns$.pipe(bufferPointerDowns)\n\n /**\n * Exit condition for `tolerance`\n */\n const clickedTooFarFromOriginalTap$ = pointerDowns$.pipe(\n takeWhenOutsideThreshold({\n initialPointerEvent,\n pointerEvent$: this.pointerEvent$,\n tolerance,\n }),\n )\n\n /**\n * Exit condition for `maximumPressTime`\n */\n const hasFingersPressedForTooLong$ = pointerDowns$.pipe(\n takeWhenPressedTooLong({\n pointerEvent$: this.pointerEvent$,\n timeout: maximumPressTime,\n }),\n )\n\n const takeUntil$ = merge(\n this.failWith$,\n this.pointerCancel$,\n hasMoreThanOneActivePointer$,\n clickedTooFarFromOriginalTap$,\n hasFingersPressedForTooLong$,\n )\n\n const rawEvent$ = pointerDownsBuffered$.pipe(\n filterNotEmpty,\n filter((events) => events.length <= maxTaps),\n map((events) => ({\n type: \"tap\" as const,\n taps: events.length,\n latestActivePointers: events,\n event: events[0],\n })),\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type, taps }]) => ({\n ...recognizerEvent,\n type,\n taps,\n })),\n takeUntil(takeUntil$),\n )\n }),\n )\n\n return tap$\n }),\n share(),\n )\n }\n\n public update(config: RecognizerConfig<TapRecognizerOptions>): void {\n super.update(config)\n }\n}\n","import {\n Observable,\n filter,\n map,\n merge,\n scan,\n share,\n shareReplay,\n switchMap,\n} from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n RotateEvent,\n RotateRecognizerInterface,\n RotateRecognizerOptions,\n} from \"./RotateRecognizerInterface\"\n\nexport class RotateRecognizer\n extends Recognizer<RotateRecognizerOptions, RotateEvent>\n implements RotateRecognizerInterface\n{\n public events$: Observable<RotateEvent>\n\n constructor(config: RecognizerConfig<RotateRecognizerOptions> = {}) {\n super(config, {\n numInputs: 2,\n posThreshold: 15,\n ...config.options,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const rotateStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n map((event) => ({\n ...event,\n type: \"rotateStart\" as const,\n angle: 0,\n deltaAngle: 0,\n })),\n shareReplay(1),\n )\n\n const rotate$ = rotateStart$.pipe(\n switchMap(() =>\n this.panEvent$.pipe(\n scan<\n PanEvent,\n PanEvent & { angle: number; deltaAngle: number },\n undefined\n >((acc, current) => {\n const angle = (acc?.angle ?? 0) + current.deltaPointersAngle\n\n return {\n ...acc,\n ...current,\n angle,\n deltaAngle: current.deltaPointersAngle,\n }\n }, undefined),\n ),\n ),\n share(),\n )\n\n const rotateMove$ = rotate$.pipe(\n filter((event) => event.type === \"panMove\"),\n map((event) => ({ ...event, type: \"rotateMove\" as const })),\n )\n\n const rotateEnd$ = rotate$.pipe(\n filter((event) => event.type === \"panEnd\"),\n map((event) => ({ ...event, type: \"rotateEnd\" as const })),\n )\n\n return merge(rotateStart$, rotateMove$, rotateEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<RotateRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import { Observable, map, scan } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\nimport { PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport const mapPanEventToPinchEvent =\n ({\n type,\n initialEvent,\n }: {\n type: PinchEvent[\"type\"]\n initialEvent: PinchEvent | PanEvent | undefined\n }) =>\n (stream: Observable<PanEvent | PinchEvent>) =>\n stream.pipe(\n scan<\n PanEvent | PinchEvent,\n PinchEvent & {\n initialPointersAverageDistance: number\n },\n PinchEvent | PanEvent | undefined\n >((acc, curr) => {\n const previousPointersLength = acc?.pointers.length ?? 0\n const hasChangedFingers =\n previousPointersLength !== curr.pointers.length\n const previousPointersAverageDistance =\n acc?.pointersAverageDistance ?? curr.pointersAverageDistance\n\n /**\n * initial average distance is reset every time we change fingers\n * @important in case of 1 finger, distance will be 0\n */\n const initialPointersAverageDistance = hasChangedFingers\n ? curr.pointersAverageDistance\n : !!acc && \"initialPointersAverageDistance\" in acc\n ? acc.initialPointersAverageDistance\n : curr.pointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n */\n const scale =\n initialPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / initialPointersAverageDistance\n\n const distance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n const deltaDistance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n * Same when fingers change\n */\n const deltaDistanceScale =\n hasChangedFingers || previousPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / previousPointersAverageDistance\n\n return {\n ...acc,\n ...curr,\n type,\n initialPointersAverageDistance,\n scale,\n distance,\n deltaDistance,\n deltaDistanceScale,\n }\n }, initialEvent),\n map(({ initialPointersAverageDistance, ...rest }): PinchEvent => rest),\n )\n","import {\n Observable,\n filter,\n merge,\n of,\n pairwise,\n share,\n shareReplay,\n startWith,\n switchMap,\n takeWhile,\n} from \"rxjs\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport { mapPanEventToPinchEvent } from \"./mapPanEventToPinchEvent\"\nimport {\n PinchEvent,\n PinchRecognizerInterface,\n PinchRecognizerOptions,\n} from \"./PinchRecognizerInterface\"\n\nexport { type PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport class PinchRecognizer\n extends Recognizer<PinchRecognizerOptions, PinchEvent>\n implements PinchRecognizerInterface\n{\n public events$: Observable<PinchEvent>\n\n constructor(config?: RecognizerConfig<PinchRecognizerOptions>) {\n super(config, {\n ...config?.options,\n numInputs: 2,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const pinchStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n switchMap((event) =>\n of(event).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchStart\",\n initialEvent: undefined,\n }),\n ),\n ),\n shareReplay(1),\n )\n\n const pinchMove$ = pinchStart$.pipe(\n switchMap((initialEvent) => {\n return this.panEvent$.pipe(\n takeWhile((event) => event.type !== \"panEnd\"),\n mapPanEventToPinchEvent({\n type: \"pinchMove\",\n initialEvent,\n }),\n )\n }),\n )\n\n const pinchEnd$ = pinchStart$.pipe(\n switchMap((pinchStartEvent) =>\n this.panEvent$.pipe(\n // we cannot have a panEnd without a previous event so it will always emit\n startWith(pinchStartEvent),\n pairwise(),\n filter(([_, currEvent]) => currEvent.type === \"panEnd\"),\n switchMap(([previousEvent, currEvent]) =>\n of(currEvent).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchEnd\",\n initialEvent: previousEvent,\n }),\n ),\n ),\n ),\n ),\n )\n\n return merge(pinchStart$, pinchMove$, pinchEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<PinchRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import {\n Observable,\n ObservedValueOf,\n combineLatest,\n map,\n merge,\n share,\n} from \"rxjs\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n RecognizableInterface,\n RecognizableState,\n} from \"./RecognizableInterface\"\n\nexport class Recognizable<T extends Recognizer<any, any>[]>\n implements RecognizableInterface<T>\n{\n events$: Observable<ObservedValueOf<T[number][\"events$\"]>>\n recognizers: T\n state$: Observable<RecognizableState>\n\n constructor(\n protected options: {\n recognizers: T\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n },\n ) {\n this.recognizers = options.recognizers\n this.events$ = merge(\n ...options.recognizers.map((recognizer) => recognizer.events$),\n ).pipe(share())\n\n this.state$ = combineLatest(\n this.recognizers.map((recognizer) => recognizer.state$),\n ).pipe(\n map((states) =>\n states.reduce((acc, state) => ({\n fingers: Math.max(acc.fingers, state.fingers),\n })),\n ),\n )\n }\n\n public update(options: RecognizerConfig<unknown>) {\n if (options.container) {\n /**\n * We have to disable touch-action otherwise every events will be followed\n * by a cancel event since the browser will try to handle touch.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action\n */\n options.container.style.touchAction = `none`\n\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n */\n options.container.style.userSelect = `none`\n }\n\n this.options.recognizers.forEach((recognizer) => {\n recognizer.update(options)\n })\n }\n}\n"],"names":["calculateDistance","pointA","pointB","calculateAverageDistance","pointerEvents","n","totalDistance","sum","event1","i","innerSum","event2","numberOfPairs","calculateRadianAngleBetweenPoints","pointerA","pointerB","deltaX","deltaY","calculateDegreeAngleBetweenPoints","calculateCentroid","points","acc","point","numPoints","calculateAngleDelta","initialPoints","newPoints","initialCentroid","newCentroid","totalAngleDelta","initialAngle","angleDelta","radianDelta","degreesDelta","isDefined","arg","hasAtLeastOneItem","events","filterNotEmpty","stream","filter","isWithinPosThreshold","startEvent","endEvent","posThreshold","start","end","calculateVelocity","delay","velocityX","velocityY","matchPointer","pointer","newPointer","isPointerOffEvent","pointerEvent","fromPointerDown","container","afterEventReceived","event","fromEvent","map","trackPointers","pointerEvent$","pointerUp$","pointerLeave$","pointerCancel$","pointerMove$","isPointerRemoved","mergeMap","pointerDown","pointerDown$","defer","of","merge","takeWhile","scan","_deleted","rest","pointers","calculateNewDelta","newCenter","prevCenter","prevDeltaX","prevDeltaY","scanToRecognizerEvent","getCenterFromData","data","curr","prevActivePointersNumber","_a","currActivePointersNumber","_b","hasAddedOrRemovedAFinger","hasAtLeastOneFinger","deltaPointersAngle","latestActivePointers","startTime","center","pointersAverageDistance","isValidConfig","config","filterPointerOff","getPointerEvents","Recognizer","panConfig","__publicField","BehaviorSubject","stateSubject","switchMap","failWith","start$","NEVER","numInputs","trackPointers$","shareReplay","hasEnoughFingers","hasNotEnoughFingers","exhaustMap","initialPointerEvents","panReleased$","first","share","delay$","timer","panStart$","withLatestFrom","takeUntil","panUpdate$","skip","panEnd$","rawEvent$","recognizerEvent","type","tap","existingConfig","PanRecognizer","isRecognizedAsSwipe","escapeVelocity","SwipeRecognizer","initializedWith","e","takeWhenPressedTooLong","timeout","takeWhenOutsideThreshold","initialPointerEvent","tolerance","TapRecognizer","options","multiTapThreshold","maximumPressTime","maxTaps","activePointers$","hasMoreThanOneActivePointer$","bufferPointerDowns","buffer","debounceTime","ignoreElements","pointerDowns$","pointerDownsBuffered$","clickedTooFarFromOriginalTap$","hasFingersPressedForTooLong$","takeUntil$","taps","RotateRecognizer","rotateStart$","rotate$","current","angle","rotateMove$","rotateEnd$","mapPanEventToPinchEvent","initialEvent","hasChangedFingers","previousPointersAverageDistance","initialPointersAverageDistance","scale","distance","deltaDistance","deltaDistanceScale","PinchRecognizer","pinchStart$","pinchMove$","pinchEnd$","pinchStartEvent","startWith","pairwise","_","currEvent","previousEvent","Recognizable","recognizer","combineLatest","states","state"],"mappings":"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"}
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(u,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("rxjs")):typeof define=="function"&&define.amd?define(["exports","rxjs"],e):(u=typeof globalThis<"u"?globalThis:u||self,e(u.gesturx={},u.rxjs))})(this,function(u,e){"use strict";var pe=Object.defineProperty;var oe=(u,e,P)=>e in u?pe(u,e,{enumerable:!0,configurable:!0,writable:!0,value:P}):u[e]=P;var h=(u,e,P)=>(oe(u,typeof e!="symbol"?e+"":e,P),P);function P(i,p){return Math.sqrt(Math.pow(p.x-i.x,2)+Math.pow(p.y-i.y,2))}function N(i){const p=i.length;if(p<2)return 0;const t=i.reduce((n,r,l)=>n+i.slice(l+1).reduce((a,s)=>a+P(r,s),0),0),o=p*(p-1)/2;return t/o}function S(i,p){const t=p.x-i.x,o=p.y-i.y;return Math.atan2(o,t)}function V(i,p){return S(i,p)*(180/Math.PI)}function R(i){const p=i.reduce((o,n)=>(o.x+=n.x,o.y+=n.y,o),{x:0,y:0}),t=i.length||1;return{x:p.x/t,y:p.y/t}}function B(i,p){if(i.length!==p.length)throw new Error("Initial and new points arrays must have the same length.");const t=R(i),o=R(p);let n=0;for(let a=0;a<i.length;a++){const s=S(t,i[a]);let g=S(o,p[a])-s;g>Math.PI?g-=2*Math.PI:g<-Math.PI&&(g+=2*Math.PI),n+=g}const r=n/i.length,l=r*(180/Math.PI);return{radianDelta:r,degreesDelta:l}}function q(i){return i!=null}const _=i=>i.length>0,W=i=>i.pipe(e.filter(_));function k(i,p,t){const o=R([i]),n=R([p]);return Math.abs(n.x-o.x)>=t||Math.abs(n.y-o.y)>=t}const G=(i,p,t)=>{const o=i>0?p/i:0,n=i>0?t/i:0;return{velocityX:o,velocityY:n}};function T(i){return p=>p.pipe(e.filter(t=>t.pointerId===i.pointerId))}const C=i=>i.type==="pointerleave"||i.type==="pointercancel"||i.type==="pointerup",H=({container:i,afterEventReceived:p=t=>t})=>e.fromEvent(i,"pointerdown").pipe(e.map(p)),O=({pointerEvent$:i})=>p=>{const t=i.pipe(e.filter(a=>a.type==="pointerup")),o=i.pipe(e.filter(a=>a.type==="pointerleave")),n=i.pipe(e.filter(a=>a.type==="pointercancel")),r=i.pipe(e.filter(a=>a.type==="pointermove")),l=a=>["pointercancel","pointerleave","pointerup"].includes(a.type);return p.pipe(e.mergeMap(a=>{const s=e.defer(()=>e.of(a));return e.merge(s,e.merge(r,n,o,t)).pipe(T(a),e.takeWhile(g=>!l(g),!0))}),e.scan((a,s)=>{if(l(s)){const{[s.pointerId]:c,...g}=(a==null?void 0:a.pointers)??{};return{event:s,pointers:g}}return{event:s,pointers:{...(a==null?void 0:a.pointers)??{},[s.pointerId]:s}}},void 0),e.map(({event:a,pointers:s})=>({event:a,pointers:Object.values(s).filter(q)})))},F=(i,p,t,o)=>{const n=i.x-p.x+t,r=i.y-p.y+o;return{deltaX:n,deltaY:r}},L=i=>{const p=t=>R(t.latestActivePointers.length?t.latestActivePointers:[t.event]);return i.pipe(e.scan((t,o)=>{var v,D;const n=p(o),r=(t==null?void 0:t.center)??n,l=(t==null?void 0:t.deltaX)??0,a=(t==null?void 0:t.deltaY)??0,s=((v=t==null?void 0:t.latestActivePointers)==null?void 0:v.length)??1,c=((D=o.latestActivePointers)==null?void 0:D.length)??1,g=["pointerdown","pointercancel","pointerleave","pointerup"].includes(o.event.type)&&s!==c,w=c>0,{deltaX:d,deltaY:f}=g&&w?F(n,n,l,a):F(n,r,l,a),{degreesDelta:m}=s===c&&s>=2&&c>=2?B((t==null?void 0:t.latestActivePointers)??[],o.latestActivePointers??[]):{degreesDelta:0};return{startTime:new Date().getTime(),...t,...o,center:n,deltaX:d,deltaY:f,deltaPointersAngle:m}},void 0),e.map(t=>{const{deltaX:o,deltaY:n,latestActivePointers:r,startTime:l,center:a,event:s,deltaPointersAngle:c}=t,g=r??[],d=Date.now()-l,{velocityX:f,velocityY:m}=G(d,o,n),v=N(r);return{deltaX:o,deltaY:n,velocityX:f,velocityY:m,delay:d,center:a,pointers:g,startTime:l,event:s,deltaPointersAngle:c,pointersAverageDistance:v}}))},U=i=>i.pipe(e.filter(p=>!!p.container)),X=i=>i.pipe(e.filter(C)),J=({container:i,afterEventReceived:p=t=>t})=>{const t=H({afterEventReceived:p,container:i}),o=e.fromEvent(i,"pointerup").pipe(e.map(p)),n=e.fromEvent(i,"pointermove").pipe(e.map(p)),r=e.fromEvent(i,"pointerleave").pipe(e.map(p)),l=e.fromEvent(i,"pointercancel").pipe(e.map(p));return e.merge(t,l,r,o,n)};class E{constructor(p,t){h(this,"configSubject",new e.BehaviorSubject({}));h(this,"panEvent$");h(this,"pointerEvent$");h(this,"pointerDown$");h(this,"pointerUp$");h(this,"pointerCancel$");h(this,"pointerMove$");h(this,"pointerOff$");h(this,"state$");h(this,"failWith$");h(this,"config$",this.configSubject.pipe(U));const o=new e.BehaviorSubject({fingers:0});this.pointerEvent$=this.config$.pipe(e.switchMap(({container:n,afterEventReceived:r})=>J({container:n,afterEventReceived:r}))),this.pointerDown$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointerdown")),this.pointerUp$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointerup")),this.pointerMove$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointermove")),this.pointerCancel$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointercancel")),this.pointerOff$=this.pointerEvent$.pipe(X),this.failWith$=this.config$.pipe(e.switchMap(({failWith:n})=>n!=null&&n.length?e.merge(...(n==null?void 0:n.map(({start$:r})=>r))??[]):e.NEVER)),this.panEvent$=this.configSubject.pipe(U,e.switchMap(n=>{var w,d,f;const r=Math.max(1,((w=n.panConfig)==null?void 0:w.numInputs)??1),l=Math.max(0,((d=n.panConfig)==null?void 0:d.posThreshold)??0),a=Math.max(0,((f=n.panConfig)==null?void 0:f.delay)??0),s=this.pointerDown$.pipe(O({pointerEvent$:this.pointerEvent$,trackMove:!0}),e.shareReplay(1)),c=m=>m.pipe(e.filter(v=>v.pointers.length>=r)),g=m=>m.pipe(e.filter(v=>v.pointers.length<r));return s.pipe(c,e.exhaustMap(({pointers:m})=>{const v=s.pipe(g,e.first(),e.share()),D=e.timer(a),A=e.merge(...m.map($=>e.of($)),this.pointerDown$).pipe(e.mergeMap($=>e.merge(this.pointerMove$,e.of($)).pipe(T($),e.filter(M=>k($,M,l)))),e.first()).pipe(e.switchMap(()=>D),e.withLatestFrom(s),e.map(([,{event:$,pointers:M}])=>({type:"panStart",event:$,latestActivePointers:M})),e.shareReplay({bufferSize:1,refCount:!1}),e.takeUntil(v)),y=A.pipe(e.mergeMap(()=>s.pipe(e.skip(1),e.map(({event:$,pointers:M})=>({type:"panMove",event:$,latestActivePointers:M})))),e.takeUntil(v)),z=A.pipe(e.mergeMap(()=>v.pipe(e.map(({event:$,pointers:M})=>({type:"panEnd",event:$,latestActivePointers:M}))))),b=e.merge(A,y,z).pipe(e.shareReplay(1));return b.pipe(L,e.withLatestFrom(b),e.map(([$,{type:M}])=>({...$,type:M})))}))}),e.tap(n=>{o.next({fingers:n.pointers.length})}),e.share()),this.state$=o.asObservable(),this.updateInternal(p??{},t)}updateInternal(p,t){const o=this.configSubject.getValue();this.configSubject.next({...o,...p,...p.options&&{options:{...o.options,...p.options}},panConfig:{...o.panConfig,...t}})}update(p,t){this.updateInternal(p,t)}}class K extends E{constructor(t){var o;super(t,{...t,posThreshold:((o=t==null?void 0:t.options)==null?void 0:o.posThreshold)??15});h(this,"events$");h(this,"start$");h(this,"end$");this.events$=this.panEvent$,this.start$=this.panEvent$.pipe(e.filter(n=>n.type==="panStart")),this.end$=this.events$.pipe(e.filter(n=>n.type==="panEnd"))}update(t){super.update(t,t.options)}}const Q=i=>p=>p.pipe(e.filter(t=>Math.abs(t.velocityX)>=i||Math.abs(t.velocityY)>=i));class Z extends E{constructor(t){super(t,{posThreshold:0,numInputs:1});h(this,"events$");this.events$=this.config$.pipe(e.switchMap(o=>{const{escapeVelocity:n=.9}=o.options??{},r=this.panEvent$.pipe(e.filter(a=>a.type==="panStart")),l=this.panEvent$.pipe(e.filter(a=>a.type==="panEnd"));return r.pipe(e.switchMap(a=>l.pipe(Q(n),e.map(({type:s,...c})=>({type:"swipe",angle:V(a.event,c.event),...c})))),e.share())}))}update(t){super.update(t)}}const x=({timeout:i,pointerEvent$:p})=>t=>t.pipe(e.mergeMap(o=>e.timer(i).pipe(e.takeUntil(p.pipe(X,T(o)))))),j=({initialPointerEvent:i,pointerEvent$:p,tolerance:t})=>o=>o.pipe(e.mergeMap(n=>p.pipe(T(n),e.takeWhile(r=>!C(r),!0),e.filter(r=>k(i,r,t)))));class ee extends E{constructor(t){super(t);h(this,"events$");this.events$=this.config$.pipe(e.switchMap(o=>{const{multiTapThreshold:n=0,maximumPressTime:r=150,maxTaps:l=1,tolerance:a=10}=o.options??{},s=this.pointerDown$.pipe(O({pointerEvent$:this.pointerEvent$,trackMove:!0}),e.shareReplay(1)),c=s.pipe(e.filter(({pointers:d})=>d.length>1)),g=d=>d.pipe(e.buffer(this.pointerUp$.pipe(e.debounceTime(n))),e.first());return e.merge(this.pointerDown$,s.pipe(e.ignoreElements())).pipe(e.exhaustMap(d=>{const f=e.merge(e.of(d),this.pointerDown$).pipe(e.shareReplay(1)),m=f.pipe(g),v=f.pipe(j({initialPointerEvent:d,pointerEvent$:this.pointerEvent$,tolerance:a})),D=f.pipe(x({pointerEvent$:this.pointerEvent$,timeout:r})),Y=e.merge(this.failWith$,this.pointerCancel$,c,v,D),A=m.pipe(W,e.filter(y=>y.length<=l),e.map(y=>({type:"tap",taps:y.length,latestActivePointers:y,event:y[0]})),e.shareReplay(1));return A.pipe(L,e.withLatestFrom(A),e.map(([y,{type:z,taps:b}])=>({...y,type:z,taps:b})),e.takeUntil(Y))}))}),e.share())}update(t){super.update(t)}}class te extends E{constructor(t={}){super(t,{numInputs:2,posThreshold:15,...t.options});h(this,"events$");this.events$=this.config$.pipe(e.switchMap(()=>{const o=this.panEvent$.pipe(e.filter(a=>a.type==="panStart"),e.map(a=>({...a,type:"rotateStart",angle:0,deltaAngle:0})),e.shareReplay(1)),n=o.pipe(e.switchMap(()=>this.panEvent$.pipe(e.scan((a,s)=>{const c=((a==null?void 0:a.angle)??0)+s.deltaPointersAngle;return{...a,...s,angle:c,deltaAngle:s.deltaPointersAngle}},void 0))),e.share()),r=n.pipe(e.filter(a=>a.type==="panMove"),e.map(a=>({...a,type:"rotateMove"}))),l=n.pipe(e.filter(a=>a.type==="panEnd"),e.map(a=>({...a,type:"rotateEnd"})));return e.merge(o,r,l)}),e.share())}update(t){super.update(t,t.options)}}const I=({type:i,initialEvent:p})=>t=>t.pipe(e.scan((o,n)=>{const l=((o==null?void 0:o.pointers.length)??0)!==n.pointers.length,a=(o==null?void 0:o.pointersAverageDistance)??n.pointersAverageDistance,s=l?n.pointersAverageDistance:o&&"initialPointersAverageDistance"in o?o.initialPointersAverageDistance:n.pointersAverageDistance,c=s===0?1:n.pointersAverageDistance/s,g=n.pointersAverageDistance-s,w=n.pointersAverageDistance-s,d=l||a===0?1:n.pointersAverageDistance/a;return{...o,...n,type:i,initialPointersAverageDistance:s,scale:c,distance:g,deltaDistance:w,deltaDistanceScale:d}},p),e.map(({initialPointersAverageDistance:o,...n})=>n));class ne extends E{constructor(t){super(t,{...t==null?void 0:t.options,numInputs:2});h(this,"events$");this.events$=this.config$.pipe(e.switchMap(()=>{const o=this.panEvent$.pipe(e.filter(l=>l.type==="panStart"),e.switchMap(l=>e.of(l).pipe(I({type:"pinchStart",initialEvent:void 0}))),e.shareReplay(1)),n=o.pipe(e.switchMap(l=>this.panEvent$.pipe(e.takeWhile(a=>a.type!=="panEnd"),I({type:"pinchMove",initialEvent:l})))),r=o.pipe(e.switchMap(l=>this.panEvent$.pipe(e.startWith(l),e.pairwise(),e.filter(([a,s])=>s.type==="panEnd"),e.switchMap(([a,s])=>e.of(s).pipe(I({type:"pinchEnd",initialEvent:a}))))));return e.merge(o,n,r)}),e.share())}update(t){super.update(t,t.options)}}class ie{constructor(p){h(this,"events$");h(this,"recognizers");h(this,"state$");this.options=p,this.recognizers=p.recognizers,this.events$=e.merge(...p.recognizers.map(t=>t.events$)).pipe(e.share()),this.state$=e.combineLatest(this.recognizers.map(t=>t.state$)).pipe(e.map(t=>t.reduce((o,n)=>({fingers:Math.max(o.fingers,n.fingers)}))))}initialize(p){p.style.touchAction="none",p.style.userSelect="none",this.options.recognizers.forEach(t=>{console.log("recognizable update"),t.update({container:p,afterEventReceived:this.options.afterEventReceived})})}}u.PanRecognizer=K,u.PinchRecognizer=ne,u.Recognizable=ie,u.Recognizer=E,u.RotateRecognizer=te,u.SwipeRecognizer=Z,u.TapRecognizer=ee,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(u,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("rxjs")):typeof define=="function"&&define.amd?define(["exports","rxjs"],e):(u=typeof globalThis<"u"?globalThis:u||self,e(u.gesturx={},u.rxjs))})(this,function(u,e){"use strict";var pe=Object.defineProperty;var oe=(u,e,P)=>e in u?pe(u,e,{enumerable:!0,configurable:!0,writable:!0,value:P}):u[e]=P;var h=(u,e,P)=>(oe(u,typeof e!="symbol"?e+"":e,P),P);function P(i,p){return Math.sqrt(Math.pow(p.x-i.x,2)+Math.pow(p.y-i.y,2))}function N(i){const p=i.length;if(p<2)return 0;const t=i.reduce((n,r,l)=>n+i.slice(l+1).reduce((a,s)=>a+P(r,s),0),0),o=p*(p-1)/2;return t/o}function S(i,p){const t=p.x-i.x,o=p.y-i.y;return Math.atan2(o,t)}function V(i,p){return S(i,p)*(180/Math.PI)}function R(i){const p=i.reduce((o,n)=>(o.x+=n.x,o.y+=n.y,o),{x:0,y:0}),t=i.length||1;return{x:p.x/t,y:p.y/t}}function B(i,p){if(i.length!==p.length)throw new Error("Initial and new points arrays must have the same length.");const t=R(i),o=R(p);let n=0;for(let a=0;a<i.length;a++){const s=S(t,i[a]);let g=S(o,p[a])-s;g>Math.PI?g-=2*Math.PI:g<-Math.PI&&(g+=2*Math.PI),n+=g}const r=n/i.length,l=r*(180/Math.PI);return{radianDelta:r,degreesDelta:l}}function q(i){return i!=null}const _=i=>i.length>0,W=i=>i.pipe(e.filter(_));function k(i,p,t){const o=R([i]),n=R([p]);return Math.abs(n.x-o.x)>=t||Math.abs(n.y-o.y)>=t}const G=(i,p,t)=>{const o=i>0?p/i:0,n=i>0?t/i:0;return{velocityX:o,velocityY:n}};function T(i){return p=>p.pipe(e.filter(t=>t.pointerId===i.pointerId))}const C=i=>i.type==="pointerleave"||i.type==="pointercancel"||i.type==="pointerup",H=({container:i,afterEventReceived:p=t=>t})=>e.fromEvent(i,"pointerdown").pipe(e.map(p)),O=({pointerEvent$:i})=>p=>{const t=i.pipe(e.filter(a=>a.type==="pointerup")),o=i.pipe(e.filter(a=>a.type==="pointerleave")),n=i.pipe(e.filter(a=>a.type==="pointercancel")),r=i.pipe(e.filter(a=>a.type==="pointermove")),l=a=>["pointercancel","pointerleave","pointerup"].includes(a.type);return p.pipe(e.mergeMap(a=>{const s=e.defer(()=>e.of(a));return e.merge(s,e.merge(r,n,o,t)).pipe(T(a),e.takeWhile(g=>!l(g),!0))}),e.scan((a,s)=>{if(l(s)){const{[s.pointerId]:c,...g}=(a==null?void 0:a.pointers)??{};return{event:s,pointers:g}}return{event:s,pointers:{...(a==null?void 0:a.pointers)??{},[s.pointerId]:s}}},void 0),e.map(({event:a,pointers:s})=>({event:a,pointers:Object.values(s).filter(q)})))},F=(i,p,t,o)=>{const n=i.x-p.x+t,r=i.y-p.y+o;return{deltaX:n,deltaY:r}},L=i=>{const p=t=>R(t.latestActivePointers.length?t.latestActivePointers:[t.event]);return i.pipe(e.scan((t,o)=>{var v,E;const n=p(o),r=(t==null?void 0:t.center)??n,l=(t==null?void 0:t.deltaX)??0,a=(t==null?void 0:t.deltaY)??0,s=((v=t==null?void 0:t.latestActivePointers)==null?void 0:v.length)??1,c=((E=o.latestActivePointers)==null?void 0:E.length)??1,g=["pointerdown","pointercancel","pointerleave","pointerup"].includes(o.event.type)&&s!==c,w=c>0,{deltaX:d,deltaY:f}=g&&w?F(n,n,l,a):F(n,r,l,a),{degreesDelta:m}=s===c&&s>=2&&c>=2?B((t==null?void 0:t.latestActivePointers)??[],o.latestActivePointers??[]):{degreesDelta:0};return{startTime:new Date().getTime(),...t,...o,center:n,deltaX:d,deltaY:f,deltaPointersAngle:m}},void 0),e.map(t=>{const{deltaX:o,deltaY:n,latestActivePointers:r,startTime:l,center:a,event:s,deltaPointersAngle:c}=t,g=r??[],d=Date.now()-l,{velocityX:f,velocityY:m}=G(d,o,n),v=N(r);return{deltaX:o,deltaY:n,velocityX:f,velocityY:m,delay:d,center:a,pointers:g,startTime:l,event:s,deltaPointersAngle:c,pointersAverageDistance:v}}))},U=i=>i.pipe(e.filter(p=>!!p.container)),X=i=>i.pipe(e.filter(C)),J=({container:i,afterEventReceived:p=t=>t})=>{const t=H({afterEventReceived:p,container:i}),o=e.fromEvent(i,"pointerup").pipe(e.map(p)),n=e.fromEvent(i,"pointermove").pipe(e.map(p)),r=e.fromEvent(i,"pointerleave").pipe(e.map(p)),l=e.fromEvent(i,"pointercancel").pipe(e.map(p));return e.merge(t,l,r,o,n)};class D{constructor(p,t){h(this,"configSubject",new e.BehaviorSubject({}));h(this,"panEvent$");h(this,"pointerEvent$");h(this,"pointerDown$");h(this,"pointerUp$");h(this,"pointerCancel$");h(this,"pointerMove$");h(this,"pointerOff$");h(this,"state$");h(this,"failWith$");h(this,"config$",this.configSubject.pipe(U));const o=new e.BehaviorSubject({fingers:0});this.pointerEvent$=this.config$.pipe(e.switchMap(({container:n,afterEventReceived:r})=>J({container:n,afterEventReceived:r}))),this.pointerDown$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointerdown")),this.pointerUp$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointerup")),this.pointerMove$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointermove")),this.pointerCancel$=this.pointerEvent$.pipe(e.filter(n=>n.type==="pointercancel")),this.pointerOff$=this.pointerEvent$.pipe(X),this.failWith$=this.config$.pipe(e.switchMap(({failWith:n})=>n!=null&&n.length?e.merge(...(n==null?void 0:n.map(({start$:r})=>r))??[]):e.NEVER)),this.panEvent$=this.configSubject.pipe(U,e.switchMap(n=>{var w,d,f;const r=Math.max(1,((w=n.panConfig)==null?void 0:w.numInputs)??1),l=Math.max(0,((d=n.panConfig)==null?void 0:d.posThreshold)??0),a=Math.max(0,((f=n.panConfig)==null?void 0:f.delay)??0),s=this.pointerDown$.pipe(O({pointerEvent$:this.pointerEvent$,trackMove:!0}),e.shareReplay(1)),c=m=>m.pipe(e.filter(v=>v.pointers.length>=r)),g=m=>m.pipe(e.filter(v=>v.pointers.length<r));return s.pipe(c,e.exhaustMap(({pointers:m})=>{const v=s.pipe(g,e.first(),e.share()),E=e.timer(a),A=e.merge(...m.map($=>e.of($)),this.pointerDown$).pipe(e.mergeMap($=>e.merge(this.pointerMove$,e.of($)).pipe(T($),e.filter(M=>k($,M,l)))),e.first()).pipe(e.switchMap(()=>E),e.withLatestFrom(s),e.map(([,{event:$,pointers:M}])=>({type:"panStart",event:$,latestActivePointers:M})),e.shareReplay({bufferSize:1,refCount:!1}),e.takeUntil(v)),y=A.pipe(e.mergeMap(()=>s.pipe(e.skip(1),e.map(({event:$,pointers:M})=>({type:"panMove",event:$,latestActivePointers:M})))),e.takeUntil(v)),z=A.pipe(e.mergeMap(()=>v.pipe(e.map(({event:$,pointers:M})=>({type:"panEnd",event:$,latestActivePointers:M}))))),b=e.merge(A,y,z).pipe(e.shareReplay(1));return b.pipe(L,e.withLatestFrom(b),e.map(([$,{type:M}])=>({...$,type:M})))}))}),e.tap(n=>{o.next({fingers:n.pointers.length})}),e.share()),this.state$=o.asObservable(),this.updateInternal(p??{},t)}updateInternal(p,t){const o=this.configSubject.getValue();this.configSubject.next({...o,...p,...p.options&&{options:{...o.options,...p.options}},panConfig:{...o.panConfig,...t}})}update(p,t){this.updateInternal(p,t)}}class K extends D{constructor(t){var o;super(t,{...t,posThreshold:((o=t==null?void 0:t.options)==null?void 0:o.posThreshold)??15});h(this,"events$");h(this,"start$");h(this,"end$");this.events$=this.panEvent$,this.start$=this.panEvent$.pipe(e.filter(n=>n.type==="panStart")),this.end$=this.events$.pipe(e.filter(n=>n.type==="panEnd"))}update(t){super.update(t,t.options)}}const Q=i=>p=>p.pipe(e.filter(t=>Math.abs(t.velocityX)>=i||Math.abs(t.velocityY)>=i));class Z extends D{constructor(t){super(t,{posThreshold:0,numInputs:1});h(this,"events$");this.events$=this.config$.pipe(e.switchMap(o=>{const{escapeVelocity:n=.9}=o.options??{},r=this.panEvent$.pipe(e.filter(a=>a.type==="panStart")),l=this.panEvent$.pipe(e.filter(a=>a.type==="panEnd"));return r.pipe(e.switchMap(a=>l.pipe(Q(n),e.map(({type:s,...c})=>({type:"swipe",angle:V(a.event,c.event),...c})))),e.share())}))}update(t){super.update(t)}}const x=({timeout:i,pointerEvent$:p})=>t=>t.pipe(e.mergeMap(o=>e.timer(i).pipe(e.takeUntil(p.pipe(X,T(o)))))),j=({initialPointerEvent:i,pointerEvent$:p,tolerance:t})=>o=>o.pipe(e.mergeMap(n=>p.pipe(T(n),e.takeWhile(r=>!C(r),!0),e.filter(r=>k(i,r,t)))));class ee extends D{constructor(t){super(t);h(this,"events$");this.events$=this.config$.pipe(e.switchMap(o=>{const{multiTapThreshold:n=0,maximumPressTime:r=150,maxTaps:l=1,tolerance:a=10}=o.options??{},s=this.pointerDown$.pipe(O({pointerEvent$:this.pointerEvent$,trackMove:!0}),e.shareReplay(1)),c=s.pipe(e.filter(({pointers:d})=>d.length>1)),g=d=>d.pipe(e.buffer(this.pointerUp$.pipe(e.debounceTime(n))),e.first());return e.merge(this.pointerDown$,s.pipe(e.ignoreElements())).pipe(e.exhaustMap(d=>{const f=e.merge(e.of(d),this.pointerDown$).pipe(e.shareReplay(1)),m=f.pipe(g),v=f.pipe(j({initialPointerEvent:d,pointerEvent$:this.pointerEvent$,tolerance:a})),E=f.pipe(x({pointerEvent$:this.pointerEvent$,timeout:r})),Y=e.merge(this.failWith$,this.pointerCancel$,c,v,E),A=m.pipe(W,e.filter(y=>y.length<=l),e.map(y=>({type:"tap",taps:y.length,latestActivePointers:y,event:y[0]})),e.shareReplay(1));return A.pipe(L,e.withLatestFrom(A),e.map(([y,{type:z,taps:b}])=>({...y,type:z,taps:b})),e.takeUntil(Y))}))}),e.share())}update(t){super.update(t)}}class te extends D{constructor(t={}){super(t,{numInputs:2,posThreshold:15,...t.options});h(this,"events$");this.events$=this.config$.pipe(e.switchMap(()=>{const o=this.panEvent$.pipe(e.filter(a=>a.type==="panStart"),e.map(a=>({...a,type:"rotateStart",angle:0,deltaAngle:0})),e.shareReplay(1)),n=o.pipe(e.switchMap(()=>this.panEvent$.pipe(e.scan((a,s)=>{const c=((a==null?void 0:a.angle)??0)+s.deltaPointersAngle;return{...a,...s,angle:c,deltaAngle:s.deltaPointersAngle}},void 0))),e.share()),r=n.pipe(e.filter(a=>a.type==="panMove"),e.map(a=>({...a,type:"rotateMove"}))),l=n.pipe(e.filter(a=>a.type==="panEnd"),e.map(a=>({...a,type:"rotateEnd"})));return e.merge(o,r,l)}),e.share())}update(t){super.update(t,t.options)}}const I=({type:i,initialEvent:p})=>t=>t.pipe(e.scan((o,n)=>{const l=((o==null?void 0:o.pointers.length)??0)!==n.pointers.length,a=(o==null?void 0:o.pointersAverageDistance)??n.pointersAverageDistance,s=l?n.pointersAverageDistance:o&&"initialPointersAverageDistance"in o?o.initialPointersAverageDistance:n.pointersAverageDistance,c=s===0?1:n.pointersAverageDistance/s,g=n.pointersAverageDistance-s,w=n.pointersAverageDistance-s,d=l||a===0?1:n.pointersAverageDistance/a;return{...o,...n,type:i,initialPointersAverageDistance:s,scale:c,distance:g,deltaDistance:w,deltaDistanceScale:d}},p),e.map(({initialPointersAverageDistance:o,...n})=>n));class ne extends D{constructor(t){super(t,{...t==null?void 0:t.options,numInputs:2});h(this,"events$");this.events$=this.config$.pipe(e.switchMap(()=>{const o=this.panEvent$.pipe(e.filter(l=>l.type==="panStart"),e.switchMap(l=>e.of(l).pipe(I({type:"pinchStart",initialEvent:void 0}))),e.shareReplay(1)),n=o.pipe(e.switchMap(l=>this.panEvent$.pipe(e.takeWhile(a=>a.type!=="panEnd"),I({type:"pinchMove",initialEvent:l})))),r=o.pipe(e.switchMap(l=>this.panEvent$.pipe(e.startWith(l),e.pairwise(),e.filter(([a,s])=>s.type==="panEnd"),e.switchMap(([a,s])=>e.of(s).pipe(I({type:"pinchEnd",initialEvent:a}))))));return e.merge(o,n,r)}),e.share())}update(t){super.update(t,t.options)}}class ie{constructor(p){h(this,"events$");h(this,"recognizers");h(this,"state$");this.options=p,this.recognizers=p.recognizers,this.events$=e.merge(...p.recognizers.map(t=>t.events$)).pipe(e.share()),this.state$=e.combineLatest(this.recognizers.map(t=>t.state$)).pipe(e.map(t=>t.reduce((o,n)=>({fingers:Math.max(o.fingers,n.fingers)}))))}update(p){p.container&&(p.container.style.touchAction="none",p.container.style.userSelect="none"),this.options.recognizers.forEach(t=>{t.update(p)})}}u.PanRecognizer=K,u.PinchRecognizer=ne,u.Recognizable=ie,u.Recognizer=D,u.RotateRecognizer=te,u.SwipeRecognizer=Z,u.TapRecognizer=ee,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
|
|
2
2
|
//# sourceMappingURL=index.umd.cjs.map
|
package/dist/index.umd.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.cjs","sources":["../src/core/utils/geometry.ts","../src/core/utils/utils.ts","../src/core/utils/events.ts","../src/core/recognizer/scanToRecognizerEvent.ts","../src/core/recognizer/operators.ts","../src/core/recognizer/utils.ts","../src/core/recognizer/Recognizer.ts","../src/core/pan/PanRecognizer.ts","../src/core/swipe/operators.ts","../src/core/swipe/SwipeRecognizer.ts","../src/core/tap/operators.ts","../src/core/tap/TapRecognizer.ts","../src/core/rotate/RotateRecognizer.ts","../src/core/pinch/mapPanEventToPinchEvent.ts","../src/core/pinch/PinchRecognizer.ts","../src/core/recognizable/Recognizable.ts"],"sourcesContent":["type Point = { x: number; y: number }\n\nexport function calculateDistance(pointA: Point, pointB: Point): number {\n return Math.sqrt(\n Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2),\n )\n}\n\nexport function calculateAverageDistance(pointerEvents: Point[]): number {\n const n = pointerEvents.length\n if (n < 2) return 0 // No distance if fewer than 2 pointers\n\n const totalDistance = pointerEvents.reduce((sum, event1, i) => {\n return (\n sum +\n pointerEvents.slice(i + 1).reduce((innerSum, event2) => {\n return innerSum + calculateDistance(event1, event2)\n }, 0)\n )\n }, 0)\n\n // Number of pairs is n choose 2: n * (n - 1) / 2\n const numberOfPairs = (n * (n - 1)) / 2\n return totalDistance / numberOfPairs\n}\n\nexport function calculateRadianAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the differences in coordinates\n const deltaX = pointerB.x - pointerA.x\n const deltaY = pointerB.y - pointerA.y\n\n // Calculate the angle in radians\n const angleInRadians = Math.atan2(deltaY, deltaX)\n\n // Return the angle in degrees\n return angleInRadians\n}\n\nexport function calculateDegreeAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the angle in radians\n const angleInRadians = calculateRadianAngleBetweenPoints(pointerA, pointerB)\n\n // Convert the angle to degrees (optional)\n const angleInDegrees = angleInRadians * (180 / Math.PI)\n\n // Return the angle in degrees\n return angleInDegrees\n}\n\nexport function calculateCentroid(points: Point[]) {\n const sum = points.reduce(\n (acc, point) => {\n acc.x += point.x\n acc.y += point.y\n\n return acc\n },\n { x: 0, y: 0 },\n )\n\n const numPoints = points.length || 1\n\n return {\n x: sum.x / numPoints,\n y: sum.y / numPoints,\n }\n}\n\nexport function calculateAngleDelta(\n initialPoints: Point[],\n newPoints: Point[],\n) {\n if (initialPoints.length !== newPoints.length) {\n throw new Error(\"Initial and new points arrays must have the same length.\")\n }\n\n const initialCentroid = calculateCentroid(initialPoints)\n const newCentroid = calculateCentroid(newPoints)\n\n let totalAngleDelta = 0\n\n for (let i = 0; i < initialPoints.length; i++) {\n const initialAngle = calculateRadianAngleBetweenPoints(\n initialCentroid,\n initialPoints[i]!,\n )\n const newAngle = calculateRadianAngleBetweenPoints(\n newCentroid,\n newPoints[i]!,\n )\n\n let angleDelta = newAngle - initialAngle\n\n // Normalize the angle delta to be within [-PI, PI]\n if (angleDelta > Math.PI) {\n angleDelta -= 2 * Math.PI\n } else if (angleDelta < -Math.PI) {\n angleDelta += 2 * Math.PI\n }\n\n totalAngleDelta += angleDelta\n }\n\n // Return the average angle delta\n const radianDelta = totalAngleDelta / initialPoints.length\n const degreesDelta = radianDelta * (180 / Math.PI)\n\n return { radianDelta, degreesDelta }\n}\n","import {\n Observable,\n filter,\n} from \"rxjs\"\nimport { calculateCentroid } from \"./geometry\"\n\nexport function isDefined<T>(\n arg: T | null | undefined,\n): arg is T extends null | undefined ? never : T {\n return arg !== null && arg !== undefined\n}\n\nexport const hasAtLeastOneItem = <T>(events: T[]): events is [T, ...T[]] =>\n events.length > 0\n\nexport const filterNotEmpty = <T>(\n stream: Observable<T[]>,\n): Observable<[T, ...T[]]> => stream.pipe(filter(hasAtLeastOneItem))\n\nexport function isWithinPosThreshold(\n startEvent: PointerEvent,\n endEvent: PointerEvent,\n posThreshold: number,\n) {\n const start = calculateCentroid([startEvent])\n const end = calculateCentroid([endEvent])\n\n // Determines if the movement qualifies as a drag\n return (\n Math.abs(end.x - start.x) >= posThreshold ||\n Math.abs(end.y - start.y) >= posThreshold\n )\n}\n\n/**\n * Avoid division by zero\n * Calculate velocity in pixels per second\n */\nexport const calculateVelocity = (\n delay: number,\n deltaX: number,\n deltaY: number,\n) => {\n const velocityX = delay > 0 ? deltaX / delay : 0\n const velocityY = delay > 0 ? deltaY / delay : 0\n\n return {\n velocityX,\n velocityY,\n }\n}\n","import {\n Observable,\n defer,\n filter,\n fromEvent,\n map,\n merge,\n mergeMap,\n of,\n scan,\n takeWhile,\n} from \"rxjs\"\nimport { isDefined } from \"./utils\"\n\nexport function matchPointer(pointer: PointerEvent) {\n return (stream: Observable<PointerEvent>) =>\n stream.pipe(\n filter((newPointer) => newPointer.pointerId === pointer.pointerId),\n )\n}\n\nexport const isPointerOffEvent = (pointerEvent: PointerEvent) =>\n pointerEvent.type === \"pointerleave\" ||\n pointerEvent.type === \"pointercancel\" ||\n pointerEvent.type === \"pointerup\"\n\nexport const fromPointerDown = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) =>\n fromEvent<PointerEvent>(container, \"pointerdown\").pipe(\n map(afterEventReceived),\n )\n\n/**\n * Track all pointerEvent for active fingers\n */\nexport const trackPointers =\n ({\n pointerEvent$,\n }: {\n pointerEvent$: Observable<PointerEvent>\n /**\n * Setting this value to false will not update the list\n * on pointer move. Use it if you only need to track number of active\n * fingers.\n */\n trackMove: boolean\n }) =>\n (stream: Observable<PointerEvent>) => {\n type PointersState = {\n event: PointerEvent\n pointers: Record<number, PointerEvent | undefined>\n }\n\n const pointerUp$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n const pointerLeave$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerleave\"),\n )\n const pointerCancel$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n const pointerMove$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n const isPointerRemoved = (event: PointerEvent) =>\n [\"pointercancel\", \"pointerleave\", \"pointerup\"].includes(event.type)\n\n return stream.pipe(\n mergeMap((pointerDown) => {\n const pointerDown$ = defer(() => of(pointerDown))\n\n const tracking$ = merge(\n pointerDown$,\n merge(pointerMove$, pointerCancel$, pointerLeave$, pointerUp$),\n ).pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerRemoved(event), true),\n )\n\n return tracking$\n }),\n scan<PointerEvent, PointersState, undefined>((acc, event) => {\n if (isPointerRemoved(event)) {\n const { [event.pointerId]: _deleted, ...rest } = acc?.pointers ?? {}\n\n return {\n event,\n pointers: rest,\n }\n }\n\n return {\n event,\n pointers: {\n ...(acc?.pointers ?? {}),\n [event.pointerId]: event,\n },\n }\n }, undefined),\n map(({ event, pointers }) => ({\n event,\n pointers: Object.values(pointers).filter(isDefined),\n })),\n )\n }\n","import { Observable, map, scan } from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { calculateVelocity } from \"../utils/utils\"\nimport {\n calculateAngleDelta,\n calculateAverageDistance,\n calculateCentroid,\n} from \"../utils/geometry\"\n\nexport interface RecognizerEventInput {\n event: PointerEvent\n latestActivePointers: PointerEvent[]\n}\n\ninterface RecognizerEventState extends RecognizerEventInput {\n startTime: number\n center: { x: number; y: number }\n deltaX: number\n deltaY: number\n deltaPointersAngle: number\n}\n\nconst calculateNewDelta = (\n newCenter: { x: number; y: number },\n prevCenter: { x: number; y: number },\n prevDeltaX: number,\n prevDeltaY: number,\n) => {\n const deltaX = newCenter.x - prevCenter.x + prevDeltaX\n const deltaY = newCenter.y - prevCenter.y + prevDeltaY\n\n return {\n deltaX,\n deltaY,\n }\n}\n\nexport const scanToRecognizerEvent = <T extends RecognizerEventInput>(\n stream: Observable<T>,\n): Observable<RecognizerEvent> => {\n const getCenterFromData = (data: T) =>\n calculateCentroid(\n !data.latestActivePointers.length\n ? [data.event]\n : data.latestActivePointers,\n )\n\n return stream.pipe(\n scan<T, RecognizerEventState, undefined>((acc, curr) => {\n const newCenter = getCenterFromData(curr)\n const prevCenter = acc?.center ?? newCenter\n const prevDeltaX = acc?.deltaX ?? 0\n const prevDeltaY = acc?.deltaY ?? 0\n const prevActivePointersNumber = acc?.latestActivePointers?.length ?? 1\n const currActivePointersNumber = curr.latestActivePointers?.length ?? 1\n\n const hasAddedOrRemovedAFinger =\n [\"pointerdown\", \"pointercancel\", \"pointerleave\", \"pointerup\"].includes(\n curr.event.type,\n ) && prevActivePointersNumber !== currActivePointersNumber\n\n const hasAtLeastOneFinger = currActivePointersNumber > 0\n\n const { deltaX, deltaY } =\n hasAddedOrRemovedAFinger && hasAtLeastOneFinger\n ? calculateNewDelta(newCenter, newCenter, prevDeltaX, prevDeltaY)\n : calculateNewDelta(newCenter, prevCenter, prevDeltaX, prevDeltaY)\n\n const { degreesDelta: deltaPointersAngle } =\n prevActivePointersNumber === currActivePointersNumber &&\n prevActivePointersNumber >= 2 &&\n currActivePointersNumber >= 2\n ? calculateAngleDelta(\n acc?.latestActivePointers ?? [],\n curr.latestActivePointers ?? [],\n )\n : { degreesDelta: 0 }\n\n return {\n startTime: new Date().getTime(),\n ...acc,\n ...curr,\n center: newCenter,\n deltaX,\n deltaY,\n deltaPointersAngle,\n }\n }, undefined),\n map((data) => {\n const {\n deltaX,\n deltaY,\n latestActivePointers,\n startTime,\n center,\n event,\n deltaPointersAngle,\n } = data\n const events = latestActivePointers ?? []\n\n // Calculate the change in time\n const now = Date.now()\n const delay = now - startTime\n\n const { velocityX, velocityY } = calculateVelocity(delay, deltaX, deltaY)\n const pointersAverageDistance =\n calculateAverageDistance(latestActivePointers)\n\n return {\n deltaX,\n deltaY,\n velocityX,\n velocityY,\n delay,\n center,\n pointers: events,\n startTime,\n event,\n deltaPointersAngle,\n pointersAverageDistance,\n } satisfies RecognizerEvent\n }),\n )\n}\n","import { Observable, filter } from \"rxjs\"\nimport { isPointerOffEvent } from \"../utils/events\"\n\nexport const isValidConfig = <T extends { container?: HTMLElement }>(\n stream: Observable<T>,\n) =>\n stream.pipe(\n filter(\n (config): config is T & { container: HTMLElement } => !!config.container,\n ),\n )\n\nexport const filterPointerOff = (stream: Observable<PointerEvent>) =>\n stream.pipe(filter(isPointerOffEvent))\n","import { fromEvent, map, merge } from \"rxjs\"\nimport { fromPointerDown } from \"../utils/events\"\n\nexport const getPointerEvents = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) => {\n const pointerDown$ = fromPointerDown({ afterEventReceived, container })\n const pointerUp$ = fromEvent<PointerEvent>(container, \"pointerup\").pipe(\n map(afterEventReceived),\n )\n const pointerMove$ = fromEvent<PointerEvent>(container, \"pointermove\").pipe(\n map(afterEventReceived),\n )\n /**\n * Mostly used to handle cursor leaving window on mouse pointers.\n */\n const pointerLeave$ = fromEvent<PointerEvent>(container, \"pointerleave\").pipe(\n map(afterEventReceived),\n )\n /**\n * Handle things such as contextual menu popup or\n * native swipe navigation conflict.\n */\n const pointerCancel$ = fromEvent<PointerEvent>(\n container,\n \"pointercancel\",\n ).pipe(map(afterEventReceived))\n\n return merge(\n pointerDown$,\n pointerCancel$,\n pointerLeave$,\n pointerUp$,\n pointerMove$,\n )\n}\n","import {\n BehaviorSubject,\n NEVER,\n Observable,\n exhaustMap,\n filter,\n first,\n map,\n merge,\n mergeMap,\n of,\n share,\n shareReplay,\n skip,\n switchMap,\n takeUntil,\n tap,\n timer,\n withLatestFrom,\n} from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { trackPointers, matchPointer } from \"../utils/events\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"./scanToRecognizerEvent\"\nimport { filterPointerOff, isValidConfig } from \"./operators\"\nimport { getPointerEvents } from \"./utils\"\n\ntype PanConfig = {\n posThreshold?: number\n delay?: number\n /**\n * Number of inputs to trigger the event.\n * Default to 1\n */\n numInputs?: number\n}\n\nexport type RecognizerConfig<Options> = {\n container?: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n options?: Options\n failWith?: { start$: Observable<unknown> }[]\n}\n\nexport interface PanEvent extends RecognizerEvent {\n type: \"panStart\" | \"panMove\" | \"panEnd\"\n}\n\nexport type State = {\n fingers: number\n}\n\nexport abstract class Recognizer<\n Options extends Record<any, any>,\n Event extends RecognizerEvent,\n> {\n protected configSubject = new BehaviorSubject<\n RecognizerConfig<Options> & {\n panConfig?: PanConfig\n }\n >({})\n protected panEvent$: Observable<PanEvent>\n protected pointerEvent$: Observable<PointerEvent>\n protected pointerDown$: Observable<PointerEvent>\n protected pointerUp$: Observable<PointerEvent>\n protected pointerCancel$: Observable<PointerEvent>\n protected pointerMove$: Observable<PointerEvent>\n protected pointerOff$: Observable<PointerEvent>\n\n public state$: Observable<State>\n\n abstract events$: Observable<Event>\n\n protected failWith$: Observable<unknown>\n\n protected config$ = this.configSubject.pipe(isValidConfig)\n\n constructor(config?: RecognizerConfig<Options>, panConfig?: PanConfig) {\n const stateSubject = new BehaviorSubject<State>({\n fingers: 0,\n })\n\n this.pointerEvent$ = this.config$.pipe(\n switchMap(({ container, afterEventReceived }) =>\n getPointerEvents({\n container,\n afterEventReceived,\n }),\n ),\n )\n\n this.pointerDown$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerdown\"),\n )\n\n this.pointerUp$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n\n this.pointerMove$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n this.pointerCancel$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n\n this.pointerOff$ = this.pointerEvent$.pipe(filterPointerOff)\n\n this.failWith$ = this.config$.pipe(\n switchMap(({ failWith }) =>\n !failWith?.length\n ? NEVER\n : merge(...(failWith?.map(({ start$ }) => start$) ?? [])),\n ),\n )\n\n this.panEvent$ = this.configSubject.pipe(\n isValidConfig,\n switchMap((config) => {\n const numInputs = Math.max(1, config.panConfig?.numInputs ?? 1)\n const posThreshold = Math.max(0, config.panConfig?.posThreshold ?? 0)\n const delay = Math.max(0, config.panConfig?.delay ?? 0)\n\n const trackPointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasEnoughFingers = (\n stream: Observable<{ event: PointerEvent; pointers: PointerEvent[] }>,\n ) =>\n stream.pipe(\n filter(\n (\n events,\n ): events is { event: PointerEvent; pointers: [PointerEvent] } =>\n events.pointers.length >= numInputs,\n ),\n )\n\n const hasNotEnoughFingers = (\n stream: Observable<{\n event: PointerEvent\n pointers: PointerEvent[]\n }>,\n ) => stream.pipe(filter((events) => events.pointers.length < numInputs))\n\n return trackPointers$.pipe(\n hasEnoughFingers,\n exhaustMap(({ pointers: initialPointerEvents }) => {\n const panReleased$ = trackPointers$.pipe(\n hasNotEnoughFingers,\n first(),\n share(),\n )\n\n const delay$ = timer(delay)\n\n const pointerDownPassingThreshold$ = merge(\n ...initialPointerEvents.map((pointerEvent) => of(pointerEvent)),\n this.pointerDown$,\n ).pipe(\n mergeMap((pointerDown) =>\n merge(this.pointerMove$, of(pointerDown)).pipe(\n matchPointer(pointerDown),\n filter((pointerEvent) =>\n isWithinPosThreshold(\n pointerDown,\n pointerEvent,\n posThreshold,\n ),\n ),\n ),\n ),\n first(),\n )\n\n const panStart$ = pointerDownPassingThreshold$.pipe(\n switchMap(() => delay$),\n withLatestFrom(trackPointers$),\n map(([, { event, pointers }]) => ({\n type: \"panStart\" as const,\n event,\n latestActivePointers: pointers,\n })),\n shareReplay({\n bufferSize: 1,\n refCount: false,\n }),\n takeUntil(panReleased$),\n )\n\n const panUpdate$ = panStart$.pipe(\n mergeMap(() =>\n trackPointers$.pipe(\n skip(1),\n map(({ event, pointers }) => ({\n type: \"panMove\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n takeUntil(panReleased$),\n )\n\n const panEnd$ = panStart$.pipe(\n mergeMap(() =>\n panReleased$.pipe(\n map(({ event, pointers }) => ({\n type: \"panEnd\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n )\n\n const rawEvent$ = merge(panStart$, panUpdate$, panEnd$).pipe(\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type }]) => ({\n ...recognizerEvent,\n type,\n })),\n )\n }),\n )\n }),\n tap((event) => {\n stateSubject.next({\n fingers: event.pointers.length,\n })\n }),\n share(),\n )\n\n this.state$ = stateSubject.asObservable()\n\n this.updateInternal(config ?? {}, panConfig)\n }\n\n private updateInternal(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n const existingConfig = this.configSubject.getValue()\n\n this.configSubject.next({\n ...existingConfig,\n ...config,\n ...(config.options && {\n options: { ...existingConfig.options, ...config.options },\n }),\n panConfig: {\n ...existingConfig.panConfig,\n ...panConfig,\n },\n })\n }\n\n public update(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n this.updateInternal(config, panConfig)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n PanRecognizerInterface,\n PanRecognizerOptions,\n} from \"./PanRecognizerInterface\"\n\nexport class PanRecognizer\n extends Recognizer<PanRecognizerOptions, PanEvent>\n implements PanRecognizerInterface\n{\n public events$: Observable<PanEvent>\n public start$: Observable<PanEvent>\n public end$: Observable<PanEvent>\n\n constructor(config?: RecognizerConfig<PanRecognizerOptions>) {\n super(config, {\n ...config,\n posThreshold: config?.options?.posThreshold ?? 15,\n })\n\n this.events$ = this.panEvent$\n\n this.start$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n )\n\n this.end$ = this.events$.pipe(filter((event) => event.type === \"panEnd\"))\n }\n\n public update(config: RecognizerConfig<PanRecognizerOptions>) {\n super.update(config, config.options)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\n\nexport const isRecognizedAsSwipe =\n (escapeVelocity: number) => (stream: Observable<PanEvent>) =>\n stream.pipe(\n filter((event) => {\n return (\n Math.abs(event.velocityX) >= escapeVelocity ||\n Math.abs(event.velocityY) >= escapeVelocity\n )\n }),\n )\n","import {\n Observable,\n filter,\n map,\n share,\n switchMap,\n} from \"rxjs\"\nimport { calculateDegreeAngleBetweenPoints } from \"../utils/geometry\"\nimport { isRecognizedAsSwipe } from \"./operators\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n SwipeEvent,\n SwipeRecognizerInterface,\n SwipeRecognizerOptions,\n} from \"./SwipeRecognizerInterface\"\n\nexport class SwipeRecognizer\n extends Recognizer<SwipeRecognizerOptions, SwipeEvent>\n implements SwipeRecognizerInterface\n{\n public events$: Observable<SwipeEvent>\n\n constructor(config?: RecognizerConfig<SwipeRecognizerOptions>) {\n super(config, {\n posThreshold: 0,\n numInputs: 1,\n })\n\n this.events$ = this.config$.pipe(\n switchMap((initializedWith) => {\n const { escapeVelocity = 0.9 } = initializedWith.options ?? {}\n\n const panStart$ = this.panEvent$.pipe(\n filter((e) => e.type === \"panStart\"),\n )\n\n const panEnd$ = this.panEvent$.pipe(filter((e) => e.type === \"panEnd\"))\n\n return panStart$.pipe(\n switchMap((startEvent) => {\n return panEnd$.pipe(\n isRecognizedAsSwipe(escapeVelocity),\n map(({ type, ...rest }) => {\n return {\n type: \"swipe\" as const,\n angle: calculateDegreeAngleBetweenPoints(\n startEvent.event,\n rest.event,\n ),\n ...rest,\n }\n }),\n )\n }),\n share(),\n )\n }),\n )\n }\n\n public update(config: RecognizerConfig<SwipeRecognizerOptions>) {\n super.update(config)\n }\n}\n","import { Observable, filter, mergeMap, takeUntil, takeWhile, timer } from \"rxjs\"\nimport { isPointerOffEvent, matchPointer } from \"../utils/events\"\nimport { filterPointerOff } from \"../recognizer/operators\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\n\nexport const takeWhenPressedTooLong =\n ({\n timeout,\n pointerEvent$,\n }: {\n timeout: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n timer(timeout).pipe(\n takeUntil(\n pointerEvent$.pipe(filterPointerOff, matchPointer(pointerDown)),\n ),\n ),\n ),\n )\n\nexport const takeWhenOutsideThreshold =\n ({\n initialPointerEvent,\n pointerEvent$,\n tolerance,\n }: {\n initialPointerEvent: PointerEvent\n tolerance: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n pointerEvent$.pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerOffEvent(event), true),\n filter((event) =>\n isWithinPosThreshold(initialPointerEvent, event, tolerance),\n ),\n ),\n ),\n )\n","import {\n Observable,\n buffer,\n debounceTime,\n exhaustMap,\n filter,\n first,\n ignoreElements,\n map,\n merge,\n of,\n share,\n shareReplay,\n switchMap,\n takeUntil,\n withLatestFrom,\n} from \"rxjs\"\nimport { filterNotEmpty } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"../recognizer/scanToRecognizerEvent\"\nimport { trackPointers } from \"../utils/events\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n TapEvent,\n TapRecognizerInterface,\n TapRecognizerOptions,\n} from \"./TapRecognizerInterface\"\nimport { takeWhenOutsideThreshold, takeWhenPressedTooLong } from \"./operators\"\n\nexport class TapRecognizer\n extends Recognizer<TapRecognizerOptions, TapEvent>\n implements TapRecognizerInterface\n{\n public events$: Observable<TapEvent>\n\n constructor(options?: RecognizerConfig<TapRecognizerOptions>) {\n super(options)\n\n this.events$ = this.config$.pipe(\n switchMap((config) => {\n const {\n multiTapThreshold = 0,\n maximumPressTime = 150,\n maxTaps = 1,\n tolerance = 10,\n } = config.options ?? {}\n\n const activePointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasMoreThanOneActivePointer$ = activePointers$.pipe(\n filter(({ pointers }) => pointers.length > 1),\n )\n\n const bufferPointerDowns = (stream: Observable<PointerEvent>) =>\n stream.pipe(\n buffer(this.pointerUp$.pipe(debounceTime(multiTapThreshold))),\n first(),\n )\n\n const tap$ = merge(\n this.pointerDown$,\n activePointers$.pipe(ignoreElements()),\n ).pipe(\n exhaustMap((initialPointerEvent) => {\n const pointerDowns$ = merge(\n of(initialPointerEvent),\n this.pointerDown$,\n ).pipe(shareReplay(1))\n\n const pointerDownsBuffered$ = pointerDowns$.pipe(bufferPointerDowns)\n\n /**\n * Exit condition for `tolerance`\n */\n const clickedTooFarFromOriginalTap$ = pointerDowns$.pipe(\n takeWhenOutsideThreshold({\n initialPointerEvent,\n pointerEvent$: this.pointerEvent$,\n tolerance,\n }),\n )\n\n /**\n * Exit condition for `maximumPressTime`\n */\n const hasFingersPressedForTooLong$ = pointerDowns$.pipe(\n takeWhenPressedTooLong({\n pointerEvent$: this.pointerEvent$,\n timeout: maximumPressTime,\n }),\n )\n\n const takeUntil$ = merge(\n this.failWith$,\n this.pointerCancel$,\n hasMoreThanOneActivePointer$,\n clickedTooFarFromOriginalTap$,\n hasFingersPressedForTooLong$,\n )\n\n const rawEvent$ = pointerDownsBuffered$.pipe(\n filterNotEmpty,\n filter((events) => events.length <= maxTaps),\n map((events) => ({\n type: \"tap\" as const,\n taps: events.length,\n latestActivePointers: events,\n event: events[0],\n })),\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type, taps }]) => ({\n ...recognizerEvent,\n type,\n taps,\n })),\n takeUntil(takeUntil$),\n )\n }),\n )\n\n return tap$\n }),\n share(),\n )\n }\n\n public update(config: RecognizerConfig<TapRecognizerOptions>): void {\n super.update(config)\n }\n}\n","import {\n Observable,\n filter,\n map,\n merge,\n scan,\n share,\n shareReplay,\n switchMap,\n} from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n RotateEvent,\n RotateRecognizerInterface,\n RotateRecognizerOptions,\n} from \"./RotateRecognizerInterface\"\n\nexport class RotateRecognizer\n extends Recognizer<RotateRecognizerOptions, RotateEvent>\n implements RotateRecognizerInterface\n{\n public events$: Observable<RotateEvent>\n\n constructor(config: RecognizerConfig<RotateRecognizerOptions> = {}) {\n super(config, {\n numInputs: 2,\n posThreshold: 15,\n ...config.options,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const rotateStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n map((event) => ({\n ...event,\n type: \"rotateStart\" as const,\n angle: 0,\n deltaAngle: 0,\n })),\n shareReplay(1),\n )\n\n const rotate$ = rotateStart$.pipe(\n switchMap(() =>\n this.panEvent$.pipe(\n scan<\n PanEvent,\n PanEvent & { angle: number; deltaAngle: number },\n undefined\n >((acc, current) => {\n const angle = (acc?.angle ?? 0) + current.deltaPointersAngle\n\n return {\n ...acc,\n ...current,\n angle,\n deltaAngle: current.deltaPointersAngle,\n }\n }, undefined),\n ),\n ),\n share(),\n )\n\n const rotateMove$ = rotate$.pipe(\n filter((event) => event.type === \"panMove\"),\n map((event) => ({ ...event, type: \"rotateMove\" as const })),\n )\n\n const rotateEnd$ = rotate$.pipe(\n filter((event) => event.type === \"panEnd\"),\n map((event) => ({ ...event, type: \"rotateEnd\" as const })),\n )\n\n return merge(rotateStart$, rotateMove$, rotateEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<RotateRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import { Observable, map, scan } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\nimport { PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport const mapPanEventToPinchEvent =\n ({\n type,\n initialEvent,\n }: {\n type: PinchEvent[\"type\"]\n initialEvent: PinchEvent | PanEvent | undefined\n }) =>\n (stream: Observable<PanEvent | PinchEvent>) =>\n stream.pipe(\n scan<\n PanEvent | PinchEvent,\n PinchEvent & {\n initialPointersAverageDistance: number\n },\n PinchEvent | PanEvent | undefined\n >((acc, curr) => {\n const previousPointersLength = acc?.pointers.length ?? 0\n const hasChangedFingers =\n previousPointersLength !== curr.pointers.length\n const previousPointersAverageDistance =\n acc?.pointersAverageDistance ?? curr.pointersAverageDistance\n\n /**\n * initial average distance is reset every time we change fingers\n * @important in case of 1 finger, distance will be 0\n */\n const initialPointersAverageDistance = hasChangedFingers\n ? curr.pointersAverageDistance\n : !!acc && \"initialPointersAverageDistance\" in acc\n ? acc.initialPointersAverageDistance\n : curr.pointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n */\n const scale =\n initialPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / initialPointersAverageDistance\n\n const distance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n const deltaDistance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n * Same when fingers change\n */\n const deltaDistanceScale =\n hasChangedFingers || previousPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / previousPointersAverageDistance\n\n return {\n ...acc,\n ...curr,\n type,\n initialPointersAverageDistance,\n scale,\n distance,\n deltaDistance,\n deltaDistanceScale,\n }\n }, initialEvent),\n map(({ initialPointersAverageDistance, ...rest }): PinchEvent => rest),\n )\n","import {\n Observable,\n filter,\n merge,\n of,\n pairwise,\n share,\n shareReplay,\n startWith,\n switchMap,\n takeWhile,\n} from \"rxjs\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport { mapPanEventToPinchEvent } from \"./mapPanEventToPinchEvent\"\nimport {\n PinchEvent,\n PinchRecognizerInterface,\n PinchRecognizerOptions,\n} from \"./PinchRecognizerInterface\"\n\nexport { type PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport class PinchRecognizer\n extends Recognizer<PinchRecognizerOptions, PinchEvent>\n implements PinchRecognizerInterface\n{\n public events$: Observable<PinchEvent>\n\n constructor(config?: RecognizerConfig<PinchRecognizerOptions>) {\n super(config, {\n ...config?.options,\n numInputs: 2,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const pinchStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n switchMap((event) =>\n of(event).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchStart\",\n initialEvent: undefined,\n }),\n ),\n ),\n shareReplay(1),\n )\n\n const pinchMove$ = pinchStart$.pipe(\n switchMap((initialEvent) => {\n return this.panEvent$.pipe(\n takeWhile((event) => event.type !== \"panEnd\"),\n mapPanEventToPinchEvent({\n type: \"pinchMove\",\n initialEvent,\n }),\n )\n }),\n )\n\n const pinchEnd$ = pinchStart$.pipe(\n switchMap((pinchStartEvent) =>\n this.panEvent$.pipe(\n // we cannot have a panEnd without a previous event so it will always emit\n startWith(pinchStartEvent),\n pairwise(),\n filter(([_, currEvent]) => currEvent.type === \"panEnd\"),\n switchMap(([previousEvent, currEvent]) =>\n of(currEvent).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchEnd\",\n initialEvent: previousEvent,\n }),\n ),\n ),\n ),\n ),\n )\n\n return merge(pinchStart$, pinchMove$, pinchEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<PinchRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import {\n Observable,\n ObservedValueOf,\n combineLatest,\n map,\n merge,\n share,\n} from \"rxjs\"\nimport { Recognizer } from \"../recognizer/Recognizer\"\nimport {\n RecognizableInterface,\n RecognizableState,\n} from \"./RecognizableInterface\"\n\nexport class Recognizable<T extends Recognizer<any, any>[]>\n implements RecognizableInterface<T>\n{\n events$: Observable<ObservedValueOf<T[number][\"events$\"]>>\n recognizers: T\n state$: Observable<RecognizableState>\n\n constructor(\n protected options: {\n recognizers: T\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n },\n ) {\n this.recognizers = options.recognizers\n this.events$ = merge(\n ...options.recognizers.map((recognizer) => recognizer.events$),\n ).pipe(share())\n\n this.state$ = combineLatest(\n this.recognizers.map((recognizer) => recognizer.state$),\n ).pipe(\n map((states) =>\n states.reduce((acc, state) => ({\n fingers: Math.max(acc.fingers, state.fingers),\n })),\n ),\n )\n }\n\n public initialize(container: HTMLElement) {\n /**\n * We have to disable touch-action otherwise every events will be followed\n * by a cancel event since the browser will try to handle touch.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action\n */\n container.style.touchAction = `none`\n\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n */\n container.style.userSelect = `none`\n\n this.options.recognizers.forEach((recognizer) => {\n console.log(\"recognizable update\")\n recognizer.update({\n container,\n afterEventReceived: this.options.afterEventReceived,\n })\n })\n }\n}\n"],"names":["calculateDistance","pointA","pointB","calculateAverageDistance","pointerEvents","n","totalDistance","sum","event1","i","innerSum","event2","numberOfPairs","calculateRadianAngleBetweenPoints","pointerA","pointerB","deltaX","deltaY","calculateDegreeAngleBetweenPoints","calculateCentroid","points","acc","point","numPoints","calculateAngleDelta","initialPoints","newPoints","initialCentroid","newCentroid","totalAngleDelta","initialAngle","angleDelta","radianDelta","degreesDelta","isDefined","arg","hasAtLeastOneItem","events","filterNotEmpty","stream","filter","isWithinPosThreshold","startEvent","endEvent","posThreshold","start","end","calculateVelocity","delay","velocityX","velocityY","matchPointer","pointer","newPointer","isPointerOffEvent","pointerEvent","fromPointerDown","container","afterEventReceived","event","fromEvent","map","trackPointers","pointerEvent$","pointerUp$","pointerLeave$","pointerCancel$","pointerMove$","isPointerRemoved","mergeMap","pointerDown","pointerDown$","defer","of","merge","takeWhile","scan","_deleted","rest","pointers","calculateNewDelta","newCenter","prevCenter","prevDeltaX","prevDeltaY","scanToRecognizerEvent","getCenterFromData","data","curr","prevActivePointersNumber","_a","currActivePointersNumber","_b","hasAddedOrRemovedAFinger","hasAtLeastOneFinger","deltaPointersAngle","latestActivePointers","startTime","center","pointersAverageDistance","isValidConfig","config","filterPointerOff","getPointerEvents","Recognizer","panConfig","__publicField","BehaviorSubject","stateSubject","switchMap","failWith","start$","NEVER","numInputs","trackPointers$","shareReplay","hasEnoughFingers","hasNotEnoughFingers","exhaustMap","initialPointerEvents","panReleased$","first","share","delay$","timer","panStart$","withLatestFrom","takeUntil","panUpdate$","skip","panEnd$","rawEvent$","recognizerEvent","type","tap","existingConfig","PanRecognizer","isRecognizedAsSwipe","escapeVelocity","SwipeRecognizer","initializedWith","e","takeWhenPressedTooLong","timeout","takeWhenOutsideThreshold","initialPointerEvent","tolerance","TapRecognizer","options","multiTapThreshold","maximumPressTime","maxTaps","activePointers$","hasMoreThanOneActivePointer$","bufferPointerDowns","buffer","debounceTime","ignoreElements","pointerDowns$","pointerDownsBuffered$","clickedTooFarFromOriginalTap$","hasFingersPressedForTooLong$","takeUntil$","taps","RotateRecognizer","rotateStart$","rotate$","current","angle","rotateMove$","rotateEnd$","mapPanEventToPinchEvent","initialEvent","hasChangedFingers","previousPointersAverageDistance","initialPointersAverageDistance","scale","distance","deltaDistance","deltaDistanceScale","PinchRecognizer","pinchStart$","pinchMove$","pinchEnd$","pinchStartEvent","startWith","pairwise","_","currEvent","previousEvent","Recognizable","recognizer","combineLatest","states","state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.umd.cjs","sources":["../src/core/utils/geometry.ts","../src/core/utils/utils.ts","../src/core/utils/events.ts","../src/core/recognizer/scanToRecognizerEvent.ts","../src/core/recognizer/operators.ts","../src/core/recognizer/utils.ts","../src/core/recognizer/Recognizer.ts","../src/core/pan/PanRecognizer.ts","../src/core/swipe/operators.ts","../src/core/swipe/SwipeRecognizer.ts","../src/core/tap/operators.ts","../src/core/tap/TapRecognizer.ts","../src/core/rotate/RotateRecognizer.ts","../src/core/pinch/mapPanEventToPinchEvent.ts","../src/core/pinch/PinchRecognizer.ts","../src/core/recognizable/Recognizable.ts"],"sourcesContent":["type Point = { x: number; y: number }\n\nexport function calculateDistance(pointA: Point, pointB: Point): number {\n return Math.sqrt(\n Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2),\n )\n}\n\nexport function calculateAverageDistance(pointerEvents: Point[]): number {\n const n = pointerEvents.length\n if (n < 2) return 0 // No distance if fewer than 2 pointers\n\n const totalDistance = pointerEvents.reduce((sum, event1, i) => {\n return (\n sum +\n pointerEvents.slice(i + 1).reduce((innerSum, event2) => {\n return innerSum + calculateDistance(event1, event2)\n }, 0)\n )\n }, 0)\n\n // Number of pairs is n choose 2: n * (n - 1) / 2\n const numberOfPairs = (n * (n - 1)) / 2\n return totalDistance / numberOfPairs\n}\n\nexport function calculateRadianAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the differences in coordinates\n const deltaX = pointerB.x - pointerA.x\n const deltaY = pointerB.y - pointerA.y\n\n // Calculate the angle in radians\n const angleInRadians = Math.atan2(deltaY, deltaX)\n\n // Return the angle in degrees\n return angleInRadians\n}\n\nexport function calculateDegreeAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the angle in radians\n const angleInRadians = calculateRadianAngleBetweenPoints(pointerA, pointerB)\n\n // Convert the angle to degrees (optional)\n const angleInDegrees = angleInRadians * (180 / Math.PI)\n\n // Return the angle in degrees\n return angleInDegrees\n}\n\nexport function calculateCentroid(points: Point[]) {\n const sum = points.reduce(\n (acc, point) => {\n acc.x += point.x\n acc.y += point.y\n\n return acc\n },\n { x: 0, y: 0 },\n )\n\n const numPoints = points.length || 1\n\n return {\n x: sum.x / numPoints,\n y: sum.y / numPoints,\n }\n}\n\nexport function calculateAngleDelta(\n initialPoints: Point[],\n newPoints: Point[],\n) {\n if (initialPoints.length !== newPoints.length) {\n throw new Error(\"Initial and new points arrays must have the same length.\")\n }\n\n const initialCentroid = calculateCentroid(initialPoints)\n const newCentroid = calculateCentroid(newPoints)\n\n let totalAngleDelta = 0\n\n for (let i = 0; i < initialPoints.length; i++) {\n const initialAngle = calculateRadianAngleBetweenPoints(\n initialCentroid,\n initialPoints[i]!,\n )\n const newAngle = calculateRadianAngleBetweenPoints(\n newCentroid,\n newPoints[i]!,\n )\n\n let angleDelta = newAngle - initialAngle\n\n // Normalize the angle delta to be within [-PI, PI]\n if (angleDelta > Math.PI) {\n angleDelta -= 2 * Math.PI\n } else if (angleDelta < -Math.PI) {\n angleDelta += 2 * Math.PI\n }\n\n totalAngleDelta += angleDelta\n }\n\n // Return the average angle delta\n const radianDelta = totalAngleDelta / initialPoints.length\n const degreesDelta = radianDelta * (180 / Math.PI)\n\n return { radianDelta, degreesDelta }\n}\n","import {\n Observable,\n filter,\n} from \"rxjs\"\nimport { calculateCentroid } from \"./geometry\"\n\nexport function isDefined<T>(\n arg: T | null | undefined,\n): arg is T extends null | undefined ? never : T {\n return arg !== null && arg !== undefined\n}\n\nexport const hasAtLeastOneItem = <T>(events: T[]): events is [T, ...T[]] =>\n events.length > 0\n\nexport const filterNotEmpty = <T>(\n stream: Observable<T[]>,\n): Observable<[T, ...T[]]> => stream.pipe(filter(hasAtLeastOneItem))\n\nexport function isWithinPosThreshold(\n startEvent: PointerEvent,\n endEvent: PointerEvent,\n posThreshold: number,\n) {\n const start = calculateCentroid([startEvent])\n const end = calculateCentroid([endEvent])\n\n // Determines if the movement qualifies as a drag\n return (\n Math.abs(end.x - start.x) >= posThreshold ||\n Math.abs(end.y - start.y) >= posThreshold\n )\n}\n\n/**\n * Avoid division by zero\n * Calculate velocity in pixels per second\n */\nexport const calculateVelocity = (\n delay: number,\n deltaX: number,\n deltaY: number,\n) => {\n const velocityX = delay > 0 ? deltaX / delay : 0\n const velocityY = delay > 0 ? deltaY / delay : 0\n\n return {\n velocityX,\n velocityY,\n }\n}\n","import {\n Observable,\n defer,\n filter,\n fromEvent,\n map,\n merge,\n mergeMap,\n of,\n scan,\n takeWhile,\n} from \"rxjs\"\nimport { isDefined } from \"./utils\"\n\nexport function matchPointer(pointer: PointerEvent) {\n return (stream: Observable<PointerEvent>) =>\n stream.pipe(\n filter((newPointer) => newPointer.pointerId === pointer.pointerId),\n )\n}\n\nexport const isPointerOffEvent = (pointerEvent: PointerEvent) =>\n pointerEvent.type === \"pointerleave\" ||\n pointerEvent.type === \"pointercancel\" ||\n pointerEvent.type === \"pointerup\"\n\nexport const fromPointerDown = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) =>\n fromEvent<PointerEvent>(container, \"pointerdown\").pipe(\n map(afterEventReceived),\n )\n\n/**\n * Track all pointerEvent for active fingers\n */\nexport const trackPointers =\n ({\n pointerEvent$,\n }: {\n pointerEvent$: Observable<PointerEvent>\n /**\n * Setting this value to false will not update the list\n * on pointer move. Use it if you only need to track number of active\n * fingers.\n */\n trackMove: boolean\n }) =>\n (stream: Observable<PointerEvent>) => {\n type PointersState = {\n event: PointerEvent\n pointers: Record<number, PointerEvent | undefined>\n }\n\n const pointerUp$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n const pointerLeave$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointerleave\"),\n )\n const pointerCancel$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n const pointerMove$ = pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n const isPointerRemoved = (event: PointerEvent) =>\n [\"pointercancel\", \"pointerleave\", \"pointerup\"].includes(event.type)\n\n return stream.pipe(\n mergeMap((pointerDown) => {\n const pointerDown$ = defer(() => of(pointerDown))\n\n const tracking$ = merge(\n pointerDown$,\n merge(pointerMove$, pointerCancel$, pointerLeave$, pointerUp$),\n ).pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerRemoved(event), true),\n )\n\n return tracking$\n }),\n scan<PointerEvent, PointersState, undefined>((acc, event) => {\n if (isPointerRemoved(event)) {\n const { [event.pointerId]: _deleted, ...rest } = acc?.pointers ?? {}\n\n return {\n event,\n pointers: rest,\n }\n }\n\n return {\n event,\n pointers: {\n ...(acc?.pointers ?? {}),\n [event.pointerId]: event,\n },\n }\n }, undefined),\n map(({ event, pointers }) => ({\n event,\n pointers: Object.values(pointers).filter(isDefined),\n })),\n )\n }\n","import { Observable, map, scan } from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { calculateVelocity } from \"../utils/utils\"\nimport {\n calculateAngleDelta,\n calculateAverageDistance,\n calculateCentroid,\n} from \"../utils/geometry\"\n\nexport interface RecognizerEventInput {\n event: PointerEvent\n latestActivePointers: PointerEvent[]\n}\n\ninterface RecognizerEventState extends RecognizerEventInput {\n startTime: number\n center: { x: number; y: number }\n deltaX: number\n deltaY: number\n deltaPointersAngle: number\n}\n\nconst calculateNewDelta = (\n newCenter: { x: number; y: number },\n prevCenter: { x: number; y: number },\n prevDeltaX: number,\n prevDeltaY: number,\n) => {\n const deltaX = newCenter.x - prevCenter.x + prevDeltaX\n const deltaY = newCenter.y - prevCenter.y + prevDeltaY\n\n return {\n deltaX,\n deltaY,\n }\n}\n\nexport const scanToRecognizerEvent = <T extends RecognizerEventInput>(\n stream: Observable<T>,\n): Observable<RecognizerEvent> => {\n const getCenterFromData = (data: T) =>\n calculateCentroid(\n !data.latestActivePointers.length\n ? [data.event]\n : data.latestActivePointers,\n )\n\n return stream.pipe(\n scan<T, RecognizerEventState, undefined>((acc, curr) => {\n const newCenter = getCenterFromData(curr)\n const prevCenter = acc?.center ?? newCenter\n const prevDeltaX = acc?.deltaX ?? 0\n const prevDeltaY = acc?.deltaY ?? 0\n const prevActivePointersNumber = acc?.latestActivePointers?.length ?? 1\n const currActivePointersNumber = curr.latestActivePointers?.length ?? 1\n\n const hasAddedOrRemovedAFinger =\n [\"pointerdown\", \"pointercancel\", \"pointerleave\", \"pointerup\"].includes(\n curr.event.type,\n ) && prevActivePointersNumber !== currActivePointersNumber\n\n const hasAtLeastOneFinger = currActivePointersNumber > 0\n\n const { deltaX, deltaY } =\n hasAddedOrRemovedAFinger && hasAtLeastOneFinger\n ? calculateNewDelta(newCenter, newCenter, prevDeltaX, prevDeltaY)\n : calculateNewDelta(newCenter, prevCenter, prevDeltaX, prevDeltaY)\n\n const { degreesDelta: deltaPointersAngle } =\n prevActivePointersNumber === currActivePointersNumber &&\n prevActivePointersNumber >= 2 &&\n currActivePointersNumber >= 2\n ? calculateAngleDelta(\n acc?.latestActivePointers ?? [],\n curr.latestActivePointers ?? [],\n )\n : { degreesDelta: 0 }\n\n return {\n startTime: new Date().getTime(),\n ...acc,\n ...curr,\n center: newCenter,\n deltaX,\n deltaY,\n deltaPointersAngle,\n }\n }, undefined),\n map((data) => {\n const {\n deltaX,\n deltaY,\n latestActivePointers,\n startTime,\n center,\n event,\n deltaPointersAngle,\n } = data\n const events = latestActivePointers ?? []\n\n // Calculate the change in time\n const now = Date.now()\n const delay = now - startTime\n\n const { velocityX, velocityY } = calculateVelocity(delay, deltaX, deltaY)\n const pointersAverageDistance =\n calculateAverageDistance(latestActivePointers)\n\n return {\n deltaX,\n deltaY,\n velocityX,\n velocityY,\n delay,\n center,\n pointers: events,\n startTime,\n event,\n deltaPointersAngle,\n pointersAverageDistance,\n } satisfies RecognizerEvent\n }),\n )\n}\n","import { Observable, filter } from \"rxjs\"\nimport { isPointerOffEvent } from \"../utils/events\"\n\nexport const isValidConfig = <T extends { container?: HTMLElement }>(\n stream: Observable<T>,\n) =>\n stream.pipe(\n filter(\n (config): config is T & { container: HTMLElement } => !!config.container,\n ),\n )\n\nexport const filterPointerOff = (stream: Observable<PointerEvent>) =>\n stream.pipe(filter(isPointerOffEvent))\n","import { fromEvent, map, merge } from \"rxjs\"\nimport { fromPointerDown } from \"../utils/events\"\n\nexport const getPointerEvents = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) => {\n const pointerDown$ = fromPointerDown({ afterEventReceived, container })\n const pointerUp$ = fromEvent<PointerEvent>(container, \"pointerup\").pipe(\n map(afterEventReceived),\n )\n const pointerMove$ = fromEvent<PointerEvent>(container, \"pointermove\").pipe(\n map(afterEventReceived),\n )\n /**\n * Mostly used to handle cursor leaving window on mouse pointers.\n */\n const pointerLeave$ = fromEvent<PointerEvent>(container, \"pointerleave\").pipe(\n map(afterEventReceived),\n )\n /**\n * Handle things such as contextual menu popup or\n * native swipe navigation conflict.\n */\n const pointerCancel$ = fromEvent<PointerEvent>(\n container,\n \"pointercancel\",\n ).pipe(map(afterEventReceived))\n\n return merge(\n pointerDown$,\n pointerCancel$,\n pointerLeave$,\n pointerUp$,\n pointerMove$,\n )\n}\n","import {\n BehaviorSubject,\n NEVER,\n Observable,\n exhaustMap,\n filter,\n first,\n map,\n merge,\n mergeMap,\n of,\n share,\n shareReplay,\n skip,\n switchMap,\n takeUntil,\n tap,\n timer,\n withLatestFrom,\n} from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { trackPointers, matchPointer } from \"../utils/events\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"./scanToRecognizerEvent\"\nimport { filterPointerOff, isValidConfig } from \"./operators\"\nimport { getPointerEvents } from \"./utils\"\n\ntype PanConfig = {\n posThreshold?: number\n delay?: number\n /**\n * Number of inputs to trigger the event.\n * Default to 1\n */\n numInputs?: number\n}\n\nexport type RecognizerConfig<Options> = {\n container?: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n options?: Options\n failWith?: { start$: Observable<unknown> }[]\n}\n\nexport interface PanEvent extends RecognizerEvent {\n type: \"panStart\" | \"panMove\" | \"panEnd\"\n}\n\nexport type State = {\n fingers: number\n}\n\nexport abstract class Recognizer<\n Options extends Record<any, any>,\n Event extends RecognizerEvent,\n> {\n protected configSubject = new BehaviorSubject<\n RecognizerConfig<Options> & {\n panConfig?: PanConfig\n }\n >({})\n protected panEvent$: Observable<PanEvent>\n protected pointerEvent$: Observable<PointerEvent>\n protected pointerDown$: Observable<PointerEvent>\n protected pointerUp$: Observable<PointerEvent>\n protected pointerCancel$: Observable<PointerEvent>\n protected pointerMove$: Observable<PointerEvent>\n protected pointerOff$: Observable<PointerEvent>\n\n public state$: Observable<State>\n\n abstract events$: Observable<Event>\n\n protected failWith$: Observable<unknown>\n\n protected config$ = this.configSubject.pipe(isValidConfig)\n\n constructor(config?: RecognizerConfig<Options>, panConfig?: PanConfig) {\n const stateSubject = new BehaviorSubject<State>({\n fingers: 0,\n })\n\n this.pointerEvent$ = this.config$.pipe(\n switchMap(({ container, afterEventReceived }) =>\n getPointerEvents({\n container,\n afterEventReceived,\n }),\n ),\n )\n\n this.pointerDown$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerdown\"),\n )\n\n this.pointerUp$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointerup\"),\n )\n\n this.pointerMove$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointermove\"),\n )\n\n this.pointerCancel$ = this.pointerEvent$.pipe(\n filter((event) => event.type === \"pointercancel\"),\n )\n\n this.pointerOff$ = this.pointerEvent$.pipe(filterPointerOff)\n\n this.failWith$ = this.config$.pipe(\n switchMap(({ failWith }) =>\n !failWith?.length\n ? NEVER\n : merge(...(failWith?.map(({ start$ }) => start$) ?? [])),\n ),\n )\n\n this.panEvent$ = this.configSubject.pipe(\n isValidConfig,\n switchMap((config) => {\n const numInputs = Math.max(1, config.panConfig?.numInputs ?? 1)\n const posThreshold = Math.max(0, config.panConfig?.posThreshold ?? 0)\n const delay = Math.max(0, config.panConfig?.delay ?? 0)\n\n const trackPointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasEnoughFingers = (\n stream: Observable<{ event: PointerEvent; pointers: PointerEvent[] }>,\n ) =>\n stream.pipe(\n filter(\n (\n events,\n ): events is { event: PointerEvent; pointers: [PointerEvent] } =>\n events.pointers.length >= numInputs,\n ),\n )\n\n const hasNotEnoughFingers = (\n stream: Observable<{\n event: PointerEvent\n pointers: PointerEvent[]\n }>,\n ) => stream.pipe(filter((events) => events.pointers.length < numInputs))\n\n return trackPointers$.pipe(\n hasEnoughFingers,\n exhaustMap(({ pointers: initialPointerEvents }) => {\n const panReleased$ = trackPointers$.pipe(\n hasNotEnoughFingers,\n first(),\n share(),\n )\n\n const delay$ = timer(delay)\n\n const pointerDownPassingThreshold$ = merge(\n ...initialPointerEvents.map((pointerEvent) => of(pointerEvent)),\n this.pointerDown$,\n ).pipe(\n mergeMap((pointerDown) =>\n merge(this.pointerMove$, of(pointerDown)).pipe(\n matchPointer(pointerDown),\n filter((pointerEvent) =>\n isWithinPosThreshold(\n pointerDown,\n pointerEvent,\n posThreshold,\n ),\n ),\n ),\n ),\n first(),\n )\n\n const panStart$ = pointerDownPassingThreshold$.pipe(\n switchMap(() => delay$),\n withLatestFrom(trackPointers$),\n map(([, { event, pointers }]) => ({\n type: \"panStart\" as const,\n event,\n latestActivePointers: pointers,\n })),\n shareReplay({\n bufferSize: 1,\n refCount: false,\n }),\n takeUntil(panReleased$),\n )\n\n const panUpdate$ = panStart$.pipe(\n mergeMap(() =>\n trackPointers$.pipe(\n skip(1),\n map(({ event, pointers }) => ({\n type: \"panMove\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n takeUntil(panReleased$),\n )\n\n const panEnd$ = panStart$.pipe(\n mergeMap(() =>\n panReleased$.pipe(\n map(({ event, pointers }) => ({\n type: \"panEnd\" as const,\n event,\n latestActivePointers: pointers,\n })),\n ),\n ),\n )\n\n const rawEvent$ = merge(panStart$, panUpdate$, panEnd$).pipe(\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type }]) => ({\n ...recognizerEvent,\n type,\n })),\n )\n }),\n )\n }),\n tap((event) => {\n stateSubject.next({\n fingers: event.pointers.length,\n })\n }),\n share(),\n )\n\n this.state$ = stateSubject.asObservable()\n\n this.updateInternal(config ?? {}, panConfig)\n }\n\n private updateInternal(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n const existingConfig = this.configSubject.getValue()\n\n this.configSubject.next({\n ...existingConfig,\n ...config,\n ...(config.options && {\n options: { ...existingConfig.options, ...config.options },\n }),\n panConfig: {\n ...existingConfig.panConfig,\n ...panConfig,\n },\n })\n }\n\n public update(\n config: Partial<RecognizerConfig<Options>>,\n panConfig?: PanConfig,\n ) {\n this.updateInternal(config, panConfig)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n PanRecognizerInterface,\n PanRecognizerOptions,\n} from \"./PanRecognizerInterface\"\n\nexport class PanRecognizer\n extends Recognizer<PanRecognizerOptions, PanEvent>\n implements PanRecognizerInterface\n{\n public events$: Observable<PanEvent>\n public start$: Observable<PanEvent>\n public end$: Observable<PanEvent>\n\n constructor(config?: RecognizerConfig<PanRecognizerOptions>) {\n super(config, {\n ...config,\n posThreshold: config?.options?.posThreshold ?? 15,\n })\n\n this.events$ = this.panEvent$\n\n this.start$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n )\n\n this.end$ = this.events$.pipe(filter((event) => event.type === \"panEnd\"))\n }\n\n public update(config: RecognizerConfig<PanRecognizerOptions>) {\n super.update(config, config.options)\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\n\nexport const isRecognizedAsSwipe =\n (escapeVelocity: number) => (stream: Observable<PanEvent>) =>\n stream.pipe(\n filter((event) => {\n return (\n Math.abs(event.velocityX) >= escapeVelocity ||\n Math.abs(event.velocityY) >= escapeVelocity\n )\n }),\n )\n","import {\n Observable,\n filter,\n map,\n share,\n switchMap,\n} from \"rxjs\"\nimport { calculateDegreeAngleBetweenPoints } from \"../utils/geometry\"\nimport { isRecognizedAsSwipe } from \"./operators\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n SwipeEvent,\n SwipeRecognizerInterface,\n SwipeRecognizerOptions,\n} from \"./SwipeRecognizerInterface\"\n\nexport class SwipeRecognizer\n extends Recognizer<SwipeRecognizerOptions, SwipeEvent>\n implements SwipeRecognizerInterface\n{\n public events$: Observable<SwipeEvent>\n\n constructor(config?: RecognizerConfig<SwipeRecognizerOptions>) {\n super(config, {\n posThreshold: 0,\n numInputs: 1,\n })\n\n this.events$ = this.config$.pipe(\n switchMap((initializedWith) => {\n const { escapeVelocity = 0.9 } = initializedWith.options ?? {}\n\n const panStart$ = this.panEvent$.pipe(\n filter((e) => e.type === \"panStart\"),\n )\n\n const panEnd$ = this.panEvent$.pipe(filter((e) => e.type === \"panEnd\"))\n\n return panStart$.pipe(\n switchMap((startEvent) => {\n return panEnd$.pipe(\n isRecognizedAsSwipe(escapeVelocity),\n map(({ type, ...rest }) => {\n return {\n type: \"swipe\" as const,\n angle: calculateDegreeAngleBetweenPoints(\n startEvent.event,\n rest.event,\n ),\n ...rest,\n }\n }),\n )\n }),\n share(),\n )\n }),\n )\n }\n\n public update(config: RecognizerConfig<SwipeRecognizerOptions>) {\n super.update(config)\n }\n}\n","import { Observable, filter, mergeMap, takeUntil, takeWhile, timer } from \"rxjs\"\nimport { isPointerOffEvent, matchPointer } from \"../utils/events\"\nimport { filterPointerOff } from \"../recognizer/operators\"\nimport { isWithinPosThreshold } from \"../utils/utils\"\n\nexport const takeWhenPressedTooLong =\n ({\n timeout,\n pointerEvent$,\n }: {\n timeout: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n timer(timeout).pipe(\n takeUntil(\n pointerEvent$.pipe(filterPointerOff, matchPointer(pointerDown)),\n ),\n ),\n ),\n )\n\nexport const takeWhenOutsideThreshold =\n ({\n initialPointerEvent,\n pointerEvent$,\n tolerance,\n }: {\n initialPointerEvent: PointerEvent\n tolerance: number\n pointerEvent$: Observable<PointerEvent>\n }) =>\n (stream: Observable<PointerEvent>) =>\n stream.pipe(\n mergeMap((pointerDown) =>\n pointerEvent$.pipe(\n matchPointer(pointerDown),\n takeWhile((event) => !isPointerOffEvent(event), true),\n filter((event) =>\n isWithinPosThreshold(initialPointerEvent, event, tolerance),\n ),\n ),\n ),\n )\n","import {\n Observable,\n buffer,\n debounceTime,\n exhaustMap,\n filter,\n first,\n ignoreElements,\n map,\n merge,\n of,\n share,\n shareReplay,\n switchMap,\n takeUntil,\n withLatestFrom,\n} from \"rxjs\"\nimport { filterNotEmpty } from \"../utils/utils\"\nimport { scanToRecognizerEvent } from \"../recognizer/scanToRecognizerEvent\"\nimport { trackPointers } from \"../utils/events\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n TapEvent,\n TapRecognizerInterface,\n TapRecognizerOptions,\n} from \"./TapRecognizerInterface\"\nimport { takeWhenOutsideThreshold, takeWhenPressedTooLong } from \"./operators\"\n\nexport class TapRecognizer\n extends Recognizer<TapRecognizerOptions, TapEvent>\n implements TapRecognizerInterface\n{\n public events$: Observable<TapEvent>\n\n constructor(options?: RecognizerConfig<TapRecognizerOptions>) {\n super(options)\n\n this.events$ = this.config$.pipe(\n switchMap((config) => {\n const {\n multiTapThreshold = 0,\n maximumPressTime = 150,\n maxTaps = 1,\n tolerance = 10,\n } = config.options ?? {}\n\n const activePointers$ = this.pointerDown$.pipe(\n trackPointers({\n pointerEvent$: this.pointerEvent$,\n trackMove: true,\n }),\n shareReplay(1),\n )\n\n const hasMoreThanOneActivePointer$ = activePointers$.pipe(\n filter(({ pointers }) => pointers.length > 1),\n )\n\n const bufferPointerDowns = (stream: Observable<PointerEvent>) =>\n stream.pipe(\n buffer(this.pointerUp$.pipe(debounceTime(multiTapThreshold))),\n first(),\n )\n\n const tap$ = merge(\n this.pointerDown$,\n activePointers$.pipe(ignoreElements()),\n ).pipe(\n exhaustMap((initialPointerEvent) => {\n const pointerDowns$ = merge(\n of(initialPointerEvent),\n this.pointerDown$,\n ).pipe(shareReplay(1))\n\n const pointerDownsBuffered$ = pointerDowns$.pipe(bufferPointerDowns)\n\n /**\n * Exit condition for `tolerance`\n */\n const clickedTooFarFromOriginalTap$ = pointerDowns$.pipe(\n takeWhenOutsideThreshold({\n initialPointerEvent,\n pointerEvent$: this.pointerEvent$,\n tolerance,\n }),\n )\n\n /**\n * Exit condition for `maximumPressTime`\n */\n const hasFingersPressedForTooLong$ = pointerDowns$.pipe(\n takeWhenPressedTooLong({\n pointerEvent$: this.pointerEvent$,\n timeout: maximumPressTime,\n }),\n )\n\n const takeUntil$ = merge(\n this.failWith$,\n this.pointerCancel$,\n hasMoreThanOneActivePointer$,\n clickedTooFarFromOriginalTap$,\n hasFingersPressedForTooLong$,\n )\n\n const rawEvent$ = pointerDownsBuffered$.pipe(\n filterNotEmpty,\n filter((events) => events.length <= maxTaps),\n map((events) => ({\n type: \"tap\" as const,\n taps: events.length,\n latestActivePointers: events,\n event: events[0],\n })),\n shareReplay(1),\n )\n\n return rawEvent$.pipe(\n scanToRecognizerEvent,\n withLatestFrom(rawEvent$),\n map(([recognizerEvent, { type, taps }]) => ({\n ...recognizerEvent,\n type,\n taps,\n })),\n takeUntil(takeUntil$),\n )\n }),\n )\n\n return tap$\n }),\n share(),\n )\n }\n\n public update(config: RecognizerConfig<TapRecognizerOptions>): void {\n super.update(config)\n }\n}\n","import {\n Observable,\n filter,\n map,\n merge,\n scan,\n share,\n shareReplay,\n switchMap,\n} from \"rxjs\"\nimport {\n Recognizer,\n PanEvent,\n RecognizerConfig,\n} from \"../recognizer/Recognizer\"\nimport {\n RotateEvent,\n RotateRecognizerInterface,\n RotateRecognizerOptions,\n} from \"./RotateRecognizerInterface\"\n\nexport class RotateRecognizer\n extends Recognizer<RotateRecognizerOptions, RotateEvent>\n implements RotateRecognizerInterface\n{\n public events$: Observable<RotateEvent>\n\n constructor(config: RecognizerConfig<RotateRecognizerOptions> = {}) {\n super(config, {\n numInputs: 2,\n posThreshold: 15,\n ...config.options,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const rotateStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n map((event) => ({\n ...event,\n type: \"rotateStart\" as const,\n angle: 0,\n deltaAngle: 0,\n })),\n shareReplay(1),\n )\n\n const rotate$ = rotateStart$.pipe(\n switchMap(() =>\n this.panEvent$.pipe(\n scan<\n PanEvent,\n PanEvent & { angle: number; deltaAngle: number },\n undefined\n >((acc, current) => {\n const angle = (acc?.angle ?? 0) + current.deltaPointersAngle\n\n return {\n ...acc,\n ...current,\n angle,\n deltaAngle: current.deltaPointersAngle,\n }\n }, undefined),\n ),\n ),\n share(),\n )\n\n const rotateMove$ = rotate$.pipe(\n filter((event) => event.type === \"panMove\"),\n map((event) => ({ ...event, type: \"rotateMove\" as const })),\n )\n\n const rotateEnd$ = rotate$.pipe(\n filter((event) => event.type === \"panEnd\"),\n map((event) => ({ ...event, type: \"rotateEnd\" as const })),\n )\n\n return merge(rotateStart$, rotateMove$, rotateEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<RotateRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import { Observable, map, scan } from \"rxjs\"\nimport { PanEvent } from \"../recognizer/Recognizer\"\nimport { PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport const mapPanEventToPinchEvent =\n ({\n type,\n initialEvent,\n }: {\n type: PinchEvent[\"type\"]\n initialEvent: PinchEvent | PanEvent | undefined\n }) =>\n (stream: Observable<PanEvent | PinchEvent>) =>\n stream.pipe(\n scan<\n PanEvent | PinchEvent,\n PinchEvent & {\n initialPointersAverageDistance: number\n },\n PinchEvent | PanEvent | undefined\n >((acc, curr) => {\n const previousPointersLength = acc?.pointers.length ?? 0\n const hasChangedFingers =\n previousPointersLength !== curr.pointers.length\n const previousPointersAverageDistance =\n acc?.pointersAverageDistance ?? curr.pointersAverageDistance\n\n /**\n * initial average distance is reset every time we change fingers\n * @important in case of 1 finger, distance will be 0\n */\n const initialPointersAverageDistance = hasChangedFingers\n ? curr.pointersAverageDistance\n : !!acc && \"initialPointersAverageDistance\" in acc\n ? acc.initialPointersAverageDistance\n : curr.pointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n */\n const scale =\n initialPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / initialPointersAverageDistance\n\n const distance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n const deltaDistance =\n curr.pointersAverageDistance - initialPointersAverageDistance\n\n /**\n * @important When finger is 1, distance is 0\n * Same when fingers change\n */\n const deltaDistanceScale =\n hasChangedFingers || previousPointersAverageDistance === 0\n ? 1\n : curr.pointersAverageDistance / previousPointersAverageDistance\n\n return {\n ...acc,\n ...curr,\n type,\n initialPointersAverageDistance,\n scale,\n distance,\n deltaDistance,\n deltaDistanceScale,\n }\n }, initialEvent),\n map(({ initialPointersAverageDistance, ...rest }): PinchEvent => rest),\n )\n","import {\n Observable,\n filter,\n merge,\n of,\n pairwise,\n share,\n shareReplay,\n startWith,\n switchMap,\n takeWhile,\n} from \"rxjs\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport { mapPanEventToPinchEvent } from \"./mapPanEventToPinchEvent\"\nimport {\n PinchEvent,\n PinchRecognizerInterface,\n PinchRecognizerOptions,\n} from \"./PinchRecognizerInterface\"\n\nexport { type PinchEvent } from \"./PinchRecognizerInterface\"\n\nexport class PinchRecognizer\n extends Recognizer<PinchRecognizerOptions, PinchEvent>\n implements PinchRecognizerInterface\n{\n public events$: Observable<PinchEvent>\n\n constructor(config?: RecognizerConfig<PinchRecognizerOptions>) {\n super(config, {\n ...config?.options,\n numInputs: 2,\n })\n\n this.events$ = this.config$.pipe(\n switchMap(() => {\n const pinchStart$ = this.panEvent$.pipe(\n filter((event) => event.type === \"panStart\"),\n switchMap((event) =>\n of(event).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchStart\",\n initialEvent: undefined,\n }),\n ),\n ),\n shareReplay(1),\n )\n\n const pinchMove$ = pinchStart$.pipe(\n switchMap((initialEvent) => {\n return this.panEvent$.pipe(\n takeWhile((event) => event.type !== \"panEnd\"),\n mapPanEventToPinchEvent({\n type: \"pinchMove\",\n initialEvent,\n }),\n )\n }),\n )\n\n const pinchEnd$ = pinchStart$.pipe(\n switchMap((pinchStartEvent) =>\n this.panEvent$.pipe(\n // we cannot have a panEnd without a previous event so it will always emit\n startWith(pinchStartEvent),\n pairwise(),\n filter(([_, currEvent]) => currEvent.type === \"panEnd\"),\n switchMap(([previousEvent, currEvent]) =>\n of(currEvent).pipe(\n mapPanEventToPinchEvent({\n type: \"pinchEnd\",\n initialEvent: previousEvent,\n }),\n ),\n ),\n ),\n ),\n )\n\n return merge(pinchStart$, pinchMove$, pinchEnd$)\n }),\n share(),\n )\n }\n\n public update(options: RecognizerConfig<PinchRecognizerOptions>) {\n super.update(options, options.options)\n }\n}\n","import {\n Observable,\n ObservedValueOf,\n combineLatest,\n map,\n merge,\n share,\n} from \"rxjs\"\nimport { Recognizer, RecognizerConfig } from \"../recognizer/Recognizer\"\nimport {\n RecognizableInterface,\n RecognizableState,\n} from \"./RecognizableInterface\"\n\nexport class Recognizable<T extends Recognizer<any, any>[]>\n implements RecognizableInterface<T>\n{\n events$: Observable<ObservedValueOf<T[number][\"events$\"]>>\n recognizers: T\n state$: Observable<RecognizableState>\n\n constructor(\n protected options: {\n recognizers: T\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n },\n ) {\n this.recognizers = options.recognizers\n this.events$ = merge(\n ...options.recognizers.map((recognizer) => recognizer.events$),\n ).pipe(share())\n\n this.state$ = combineLatest(\n this.recognizers.map((recognizer) => recognizer.state$),\n ).pipe(\n map((states) =>\n states.reduce((acc, state) => ({\n fingers: Math.max(acc.fingers, state.fingers),\n })),\n ),\n )\n }\n\n public update(options: RecognizerConfig<unknown>) {\n if (options.container) {\n /**\n * We have to disable touch-action otherwise every events will be followed\n * by a cancel event since the browser will try to handle touch.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action\n */\n options.container.style.touchAction = `none`\n\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n */\n options.container.style.userSelect = `none`\n }\n\n this.options.recognizers.forEach((recognizer) => {\n recognizer.update(options)\n })\n }\n}\n"],"names":["calculateDistance","pointA","pointB","calculateAverageDistance","pointerEvents","n","totalDistance","sum","event1","i","innerSum","event2","numberOfPairs","calculateRadianAngleBetweenPoints","pointerA","pointerB","deltaX","deltaY","calculateDegreeAngleBetweenPoints","calculateCentroid","points","acc","point","numPoints","calculateAngleDelta","initialPoints","newPoints","initialCentroid","newCentroid","totalAngleDelta","initialAngle","angleDelta","radianDelta","degreesDelta","isDefined","arg","hasAtLeastOneItem","events","filterNotEmpty","stream","filter","isWithinPosThreshold","startEvent","endEvent","posThreshold","start","end","calculateVelocity","delay","velocityX","velocityY","matchPointer","pointer","newPointer","isPointerOffEvent","pointerEvent","fromPointerDown","container","afterEventReceived","event","fromEvent","map","trackPointers","pointerEvent$","pointerUp$","pointerLeave$","pointerCancel$","pointerMove$","isPointerRemoved","mergeMap","pointerDown","pointerDown$","defer","of","merge","takeWhile","scan","_deleted","rest","pointers","calculateNewDelta","newCenter","prevCenter","prevDeltaX","prevDeltaY","scanToRecognizerEvent","getCenterFromData","data","curr","prevActivePointersNumber","_a","currActivePointersNumber","_b","hasAddedOrRemovedAFinger","hasAtLeastOneFinger","deltaPointersAngle","latestActivePointers","startTime","center","pointersAverageDistance","isValidConfig","config","filterPointerOff","getPointerEvents","Recognizer","panConfig","__publicField","BehaviorSubject","stateSubject","switchMap","failWith","start$","NEVER","numInputs","trackPointers$","shareReplay","hasEnoughFingers","hasNotEnoughFingers","exhaustMap","initialPointerEvents","panReleased$","first","share","delay$","timer","panStart$","withLatestFrom","takeUntil","panUpdate$","skip","panEnd$","rawEvent$","recognizerEvent","type","tap","existingConfig","PanRecognizer","isRecognizedAsSwipe","escapeVelocity","SwipeRecognizer","initializedWith","e","takeWhenPressedTooLong","timeout","takeWhenOutsideThreshold","initialPointerEvent","tolerance","TapRecognizer","options","multiTapThreshold","maximumPressTime","maxTaps","activePointers$","hasMoreThanOneActivePointer$","bufferPointerDowns","buffer","debounceTime","ignoreElements","pointerDowns$","pointerDownsBuffered$","clickedTooFarFromOriginalTap$","hasFingersPressedForTooLong$","takeUntil$","taps","RotateRecognizer","rotateStart$","rotate$","current","angle","rotateMove$","rotateEnd$","mapPanEventToPinchEvent","initialEvent","hasChangedFingers","previousPointersAverageDistance","initialPointersAverageDistance","scale","distance","deltaDistance","deltaDistanceScale","PinchRecognizer","pinchStart$","pinchMove$","pinchEnd$","pinchStartEvent","startWith","pairwise","_","currEvent","previousEvent","Recognizable","recognizer","combineLatest","states","state"],"mappings":"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"}
|