gesturx 0.0.0 → 1.0.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/src/core/utils.ts DELETED
@@ -1,211 +0,0 @@
1
- import {
2
- NEVER,
3
- Observable,
4
- defer,
5
- endWith,
6
- filter,
7
- fromEvent,
8
- map,
9
- merge,
10
- mergeMap,
11
- of,
12
- scan,
13
- takeUntil,
14
- } from "rxjs";
15
-
16
- export function isDefined<T>(
17
- arg: T | null | undefined,
18
- ): arg is T extends null | undefined ? never : T {
19
- return arg !== null && arg !== undefined;
20
- }
21
-
22
- export const hasAtLeastOneItem = <T>(events: T[]): events is [T, ...T[]] =>
23
- events.length > 0;
24
-
25
- export const getCenterFromEvent = (
26
- event: MouseEvent | TouchEvent | PointerEvent,
27
- ) => ({
28
- x:
29
- "changedTouches" in event
30
- ? event.changedTouches[0]?.pageX ?? 0
31
- : event.clientX,
32
- y:
33
- "changedTouches" in event
34
- ? event.changedTouches[0]?.pageY ?? 0
35
- : event.clientY,
36
- });
37
-
38
- export function isOUtsidePosThreshold(
39
- startEvent: PointerEvent,
40
- endEvent: PointerEvent,
41
- posThreshold: number,
42
- ) {
43
- const start = getCenterFromEvent(startEvent);
44
- const end = getCenterFromEvent(endEvent);
45
-
46
- // Determines if the movement qualifies as a drag
47
- return (
48
- Math.abs(end.x - start.x) > posThreshold ||
49
- Math.abs(end.y - start.y) > posThreshold
50
- );
51
- }
52
-
53
- export function calculateDistance(pointA: PointerEvent, pointB: PointerEvent) {
54
- const dx = pointA.clientX - pointB.clientX;
55
- const dy = pointA.clientY - pointB.clientY;
56
-
57
- return Math.sqrt(dx * dx + dy * dy);
58
- }
59
-
60
- export const fromFailWith = (failWith?: { start$: Observable<unknown> }[]) =>
61
- !failWith?.length
62
- ? NEVER
63
- : merge(...(failWith?.map(({ start$ }) => start$) ?? []));
64
-
65
- export function matchPointer(pointer: PointerEvent) {
66
- return (stream: Observable<PointerEvent>) =>
67
- stream.pipe(
68
- filter((newPointer) => newPointer.pointerId === pointer.pointerId),
69
- );
70
- }
71
-
72
- export const getPointerEvents = ({
73
- container,
74
- afterEventReceived = (event) => event,
75
- }: {
76
- container: HTMLElement;
77
- afterEventReceived?: (event: PointerEvent) => PointerEvent;
78
- }) => {
79
- const pointerDown$ = fromPointerDown({ afterEventReceived, container });
80
- const pointerUp$ = fromEvent<PointerEvent>(container, "pointerup").pipe(
81
- map(afterEventReceived),
82
- );
83
- const pointerMove$ = fromEvent<PointerEvent>(container, "pointermove").pipe(
84
- map(afterEventReceived),
85
- );
86
- /**
87
- * Mostly used to handle cursor leaving window on mouse pointers.
88
- */
89
- const pointerLeave$ = fromEvent<PointerEvent>(container, "pointerleave").pipe(
90
- map(afterEventReceived),
91
- );
92
- /**
93
- * Handle things such as contextual menu popup or
94
- * native swipe navigation conflict.
95
- */
96
- const pointerCancel$ = fromEvent<PointerEvent>(
97
- container,
98
- "pointercancel",
99
- ).pipe(map(afterEventReceived));
100
-
101
- return {
102
- pointerDown$,
103
- pointerCancel$,
104
- pointerLeave$,
105
- pointerUp$,
106
- pointerMove$,
107
- };
108
- };
109
-
110
- export const fromPointerDown = ({
111
- container,
112
- afterEventReceived = (event) => event,
113
- }: {
114
- container: HTMLElement;
115
- afterEventReceived?: (event: PointerEvent) => PointerEvent;
116
- }) =>
117
- fromEvent<PointerEvent>(container, "pointerdown").pipe(
118
- map(afterEventReceived),
119
- );
120
-
121
- export const enrichEvent = ({
122
- event,
123
- startTime,
124
- startEvent,
125
- }: {
126
- event: PointerEvent;
127
- startTime: number;
128
- startEvent: PointerEvent;
129
- }) => {
130
- const startX = startEvent.clientX;
131
- const startY = startEvent.clientY;
132
- const deltaX = event.clientX - startX;
133
- const deltaY = event.clientY - startY;
134
-
135
- // Calculate the change in time
136
- const dt = Date.now() - startTime;
137
-
138
- // Avoid division by zero
139
- // Calculate velocity in pixels per second
140
- const velocityX = dt > 0 ? deltaX / dt : 0;
141
- const velocityY = dt > 0 ? deltaY / dt : 0;
142
-
143
- return {
144
- srcEvent: event,
145
- deltaX,
146
- deltaY,
147
- velocityX,
148
- velocityY,
149
- delay: new Date().getTime() - startTime,
150
- center: {
151
- x: event.x,
152
- y: event.y,
153
- },
154
- };
155
- };
156
-
157
- /**
158
- * @todo test the strict stability
159
- * @important
160
- * Stable function, will not emit if the pointers don't change
161
- */
162
- export const trackActivePointers = ({
163
- container,
164
- }: {
165
- container: HTMLElement;
166
- }) => {
167
- const pointerUp$ = fromEvent<PointerEvent>(container, "pointerup");
168
- // const pointerMove$ = fromEvent<PointerEvent>(container, "pointermove")
169
- const pointerLeave$ = fromEvent<PointerEvent>(container, "pointerleave");
170
- const pointerCancel$ = fromEvent<PointerEvent>(container, "pointercancel");
171
-
172
- return fromEvent<PointerEvent>(container, "pointerdown").pipe(
173
- mergeMap((pointerDown) => {
174
- const pointerDownRelease$ = merge(
175
- pointerUp$,
176
- pointerLeave$,
177
- pointerCancel$,
178
- ).pipe(matchPointer(pointerDown));
179
- const pointerDown$ = defer(() => of(pointerDown));
180
- // const currentPointerMove$ = pointerMove$.pipe(
181
- // filter((pointerMoveEvent) => matchPointer(pointerMoveEvent, pointerDown)),
182
- // throttleTime(100, undefined, { trailing: true }),
183
- // )
184
-
185
- return pointerDown$.pipe(
186
- // mergeMap(() => merge(pointerDown$, currentPointerMove$)),
187
- mergeMap(() => merge(pointerDown$, NEVER)),
188
- map((event) => ({ id: event.pointerId, event })),
189
- takeUntil(pointerDownRelease$),
190
- endWith({ id: pointerDown.pointerId, event: undefined }),
191
- );
192
- }),
193
- scan(
194
- (acc, { event, id }) => {
195
- if (!event) {
196
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
197
- const { [id]: _deleted, ...rest } = acc;
198
-
199
- return rest;
200
- }
201
-
202
- return {
203
- ...acc,
204
- [id]: event,
205
- };
206
- },
207
- {} as Record<number, PointerEvent | undefined>,
208
- ),
209
- map((events) => Object.values(events).filter(isDefined)),
210
- );
211
- };
package/src/main.ts DELETED
@@ -1,19 +0,0 @@
1
- import { createManager } from "./core/manager";
2
- import { createTapRecognizer } from "./core/tapRecognizer";
3
- import "./style.css";
4
-
5
- const container = document.querySelector<HTMLDivElement>("#app")!;
6
-
7
- const tapRecognizer = createTapRecognizer({ maxTaps: 3 });
8
-
9
- const manager = createManager({
10
- container,
11
- recognizers: [tapRecognizer],
12
- });
13
-
14
- manager.events$.subscribe(console.warn);
15
-
16
- container.innerHTML = `
17
- <div class="container">
18
- </div>
19
- `;
package/src/style.css DELETED
@@ -1,29 +0,0 @@
1
- :root {
2
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3
- line-height: 1.5;
4
- font-weight: 400;
5
-
6
- color-scheme: light dark;
7
- color: rgba(255, 255, 255, 0.87);
8
- background-color: #242424;
9
-
10
- font-synthesis: none;
11
- text-rendering: optimizeLegibility;
12
- -webkit-font-smoothing: antialiased;
13
- -moz-osx-font-smoothing: grayscale;
14
- }
15
-
16
- body {
17
- margin: 0;
18
- display: flex;
19
- min-width: 100vw;
20
- min-height: 100vh;
21
- }
22
-
23
- #app {
24
- display: flex;
25
- padding: 2rem;
26
- justify-content: center;
27
- align-items: center;
28
- flex: 1;
29
- }