gesturx 1.0.0 → 1.2.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/README.md +17 -1
- package/dist/index.d.ts +192 -0
- package/dist/index.js +627 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +2 -0
- package/dist/index.umd.cjs.map +1 -0
- package/package.json +12 -1
- package/.github/workflows/publish.yml +0 -17
- package/.prettierrc.json +0 -3
- package/eslint.config.js +0 -18
- package/index.html +0 -13
- package/src/core/index.ts +0 -4
- package/src/core/manager.ts +0 -46
- package/src/core/pan/PanRecognizer.ts +0 -192
- package/src/core/pinch/PinchRecognizer.ts +0 -131
- package/src/core/recognizer/Recognizer.ts +0 -54
- package/src/core/recognizer/RecognizerEvent.ts +0 -39
- package/src/core/recognizer/mapToRecognizerEvent.ts +0 -142
- package/src/core/rotate/RotateRecognizer.ts +0 -115
- package/src/core/swipe/SwipeRecognizer.test.ts +0 -160
- package/src/core/swipe/SwipeRecognizer.ts +0 -82
- package/src/core/swipe/isRecognizedAsSwipe.ts +0 -13
- package/src/core/tap/TapRecognizer.test.ts +0 -567
- package/src/core/tap/TapRecognizer.ts +0 -172
- package/src/core/utils/events.ts +0 -186
- package/src/core/utils/geometry.ts +0 -115
- package/src/core/utils/utils.test.ts +0 -26
- package/src/core/utils/utils.ts +0 -58
- package/src/demo/App.tsx +0 -171
- package/src/demo/DebugBox.tsx +0 -10
- package/src/demo/useManager.ts +0 -40
- package/src/demo/useTap.tsx +0 -87
- package/src/index.css +0 -66
- package/src/main.tsx +0 -14
- package/src/theme.ts +0 -11
- package/src/vite-env.d.ts +0 -1
- package/tsconfig.json +0 -26
- package/tsconfig.node.json +0 -11
- package/vite.config.ts +0 -38
- package/vitest.config.ts +0 -8
- /package/{public → dist}/vite.svg +0 -0
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Observable,
|
|
3
|
-
exhaustMap,
|
|
4
|
-
filter,
|
|
5
|
-
first,
|
|
6
|
-
map,
|
|
7
|
-
share,
|
|
8
|
-
switchMap,
|
|
9
|
-
takeUntil,
|
|
10
|
-
} from "rxjs"
|
|
11
|
-
import { Recognizer } from "../recognizer/Recognizer"
|
|
12
|
-
import { PanRecognizer } from "../pan/PanRecognizer"
|
|
13
|
-
import { RecognizerEvent } from "../recognizer/RecognizerEvent"
|
|
14
|
-
import { calculateDegreeAngleBetweenPoints } from "../utils/geometry"
|
|
15
|
-
import { isRecognizedAsSwipe } from "./isRecognizedAsSwipe"
|
|
16
|
-
|
|
17
|
-
export interface SwipeEvent extends RecognizerEvent {
|
|
18
|
-
type: "swipe"
|
|
19
|
-
/**
|
|
20
|
-
* Angle between first pointer and last one in degree
|
|
21
|
-
*
|
|
22
|
-
* (-90)
|
|
23
|
-
* (+/-180) <- | -> (+/-0)
|
|
24
|
-
* (+90)
|
|
25
|
-
*/
|
|
26
|
-
angle: number
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
type Options = {
|
|
30
|
-
/**
|
|
31
|
-
* The minimum velocity (px/ms) that the gesture has to obtain by the end event.
|
|
32
|
-
*/
|
|
33
|
-
escapeVelocity?: number
|
|
34
|
-
// @todo
|
|
35
|
-
numInputs?: number
|
|
36
|
-
// @todo
|
|
37
|
-
maxRestTime?: number
|
|
38
|
-
posThreshold?: number
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class SwipeRecognizer extends Recognizer<Options> {
|
|
42
|
-
public events$: Observable<SwipeEvent>
|
|
43
|
-
|
|
44
|
-
constructor(protected options: Options = {}) {
|
|
45
|
-
super(options)
|
|
46
|
-
|
|
47
|
-
this.events$ = this.validConfig$.pipe(
|
|
48
|
-
switchMap((initializedWith) => {
|
|
49
|
-
const { escapeVelocity = 0.9, posThreshold } =
|
|
50
|
-
initializedWith.options ?? {}
|
|
51
|
-
const panRecognizer = new PanRecognizer({ posThreshold })
|
|
52
|
-
|
|
53
|
-
panRecognizer.initialize(initializedWith)
|
|
54
|
-
|
|
55
|
-
const hasMoreThanOneFinger$ = panRecognizer.events$.pipe(
|
|
56
|
-
filter(({ pointers }) => pointers.length > 1),
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
return panRecognizer.start$.pipe(
|
|
60
|
-
exhaustMap((startEvent) => {
|
|
61
|
-
return panRecognizer.end$.pipe(
|
|
62
|
-
first(),
|
|
63
|
-
isRecognizedAsSwipe(escapeVelocity),
|
|
64
|
-
map(({ type, ...rest }) => {
|
|
65
|
-
return {
|
|
66
|
-
type: "swipe" as const,
|
|
67
|
-
angle: calculateDegreeAngleBetweenPoints(
|
|
68
|
-
startEvent.event,
|
|
69
|
-
rest.event,
|
|
70
|
-
),
|
|
71
|
-
...rest,
|
|
72
|
-
}
|
|
73
|
-
}),
|
|
74
|
-
takeUntil(hasMoreThanOneFinger$),
|
|
75
|
-
)
|
|
76
|
-
}),
|
|
77
|
-
share(),
|
|
78
|
-
)
|
|
79
|
-
}),
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Observable, filter } from "rxjs"
|
|
2
|
-
import { PanEvent } from "../pan/PanRecognizer"
|
|
3
|
-
|
|
4
|
-
export const isRecognizedAsSwipe =
|
|
5
|
-
(escapeVelocity: number) => (stream: Observable<PanEvent>) =>
|
|
6
|
-
stream.pipe(
|
|
7
|
-
filter((event) => {
|
|
8
|
-
return (
|
|
9
|
-
Math.abs(event.velocityX) >= escapeVelocity ||
|
|
10
|
-
Math.abs(event.velocityY) >= escapeVelocity
|
|
11
|
-
)
|
|
12
|
-
}),
|
|
13
|
-
)
|
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from "vitest"
|
|
2
|
-
import { TapRecognizer } from "./TapRecognizer"
|
|
3
|
-
import { buffer, first, lastValueFrom, tap, timer } from "rxjs"
|
|
4
|
-
|
|
5
|
-
const waitFor = (time: number) =>
|
|
6
|
-
new Promise((resolve) => setTimeout(resolve, time))
|
|
7
|
-
|
|
8
|
-
describe("TapGestureRecognizer", () => {
|
|
9
|
-
let container = document.createElement("div")
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
container = document.createElement("div")
|
|
13
|
-
document.body.appendChild(container)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
function createPointerEvent({
|
|
17
|
-
type,
|
|
18
|
-
x,
|
|
19
|
-
y,
|
|
20
|
-
identifier,
|
|
21
|
-
}: {
|
|
22
|
-
type: string
|
|
23
|
-
x: number
|
|
24
|
-
y: number
|
|
25
|
-
identifier: number
|
|
26
|
-
}) {
|
|
27
|
-
const event = new PointerEvent(type, {
|
|
28
|
-
clientX: x,
|
|
29
|
-
clientY: y,
|
|
30
|
-
pointerId: identifier,
|
|
31
|
-
pointerType: "touch",
|
|
32
|
-
bubbles: true,
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
// @ts-ignore
|
|
36
|
-
event.x = x
|
|
37
|
-
// @ts-ignore
|
|
38
|
-
event.y = y
|
|
39
|
-
|
|
40
|
-
return event
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function sendPointerEvent({
|
|
44
|
-
type,
|
|
45
|
-
x,
|
|
46
|
-
y,
|
|
47
|
-
container,
|
|
48
|
-
identifier,
|
|
49
|
-
}: {
|
|
50
|
-
container: HTMLElement
|
|
51
|
-
type: string
|
|
52
|
-
x: number
|
|
53
|
-
y: number
|
|
54
|
-
identifier: number
|
|
55
|
-
}) {
|
|
56
|
-
const event = createPointerEvent({
|
|
57
|
-
type,
|
|
58
|
-
x,
|
|
59
|
-
y,
|
|
60
|
-
identifier,
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
sendPointerEventFromEvent({ event, container })
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function sendPointerEventFromEvent({
|
|
67
|
-
event,
|
|
68
|
-
container,
|
|
69
|
-
}: {
|
|
70
|
-
event: PointerEvent
|
|
71
|
-
container: HTMLElement
|
|
72
|
-
}) {
|
|
73
|
-
container.dispatchEvent(event)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
it("should detect a single tap", async () => {
|
|
77
|
-
const multiTapThreshold = 5
|
|
78
|
-
const waitLongEnough$ = timer(100)
|
|
79
|
-
const recognizer = new TapRecognizer({ multiTapThreshold })
|
|
80
|
-
recognizer.initialize({
|
|
81
|
-
container,
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
const values = await lastValueFrom(
|
|
85
|
-
recognizer.events$.pipe(
|
|
86
|
-
tap({
|
|
87
|
-
subscribe: async () => {
|
|
88
|
-
await waitFor(1)
|
|
89
|
-
|
|
90
|
-
sendPointerEvent({
|
|
91
|
-
container,
|
|
92
|
-
identifier: 1,
|
|
93
|
-
type: "pointerdown",
|
|
94
|
-
x: 0,
|
|
95
|
-
y: 0,
|
|
96
|
-
})
|
|
97
|
-
sendPointerEvent({
|
|
98
|
-
container,
|
|
99
|
-
identifier: 1,
|
|
100
|
-
type: "pointerup",
|
|
101
|
-
x: 0,
|
|
102
|
-
y: 0,
|
|
103
|
-
})
|
|
104
|
-
},
|
|
105
|
-
}),
|
|
106
|
-
buffer(waitLongEnough$),
|
|
107
|
-
first(),
|
|
108
|
-
),
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
expect(values).toMatchObject([{ type: "tap", taps: 1 }])
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it("should detect a double tap", async () => {
|
|
115
|
-
const multiTapThreshold = 5
|
|
116
|
-
const waitLongEnough$ = timer(multiTapThreshold * 2)
|
|
117
|
-
const recognizer = new TapRecognizer({ multiTapThreshold, maxTaps: 2 })
|
|
118
|
-
recognizer.initialize({
|
|
119
|
-
container,
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
const values = await lastValueFrom(
|
|
123
|
-
recognizer.events$.pipe(
|
|
124
|
-
tap({
|
|
125
|
-
subscribe: async () => {
|
|
126
|
-
await waitFor(1)
|
|
127
|
-
|
|
128
|
-
sendPointerEvent({
|
|
129
|
-
container,
|
|
130
|
-
identifier: 1,
|
|
131
|
-
type: "pointerdown",
|
|
132
|
-
x: 0,
|
|
133
|
-
y: 0,
|
|
134
|
-
})
|
|
135
|
-
sendPointerEvent({
|
|
136
|
-
container,
|
|
137
|
-
identifier: 1,
|
|
138
|
-
type: "pointerup",
|
|
139
|
-
x: 0,
|
|
140
|
-
y: 0,
|
|
141
|
-
})
|
|
142
|
-
sendPointerEvent({
|
|
143
|
-
container,
|
|
144
|
-
identifier: 2,
|
|
145
|
-
type: "pointerdown",
|
|
146
|
-
x: 0,
|
|
147
|
-
y: 0,
|
|
148
|
-
})
|
|
149
|
-
sendPointerEvent({
|
|
150
|
-
container,
|
|
151
|
-
identifier: 2,
|
|
152
|
-
type: "pointerup",
|
|
153
|
-
x: 0,
|
|
154
|
-
y: 0,
|
|
155
|
-
})
|
|
156
|
-
},
|
|
157
|
-
}),
|
|
158
|
-
buffer(waitLongEnough$),
|
|
159
|
-
first(),
|
|
160
|
-
),
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
expect(values).toMatchObject([{ type: "tap", taps: 2 }])
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it("should detect a triple tap", async () => {
|
|
167
|
-
const multiTapThreshold = 5
|
|
168
|
-
const recognizer = new TapRecognizer({ multiTapThreshold, maxTaps: 3 })
|
|
169
|
-
recognizer.initialize({
|
|
170
|
-
container,
|
|
171
|
-
})
|
|
172
|
-
const waitLongEnough$ = timer(100)
|
|
173
|
-
|
|
174
|
-
const values = await lastValueFrom(
|
|
175
|
-
recognizer.events$.pipe(
|
|
176
|
-
tap({
|
|
177
|
-
subscribe: () => {
|
|
178
|
-
setTimeout(() => {
|
|
179
|
-
sendPointerEvent({
|
|
180
|
-
container,
|
|
181
|
-
identifier: 1,
|
|
182
|
-
type: "pointerdown",
|
|
183
|
-
x: 0,
|
|
184
|
-
y: 0,
|
|
185
|
-
})
|
|
186
|
-
sendPointerEvent({
|
|
187
|
-
container,
|
|
188
|
-
identifier: 1,
|
|
189
|
-
type: "pointerup",
|
|
190
|
-
x: 0,
|
|
191
|
-
y: 0,
|
|
192
|
-
})
|
|
193
|
-
sendPointerEvent({
|
|
194
|
-
container,
|
|
195
|
-
identifier: 1,
|
|
196
|
-
type: "pointerdown",
|
|
197
|
-
x: 0,
|
|
198
|
-
y: 0,
|
|
199
|
-
})
|
|
200
|
-
sendPointerEvent({
|
|
201
|
-
container,
|
|
202
|
-
identifier: 1,
|
|
203
|
-
type: "pointerup",
|
|
204
|
-
x: 0,
|
|
205
|
-
y: 0,
|
|
206
|
-
})
|
|
207
|
-
sendPointerEvent({
|
|
208
|
-
container,
|
|
209
|
-
identifier: 1,
|
|
210
|
-
type: "pointerdown",
|
|
211
|
-
x: 0,
|
|
212
|
-
y: 0,
|
|
213
|
-
})
|
|
214
|
-
sendPointerEvent({
|
|
215
|
-
container,
|
|
216
|
-
identifier: 1,
|
|
217
|
-
type: "pointerup",
|
|
218
|
-
x: 0,
|
|
219
|
-
y: 0,
|
|
220
|
-
})
|
|
221
|
-
})
|
|
222
|
-
},
|
|
223
|
-
}),
|
|
224
|
-
buffer(waitLongEnough$),
|
|
225
|
-
first(),
|
|
226
|
-
),
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
expect(values).toMatchObject([{ type: "tap", taps: 3 }])
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
it("should not detect a double tap if the second tap is after threshold", async () => {
|
|
233
|
-
const multiTapThreshold = 5
|
|
234
|
-
const waitLongEnough$ = timer(100)
|
|
235
|
-
const recognizer = new TapRecognizer({ multiTapThreshold, maxTaps: 2 })
|
|
236
|
-
recognizer.initialize({
|
|
237
|
-
container,
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
const values = await lastValueFrom(
|
|
241
|
-
recognizer.events$.pipe(
|
|
242
|
-
tap({
|
|
243
|
-
subscribe: async () => {
|
|
244
|
-
await waitFor(1)
|
|
245
|
-
|
|
246
|
-
sendPointerEvent({
|
|
247
|
-
container,
|
|
248
|
-
identifier: 1,
|
|
249
|
-
type: "pointerdown",
|
|
250
|
-
x: 0,
|
|
251
|
-
y: 0,
|
|
252
|
-
})
|
|
253
|
-
sendPointerEvent({
|
|
254
|
-
container,
|
|
255
|
-
identifier: 1,
|
|
256
|
-
type: "pointerup",
|
|
257
|
-
x: 0,
|
|
258
|
-
y: 0,
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
await waitFor(multiTapThreshold)
|
|
262
|
-
|
|
263
|
-
sendPointerEvent({
|
|
264
|
-
container,
|
|
265
|
-
identifier: 2,
|
|
266
|
-
type: "pointerdown",
|
|
267
|
-
x: 0,
|
|
268
|
-
y: 0,
|
|
269
|
-
})
|
|
270
|
-
sendPointerEvent({
|
|
271
|
-
container,
|
|
272
|
-
identifier: 2,
|
|
273
|
-
type: "pointerup",
|
|
274
|
-
x: 0,
|
|
275
|
-
y: 0,
|
|
276
|
-
})
|
|
277
|
-
},
|
|
278
|
-
}),
|
|
279
|
-
buffer(waitLongEnough$),
|
|
280
|
-
first(),
|
|
281
|
-
),
|
|
282
|
-
)
|
|
283
|
-
|
|
284
|
-
expect(values.length).toBe(2)
|
|
285
|
-
expect(values).toMatchObject([
|
|
286
|
-
{ type: "tap", taps: 1, pointers: [{ pointerId: 1 }] },
|
|
287
|
-
{ type: "tap", taps: 1, pointers: [{ pointerId: 2 }] },
|
|
288
|
-
])
|
|
289
|
-
})
|
|
290
|
-
|
|
291
|
-
it("should not trigger tap if moved too much between down and up", async () => {
|
|
292
|
-
const multiTapThreshold = 5
|
|
293
|
-
const waitLongEnough$ = timer(100)
|
|
294
|
-
const recognizer = new TapRecognizer({
|
|
295
|
-
multiTapThreshold,
|
|
296
|
-
posThreshold: 5,
|
|
297
|
-
})
|
|
298
|
-
recognizer.initialize({
|
|
299
|
-
container,
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
const values = await lastValueFrom(
|
|
303
|
-
recognizer.events$.pipe(
|
|
304
|
-
tap({
|
|
305
|
-
subscribe: async () => {
|
|
306
|
-
await waitFor(1)
|
|
307
|
-
|
|
308
|
-
sendPointerEvent({
|
|
309
|
-
container,
|
|
310
|
-
identifier: 1,
|
|
311
|
-
type: "pointerdown",
|
|
312
|
-
x: 0,
|
|
313
|
-
y: 0,
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
sendPointerEvent({
|
|
317
|
-
container,
|
|
318
|
-
identifier: 1,
|
|
319
|
-
type: "pointerup",
|
|
320
|
-
x: 50,
|
|
321
|
-
y: 50,
|
|
322
|
-
})
|
|
323
|
-
},
|
|
324
|
-
}),
|
|
325
|
-
buffer(waitLongEnough$),
|
|
326
|
-
first(),
|
|
327
|
-
),
|
|
328
|
-
)
|
|
329
|
-
|
|
330
|
-
expect(values.length).toBe(0)
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
it("should not detect a tap if the pointer is held down too long", async () => {
|
|
334
|
-
const multiTapThreshold = 5
|
|
335
|
-
const maximumPressTime = 10
|
|
336
|
-
const waitLongEnough$ = timer(100)
|
|
337
|
-
const recognizer = new TapRecognizer({
|
|
338
|
-
multiTapThreshold,
|
|
339
|
-
posThreshold: 5,
|
|
340
|
-
maximumPressTime,
|
|
341
|
-
})
|
|
342
|
-
recognizer.initialize({
|
|
343
|
-
container,
|
|
344
|
-
})
|
|
345
|
-
|
|
346
|
-
const values = await lastValueFrom(
|
|
347
|
-
recognizer.events$.pipe(
|
|
348
|
-
tap({
|
|
349
|
-
subscribe: async () => {
|
|
350
|
-
await waitFor(1)
|
|
351
|
-
|
|
352
|
-
sendPointerEvent({
|
|
353
|
-
container,
|
|
354
|
-
identifier: 1,
|
|
355
|
-
type: "pointerdown",
|
|
356
|
-
x: 0,
|
|
357
|
-
y: 0,
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
await waitFor(maximumPressTime - 5)
|
|
361
|
-
|
|
362
|
-
sendPointerEvent({
|
|
363
|
-
container,
|
|
364
|
-
identifier: 1,
|
|
365
|
-
type: "pointerup",
|
|
366
|
-
x: 0,
|
|
367
|
-
y: 0,
|
|
368
|
-
})
|
|
369
|
-
|
|
370
|
-
await waitFor(multiTapThreshold * 2)
|
|
371
|
-
|
|
372
|
-
sendPointerEvent({
|
|
373
|
-
container,
|
|
374
|
-
identifier: 2,
|
|
375
|
-
type: "pointerdown",
|
|
376
|
-
x: 0,
|
|
377
|
-
y: 0,
|
|
378
|
-
})
|
|
379
|
-
|
|
380
|
-
await waitFor(maximumPressTime)
|
|
381
|
-
|
|
382
|
-
sendPointerEvent({
|
|
383
|
-
container,
|
|
384
|
-
identifier: 2,
|
|
385
|
-
type: "pointerup",
|
|
386
|
-
x: 0,
|
|
387
|
-
y: 0,
|
|
388
|
-
})
|
|
389
|
-
},
|
|
390
|
-
}),
|
|
391
|
-
buffer(waitLongEnough$),
|
|
392
|
-
first(),
|
|
393
|
-
),
|
|
394
|
-
)
|
|
395
|
-
|
|
396
|
-
expect(values.length).toBe(1)
|
|
397
|
-
expect(values).toMatchObject([
|
|
398
|
-
{ type: "tap", taps: 1, pointers: [{ pointerId: 1 }] },
|
|
399
|
-
])
|
|
400
|
-
})
|
|
401
|
-
|
|
402
|
-
it("should ignore taps when there are simultaneous pointers active", async () => {
|
|
403
|
-
const recognizer = new TapRecognizer({})
|
|
404
|
-
recognizer.initialize({
|
|
405
|
-
container,
|
|
406
|
-
})
|
|
407
|
-
const waitLongEnough$ = timer(100)
|
|
408
|
-
|
|
409
|
-
const values = await lastValueFrom(
|
|
410
|
-
recognizer.events$.pipe(
|
|
411
|
-
tap({
|
|
412
|
-
subscribe: () => {
|
|
413
|
-
setTimeout(() => {
|
|
414
|
-
sendPointerEvent({
|
|
415
|
-
container,
|
|
416
|
-
identifier: 1,
|
|
417
|
-
type: "pointerdown",
|
|
418
|
-
x: 0,
|
|
419
|
-
y: 0,
|
|
420
|
-
})
|
|
421
|
-
sendPointerEvent({
|
|
422
|
-
container,
|
|
423
|
-
identifier: 2,
|
|
424
|
-
type: "pointerdown",
|
|
425
|
-
x: 10,
|
|
426
|
-
y: 10,
|
|
427
|
-
})
|
|
428
|
-
sendPointerEvent({
|
|
429
|
-
container,
|
|
430
|
-
identifier: 1,
|
|
431
|
-
type: "pointerup",
|
|
432
|
-
x: 0,
|
|
433
|
-
y: 0,
|
|
434
|
-
})
|
|
435
|
-
sendPointerEvent({
|
|
436
|
-
container,
|
|
437
|
-
identifier: 2,
|
|
438
|
-
type: "pointerup",
|
|
439
|
-
x: 10,
|
|
440
|
-
y: 10,
|
|
441
|
-
})
|
|
442
|
-
})
|
|
443
|
-
},
|
|
444
|
-
}),
|
|
445
|
-
buffer(waitLongEnough$),
|
|
446
|
-
first(),
|
|
447
|
-
),
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
expect(values.length).toBe(0) // Assuming the recognizer should ignore simultaneous taps
|
|
451
|
-
})
|
|
452
|
-
|
|
453
|
-
it("should ignore one tap if there is more than one tap", async () => {
|
|
454
|
-
const recognizer = new TapRecognizer({
|
|
455
|
-
multiTapThreshold: 10,
|
|
456
|
-
maxTaps: 1,
|
|
457
|
-
})
|
|
458
|
-
recognizer.initialize({
|
|
459
|
-
container,
|
|
460
|
-
})
|
|
461
|
-
const waitLongEnough$ = timer(100)
|
|
462
|
-
|
|
463
|
-
const values = await lastValueFrom(
|
|
464
|
-
recognizer.events$.pipe(
|
|
465
|
-
tap({
|
|
466
|
-
subscribe: async () => {
|
|
467
|
-
await waitFor(1)
|
|
468
|
-
|
|
469
|
-
sendPointerEvent({
|
|
470
|
-
container,
|
|
471
|
-
identifier: 1,
|
|
472
|
-
type: "pointerdown",
|
|
473
|
-
x: 0,
|
|
474
|
-
y: 0,
|
|
475
|
-
})
|
|
476
|
-
sendPointerEvent({
|
|
477
|
-
container,
|
|
478
|
-
identifier: 1,
|
|
479
|
-
type: "pointerup",
|
|
480
|
-
x: 0,
|
|
481
|
-
y: 0,
|
|
482
|
-
})
|
|
483
|
-
|
|
484
|
-
await waitFor(1)
|
|
485
|
-
|
|
486
|
-
sendPointerEvent({
|
|
487
|
-
container,
|
|
488
|
-
identifier: 2,
|
|
489
|
-
type: "pointerdown",
|
|
490
|
-
x: 0,
|
|
491
|
-
y: 0,
|
|
492
|
-
})
|
|
493
|
-
sendPointerEvent({
|
|
494
|
-
container,
|
|
495
|
-
identifier: 2,
|
|
496
|
-
type: "pointerup",
|
|
497
|
-
x: 0,
|
|
498
|
-
y: 0,
|
|
499
|
-
})
|
|
500
|
-
},
|
|
501
|
-
}),
|
|
502
|
-
buffer(waitLongEnough$),
|
|
503
|
-
first(),
|
|
504
|
-
),
|
|
505
|
-
)
|
|
506
|
-
|
|
507
|
-
expect(values.length).toBe(0)
|
|
508
|
-
})
|
|
509
|
-
|
|
510
|
-
it("should ignore taps when a second tap is outside of position threshold", async () => {
|
|
511
|
-
const recognizer = new TapRecognizer({
|
|
512
|
-
posThreshold: 5,
|
|
513
|
-
multiTapThreshold: 10,
|
|
514
|
-
maxTaps: Infinity,
|
|
515
|
-
})
|
|
516
|
-
recognizer.initialize({
|
|
517
|
-
container,
|
|
518
|
-
})
|
|
519
|
-
const waitLongEnough$ = timer(100)
|
|
520
|
-
|
|
521
|
-
const values = await lastValueFrom(
|
|
522
|
-
recognizer.events$.pipe(
|
|
523
|
-
tap({
|
|
524
|
-
subscribe: async () => {
|
|
525
|
-
// await waitFor(1)
|
|
526
|
-
|
|
527
|
-
sendPointerEvent({
|
|
528
|
-
container,
|
|
529
|
-
identifier: 1,
|
|
530
|
-
type: "pointerdown",
|
|
531
|
-
x: 0,
|
|
532
|
-
y: 0,
|
|
533
|
-
})
|
|
534
|
-
sendPointerEvent({
|
|
535
|
-
container,
|
|
536
|
-
identifier: 1,
|
|
537
|
-
type: "pointerup",
|
|
538
|
-
x: 0,
|
|
539
|
-
y: 0,
|
|
540
|
-
})
|
|
541
|
-
|
|
542
|
-
// await waitFor(1)
|
|
543
|
-
|
|
544
|
-
sendPointerEvent({
|
|
545
|
-
container,
|
|
546
|
-
identifier: 2,
|
|
547
|
-
type: "pointerdown",
|
|
548
|
-
x: 10,
|
|
549
|
-
y: 10,
|
|
550
|
-
})
|
|
551
|
-
sendPointerEvent({
|
|
552
|
-
container,
|
|
553
|
-
identifier: 2,
|
|
554
|
-
type: "pointerup",
|
|
555
|
-
x: 10,
|
|
556
|
-
y: 10,
|
|
557
|
-
})
|
|
558
|
-
},
|
|
559
|
-
}),
|
|
560
|
-
buffer(waitLongEnough$),
|
|
561
|
-
first(),
|
|
562
|
-
),
|
|
563
|
-
)
|
|
564
|
-
|
|
565
|
-
expect(values.length).toBe(0)
|
|
566
|
-
})
|
|
567
|
-
})
|