@react-native-oh-tpl/react-native-gesture-handler 2.14.8-rc.1 → 2.14.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. package/DrawerLayout/index.ts +2 -2
  2. package/Swipeable/index.ts +2 -2
  3. package/harmony/gesture_handler/BuildProfile.ets +17 -0
  4. package/harmony/gesture_handler/build-profile.json5 +19 -0
  5. package/harmony/gesture_handler/hvigorfile.ts +2 -0
  6. package/harmony/gesture_handler/index.ets +2 -0
  7. package/harmony/gesture_handler/oh-package-lock.json5 +18 -0
  8. package/harmony/gesture_handler/oh-package.json5 +12 -0
  9. package/harmony/gesture_handler/src/main/cpp/CMakeLists.txt +8 -0
  10. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +12 -0
  11. package/harmony/gesture_handler/src/main/cpp/RnohReactNativeHarmonyGestureHandlerPackage.cpp +123 -0
  12. package/harmony/gesture_handler/src/main/cpp/RnohReactNativeHarmonyGestureHandlerPackage.h +15 -0
  13. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerButtonComponentInstance.h +27 -0
  14. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +245 -0
  15. package/harmony/gesture_handler/src/main/ets/RNOHPackage.ets +17 -0
  16. package/harmony/gesture_handler/src/main/ets/core/CircularBuffer.ts +42 -0
  17. package/harmony/gesture_handler/src/main/ets/core/GestureHandler.ts +739 -0
  18. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerOrchestrator.ts +344 -0
  19. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +63 -0
  20. package/harmony/gesture_handler/src/main/ets/core/IncomingEvent.ts +78 -0
  21. package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
  22. package/harmony/gesture_handler/src/main/ets/core/LeastSquareSolver.ts +182 -0
  23. package/harmony/gesture_handler/src/main/ets/core/Multiset.ts +26 -0
  24. package/harmony/gesture_handler/src/main/ets/core/OutgoingEvent.ts +34 -0
  25. package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
  26. package/harmony/gesture_handler/src/main/ets/core/PointerTracker.ts +239 -0
  27. package/harmony/gesture_handler/src/main/ets/core/RNGHError.ts +5 -0
  28. package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +16 -0
  29. package/harmony/gesture_handler/src/main/ets/core/State.ts +47 -0
  30. package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
  31. package/harmony/gesture_handler/src/main/ets/core/VelocityTracker.ts +106 -0
  32. package/harmony/gesture_handler/src/main/ets/core/View.ts +21 -0
  33. package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +7 -0
  34. package/harmony/gesture_handler/src/main/ets/core/index.ts +15 -0
  35. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  36. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +219 -0
  37. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +67 -0
  38. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +139 -0
  39. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +50 -0
  40. package/harmony/gesture_handler/src/main/ets/gesture-handlers/NativeViewGestureHandler.ts +124 -0
  41. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +361 -0
  42. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +174 -0
  43. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +172 -0
  44. package/harmony/gesture_handler/src/main/ets/gesture-handlers/TapGestureHandler.ts +216 -0
  45. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  46. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  47. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerPackage.ts +25 -0
  48. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +107 -0
  49. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +94 -0
  50. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootViewController.ts +182 -0
  51. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHView.ts +62 -0
  52. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHViewController.ts +262 -0
  53. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHViewRegistry.ts +19 -0
  54. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +267 -0
  55. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +15 -0
  56. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +25 -0
  57. package/harmony/gesture_handler/src/main/ets/rnoh/types.ts +25 -0
  58. package/harmony/gesture_handler/src/main/module.json5 +9 -0
  59. package/harmony/gesture_handler/src/main/resources/base/element/color.json +8 -0
  60. package/harmony/gesture_handler/src/main/resources/base/element/string.json +16 -0
  61. package/harmony/gesture_handler/src/main/resources/base/media/icon.png +0 -0
  62. package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -0
  63. package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +16 -0
  64. package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +16 -0
  65. package/harmony/gesture_handler/ts.ts +2 -0
  66. package/harmony/gesture_handler.har +0 -0
  67. package/lib/commonjs/RNGestureHandlerModule.js +3 -2
  68. package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
  69. package/lib/commonjs/components/GestureHandlerRootView.js +3 -3
  70. package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
  71. package/lib/commonjs/handlers/createHandler.js +18 -15
  72. package/lib/commonjs/handlers/createHandler.js.map +1 -1
  73. package/lib/commonjs/index.js +36 -8
  74. package/lib/commonjs/index.js.map +1 -1
  75. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js +2 -1
  76. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
  77. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js +3 -2
  78. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  79. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js +3 -2
  80. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  81. package/lib/module/RNGestureHandlerModule.js.map +1 -1
  82. package/lib/module/components/GestureHandlerRootView.js.map +1 -1
  83. package/lib/module/handlers/createHandler.js +15 -12
  84. package/lib/module/handlers/createHandler.js.map +1 -1
  85. package/lib/module/index.js +5 -7
  86. package/lib/module/index.js.map +1 -1
  87. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
  88. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  89. package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  90. package/lib/typescript/RNGestureHandlerModule.d.ts +2 -2
  91. package/lib/typescript/components/GestureHandlerRootView.d.ts +6 -6
  92. package/lib/typescript/handlers/createHandler.d.ts +11 -11
  93. package/lib/typescript/index.d.ts +47 -42
  94. package/lib/typescript/index.d.ts.map +1 -1
  95. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +14 -14
  96. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +14 -14
  97. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +6 -6
  98. package/package.json +78 -70
  99. package/src/RNGestureHandlerModule.ts +4 -4
  100. package/src/components/GestureHandlerRootView.tsx +23 -23
  101. package/src/handlers/createHandler.tsx +534 -534
  102. package/src/index.ts +172 -172
  103. package/src/specs/NativeRNGestureHandlerModule.ts +26 -26
  104. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +18 -18
  105. package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +6 -6
@@ -0,0 +1,182 @@
1
+ // Implementation taken from Flutter's LeastSquareSolver
2
+ // https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/gestures/lsq_solver.dart
3
+
4
+ class Vector {
5
+ private offset: number;
6
+ private length: number;
7
+ private elements: number[];
8
+
9
+ constructor(length: number) {
10
+ this.offset = 0;
11
+ this.length = length;
12
+ this.elements = new Array<number>(length);
13
+ }
14
+
15
+ public static fromVOL(
16
+ values: number[],
17
+ offset: number,
18
+ length: number
19
+ ): Vector {
20
+ const result = new Vector(0);
21
+
22
+ result.offset = offset;
23
+ result.length = length;
24
+ result.elements = values;
25
+
26
+ return result;
27
+ }
28
+
29
+ public get(index: number): number {
30
+ return this.elements[this.offset + index];
31
+ }
32
+
33
+ public set(index: number, value: number): void {
34
+ this.elements[this.offset + index] = value;
35
+ }
36
+
37
+ public dot(other: Vector): number {
38
+ let result = 0;
39
+ for (let i = 0; i < this.length; i++) {
40
+ result += this.get(i) * other.get(i);
41
+ }
42
+ return result;
43
+ }
44
+
45
+ public norm() {
46
+ return Math.sqrt(this.dot(this));
47
+ }
48
+ }
49
+
50
+ class Matrix {
51
+ private columns: number;
52
+ private elements: number[];
53
+
54
+ constructor(rows: number, columns: number) {
55
+ this.columns = columns;
56
+ this.elements = new Array<number>(rows * columns);
57
+ }
58
+
59
+ public get(row: number, column: number): number {
60
+ return this.elements[row * this.columns + column];
61
+ }
62
+
63
+ public set(row: number, column: number, value: number): void {
64
+ this.elements[row * this.columns + column] = value;
65
+ }
66
+
67
+ public getRow(row: number): Vector {
68
+ return Vector.fromVOL(this.elements, row * this.columns, this.columns);
69
+ }
70
+ }
71
+
72
+ /// An nth degree polynomial fit to a dataset.
73
+ class PolynomialFit {
74
+ /// The polynomial coefficients of the fit.
75
+ ///
76
+ /// For each `i`, the element `coefficients[i]` is the coefficient of
77
+ /// the `i`-th power of the variable.
78
+ public coefficients: number[];
79
+
80
+ /// Creates a polynomial fit of the given degree.
81
+ ///
82
+ /// There are n + 1 coefficients in a fit of degree n.
83
+ constructor(degree: number) {
84
+ this.coefficients = new Array<number>(degree + 1);
85
+ }
86
+ }
87
+
88
+ const precisionErrorTolerance = 1e-10;
89
+
90
+ /// Uses the least-squares algorithm to fit a polynomial to a set of data.
91
+ export class LeastSquareSolver {
92
+ /// The x-coordinates of each data point.
93
+ private x: number[];
94
+ /// The y-coordinates of each data point.
95
+ private y: number[];
96
+ /// The weight to use for each data point.
97
+ private w: number[];
98
+
99
+ /// Creates a least-squares solver.
100
+ ///
101
+ /// The [x], [y], and [w] arguments must not be null.
102
+ constructor(x: number[], y: number[], w: number[]) {
103
+ this.x = x;
104
+ this.y = y;
105
+ this.w = w;
106
+ }
107
+
108
+ /// Fits a polynomial of the given degree to the data points.
109
+ ///
110
+ /// When there is not enough data to fit a curve null is returned.
111
+ public solve(degree: number): PolynomialFit | null {
112
+ if (degree > this.x.length) {
113
+ // Not enough data to fit a curve.
114
+ return null;
115
+ }
116
+
117
+ const result = new PolynomialFit(degree);
118
+
119
+ // Shorthands for the purpose of notation equivalence to original C++ code.
120
+ const m = this.x.length;
121
+ const n = degree + 1;
122
+
123
+ // Expand the X vector to a matrix A, pre-multiplied by the weights.
124
+ const a = new Matrix(n, m);
125
+ for (let h = 0; h < m; h++) {
126
+ a.set(0, h, this.w[h]);
127
+
128
+ for (let i = 1; i < n; i++) {
129
+ a.set(i, h, a.get(i - 1, h) * this.x[h]);
130
+ }
131
+ }
132
+
133
+ // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
134
+
135
+ // Orthonormal basis, column-major ordVectorer.
136
+ const q = new Matrix(n, m);
137
+ // Upper triangular matrix, row-major order.
138
+ const r = new Matrix(n, m);
139
+
140
+ for (let j = 0; j < n; j += 1) {
141
+ for (let h = 0; h < m; h += 1) {
142
+ q.set(j, h, a.get(j, h));
143
+ }
144
+ for (let i = 0; i < j; i += 1) {
145
+ const dot = q.getRow(j).dot(q.getRow(i));
146
+ for (let h = 0; h < m; h += 1) {
147
+ q.set(j, h, q.get(j, h) - dot * q.get(i, h));
148
+ }
149
+ }
150
+
151
+ const norm = q.getRow(j).norm();
152
+ if (norm < precisionErrorTolerance) {
153
+ // Vectors are linearly dependent or zero so no solution.
154
+ return null;
155
+ }
156
+
157
+ const inverseNorm = 1.0 / norm;
158
+ for (let h = 0; h < m; h += 1) {
159
+ q.set(j, h, q.get(j, h) * inverseNorm);
160
+ }
161
+ for (let i = 0; i < n; i += 1) {
162
+ r.set(j, i, i < j ? 0.0 : q.getRow(j).dot(a.getRow(i)));
163
+ }
164
+ }
165
+
166
+ // Solve R B = Qt W Y to find B. This is easy because R is upper triangular.
167
+ // We just work from bottom-right to top-left calculating B's coefficients.
168
+ const wy = new Vector(m);
169
+ for (let h = 0; h < m; h += 1) {
170
+ wy.set(h, this.y[h] * this.w[h]);
171
+ }
172
+ for (let i = n - 1; i >= 0; i -= 1) {
173
+ result.coefficients[i] = q.getRow(i).dot(wy);
174
+ for (let j = n - 1; j > i; j -= 1) {
175
+ result.coefficients[i] -= r.get(i, j) * result.coefficients[j];
176
+ }
177
+ result.coefficients[i] /= r.get(i, i);
178
+ }
179
+
180
+ return result;
181
+ }
182
+ }
@@ -0,0 +1,26 @@
1
+ export class Multiset<T> {
2
+ private multiplicityByElement: Map<T, number> = new Map();
3
+ private elements: T[] = [];
4
+
5
+ add(element: T) {
6
+ const count = this.multiplicityByElement.get(element) || 0;
7
+ if (count === 0) {
8
+ this.elements.push(element);
9
+ }
10
+ this.multiplicityByElement.set(element, count + 1);
11
+ }
12
+
13
+ remove(element: T) {
14
+ const count = this.multiplicityByElement.get(element) || 0;
15
+ if (count > 1) {
16
+ this.multiplicityByElement.set(element, count - 1);
17
+ } else {
18
+ this.multiplicityByElement.delete(element);
19
+ this.elements = this.elements.filter(v => v !== element);
20
+ }
21
+ }
22
+
23
+ getElements() {
24
+ return this.elements;
25
+ }
26
+ }
@@ -0,0 +1,34 @@
1
+ import { State } from "./State"
2
+ import { TouchEventType } from "./IncomingEvent"
3
+
4
+ export interface GestureEventPayload {
5
+ handlerTag: number;
6
+ numberOfPointers: number;
7
+ state: State;
8
+ }
9
+
10
+ export interface HandlerStateChangeEventPayload extends GestureEventPayload {
11
+ oldState: State;
12
+ }
13
+
14
+ export type GestureUpdateEvent<GestureEventPayloadT = Record<string, unknown>> = GestureEventPayload
15
+ & GestureEventPayloadT
16
+
17
+ export type GestureStateChangeEvent<GestureStateChangeEventPayloadT = Record<string, unknown>> = HandlerStateChangeEventPayload & GestureStateChangeEventPayloadT
18
+
19
+ export type TouchData = {
20
+ id: number;
21
+ x: number;
22
+ y: number;
23
+ absoluteX: number;
24
+ absoluteY: number;
25
+ };
26
+
27
+ export type GestureTouchEvent = {
28
+ handlerTag: number;
29
+ numberOfTouches: number;
30
+ state: State;
31
+ eventType: TouchEventType;
32
+ allTouches: TouchData[];
33
+ changedTouches: TouchData[];
34
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ GestureStateChangeEvent,
3
+ GestureUpdateEvent,
4
+ GestureTouchEvent,
5
+ } from './OutgoingEvent';
6
+
7
+ export interface OutgoingEventDispatcher {
8
+ onGestureHandlerStateChange(event: GestureStateChangeEvent): void;
9
+ onGestureHandlerEvent(
10
+ event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
11
+ ): void;
12
+ }
@@ -0,0 +1,239 @@
1
+ import { VelocityTracker, TrackerElement } from './VelocityTracker';
2
+ import { IncomingEvent } from "./IncomingEvent"
3
+ import { Vector2D } from './Vector2D';
4
+
5
+ const MAX_POINTERS = 20;
6
+
7
+ export class PointerTracker {
8
+ private velocityTracker = new VelocityTracker();
9
+ private trackedPointers: Map<number, TrackerElement> = new Map<
10
+ number,
11
+ TrackerElement
12
+ >();
13
+
14
+ private touchEventsIds: Map<number, number> = new Map<number, number>();
15
+
16
+ private lastMovedPointerId: number;
17
+
18
+ private cachedAverages: { x: number; y: number } = { x: 0, y: 0 };
19
+
20
+ public constructor() {
21
+ this.lastMovedPointerId = NaN;
22
+
23
+ for (let i = 0; i < MAX_POINTERS; ++i) {
24
+ this.touchEventsIds.set(i, NaN);
25
+ }
26
+ }
27
+
28
+ public addToTracker(event: IncomingEvent): void {
29
+ if (this.trackedPointers.has(event.pointerId)) {
30
+ return;
31
+ }
32
+
33
+ this.lastMovedPointerId = event.pointerId;
34
+
35
+ const newElement: TrackerElement = {
36
+ lastX: event.x,
37
+ lastY: event.y,
38
+ timeStamp: event.time,
39
+ velocityX: 0,
40
+ velocityY: 0,
41
+ };
42
+
43
+ this.trackedPointers.set(event.pointerId, newElement);
44
+ this.mapTouchEventId(event.pointerId);
45
+
46
+ this.cachedAverages = {
47
+ x: this.getLastAvgX(),
48
+ y: this.getLastAvgY(),
49
+ };
50
+ }
51
+
52
+ public removeFromTracker(pointerId: number): void {
53
+ this.trackedPointers.delete(pointerId);
54
+ this.removeMappedTouchId(pointerId);
55
+ }
56
+
57
+ public track(event: IncomingEvent): void {
58
+ const element: TrackerElement = this.trackedPointers.get(
59
+ event.pointerId
60
+ ) as TrackerElement;
61
+
62
+ if (!element) {
63
+ return;
64
+ }
65
+
66
+ this.lastMovedPointerId = event.pointerId;
67
+
68
+ this.velocityTracker.add(event);
69
+ const [velocityX, velocityY] = this.velocityTracker.getVelocity();
70
+
71
+ element.velocityX = velocityX;
72
+ element.velocityY = velocityY;
73
+
74
+ element.lastX = event.x;
75
+ element.lastY = event.y;
76
+
77
+ this.trackedPointers.set(event.pointerId, element);
78
+
79
+ const avgX: number = this.getLastAvgX();
80
+ const avgY: number = this.getLastAvgY();
81
+
82
+ this.cachedAverages = {
83
+ x: avgX,
84
+ y: avgY,
85
+ };
86
+ }
87
+
88
+ //Mapping TouchEvents ID
89
+ private mapTouchEventId(id: number): void {
90
+ for (const [mappedId, touchId] of this.touchEventsIds) {
91
+ if (isNaN(touchId)) {
92
+ this.touchEventsIds.set(mappedId, id);
93
+ break;
94
+ }
95
+ }
96
+ }
97
+
98
+ private removeMappedTouchId(id: number): void {
99
+ const mappedId: number = this.getMappedTouchEventId(id);
100
+ if (!isNaN(mappedId)) {
101
+ this.touchEventsIds.set(mappedId, NaN);
102
+ }
103
+ }
104
+
105
+ public getMappedTouchEventId(touchEventId: number): number {
106
+ for (const [key, value] of this.touchEventsIds.entries()) {
107
+ if (value === touchEventId) {
108
+ return key;
109
+ }
110
+ }
111
+
112
+ return NaN;
113
+ }
114
+
115
+ public getVelocity(pointerId: number) {
116
+ return new Vector2D({x: this.getVelocityX(pointerId), y: this.getVelocityY(pointerId)})
117
+ }
118
+
119
+ public getVelocityX(pointerId: number): number {
120
+ return this.trackedPointers.get(pointerId)?.velocityX as number;
121
+ }
122
+ public getVelocityY(pointerId: number): number {
123
+ return this.trackedPointers.get(pointerId)?.velocityY as number;
124
+ }
125
+
126
+ /**
127
+ * Returns X coordinate of last moved pointer
128
+ */
129
+ public getLastX(): number;
130
+
131
+ /**
132
+ *
133
+ * @param pointerId
134
+ * Returns X coordinate of given pointer
135
+ */
136
+ // eslint-disable-next-line @typescript-eslint/unified-signatures
137
+ public getLastX(pointerId: number): number;
138
+
139
+ public getLastX(pointerId?: number): number {
140
+ if (pointerId !== undefined) {
141
+ return this.trackedPointers.get(pointerId)?.lastX as number;
142
+ } else {
143
+ return this.trackedPointers.get(this.lastMovedPointerId)?.lastX as number;
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Returns Y coordinate of last moved pointer
149
+ */
150
+ public getLastY(): number;
151
+
152
+ /**
153
+ *
154
+ * @param pointerId
155
+ * Returns Y coordinate of given pointer
156
+ */
157
+ // eslint-disable-next-line @typescript-eslint/unified-signatures
158
+ public getLastY(pointerId: number): number;
159
+
160
+ public getLastY(pointerId?: number): number {
161
+ if (pointerId !== undefined) {
162
+ return this.trackedPointers.get(pointerId)?.lastY as number;
163
+ } else {
164
+ return this.trackedPointers.get(this.lastMovedPointerId)?.lastY as number;
165
+ }
166
+ }
167
+
168
+ public getLastAvgPos() {
169
+ return new Vector2D({x: this.getLastAvgX(), y: this.getLastAvgY()})
170
+ }
171
+
172
+ // Some handlers use these methods to send average values in native event.
173
+ // This may happen when pointers have already been removed from tracker (i.e. pointerup event).
174
+ // In situation when NaN would be sent as a response, we return cached value.
175
+ // That prevents handlers from crashing
176
+ public getLastAvgX(): number {
177
+ const avgX: number = this.getSumX() / this.trackedPointers.size;
178
+ return isNaN(avgX) ? this.cachedAverages.x : avgX;
179
+ }
180
+ public getLastAvgY(): number {
181
+ const avgY: number = this.getSumY() / this.trackedPointers.size;
182
+ return isNaN(avgY) ? this.cachedAverages.y : avgY;
183
+ }
184
+ public getSumX(ignoredPointer?: number): number {
185
+ let sumX = 0;
186
+
187
+ this.trackedPointers.forEach((value, key) => {
188
+ if (key !== ignoredPointer) {
189
+ sumX += value.lastX;
190
+ }
191
+ });
192
+
193
+ return sumX;
194
+ }
195
+ public getSumY(ignoredPointer?: number): number {
196
+ let sumY = 0;
197
+
198
+ this.trackedPointers.forEach((value, key) => {
199
+ if (key !== ignoredPointer) {
200
+ sumY += value.lastY;
201
+ }
202
+ });
203
+
204
+ return sumY;
205
+ }
206
+ public getTrackedPointersCount(): number {
207
+ return this.trackedPointers.size;
208
+ }
209
+ public getTrackedPointersID(): number[] {
210
+ const keys: number[] = [];
211
+
212
+ this.trackedPointers.forEach((_value, key) => {
213
+ keys.push(key);
214
+ });
215
+
216
+ return keys;
217
+ }
218
+
219
+ public getData(): Map<number, TrackerElement> {
220
+ return this.trackedPointers;
221
+ }
222
+
223
+ public resetTracker(): void {
224
+ this.velocityTracker.reset();
225
+ this.trackedPointers.clear();
226
+ this.lastMovedPointerId = NaN;
227
+
228
+ for (let i = 0; i < MAX_POINTERS; ++i) {
229
+ this.touchEventsIds.set(i, NaN);
230
+ }
231
+ }
232
+
233
+ public static shareCommonPointers(
234
+ stPointers: number[],
235
+ ndPointers: number[]
236
+ ): boolean {
237
+ return stPointers.some((pointerId) => ndPointers.includes(pointerId));
238
+ }
239
+ }
@@ -0,0 +1,5 @@
1
+ export class RNGHError extends Error {
2
+ constructor(message: string) {
3
+ super("rnoh-gesture-handler: " + message)
4
+ }
5
+ }
@@ -0,0 +1,16 @@
1
+ export type RNGHLoggerMessage = string | Object
2
+
3
+ export interface RNGHLogger {
4
+ cloneAndJoinPrefix(prefix: string): RNGHLogger;
5
+
6
+ debug(msg: RNGHLoggerMessage);
7
+
8
+ info(msg: string): void;
9
+
10
+ warn(warn: string);
11
+
12
+ error(msg: string);
13
+
14
+ startTracing(): () => void
15
+ }
16
+
@@ -0,0 +1,47 @@
1
+ export enum State {
2
+ /** This is the initial state of each handler and it goes into this state after it's done recognizing a gesture. */
3
+ UNDETERMINED,
4
+
5
+ /** A handler received some touches but for some reason didn't recognize them. For example, if a finger travels more
6
+ * distance than a defined maxDist property allows, then the handler won't become active but will fail instead.
7
+ * Afterwards, it's state will be reset to UNDETERMINED. */
8
+ FAILED,
9
+
10
+ /** Handler has started receiving touch stream but hasn't yet received enough data to either fail or activate. */
11
+ BEGAN,
12
+
13
+ /** The gesture recognizer has received a signal (possibly new touches or a command from the touch system controller)
14
+ * resulting in the cancellation of a continuous gesture. The gesture's state will become CANCELLED until it is
15
+ * finally reset to the initial state, UNDETERMINED. */
16
+ CANCELLED,
17
+
18
+ /** Handler has recognized a gesture. It will become and stay in the ACTIVE state until the gesture finishes
19
+ * (e.g. when user lifts the finger) or gets cancelled by the touch system. Under normal circumstances the state will
20
+ * then turn into END. In the case that a gesture is cancelled by the touch system, its state would then become
21
+ * CANCELLED. Learn about discrete and continuous handlers here to understand how long a handler can be kept in the
22
+ * ACTIVE state.
23
+ * */
24
+ ACTIVE,
25
+
26
+ /** The gesture recognizer has received touches signalling the end of a gesture. Its state will become END until it is
27
+ * reset to UNDETERMINED.
28
+ * */
29
+ END,
30
+ }
31
+
32
+ export function getStateName(state: State): string {
33
+ switch (state) {
34
+ case State.UNDETERMINED:
35
+ return "UNDETERMINED"
36
+ case State.FAILED:
37
+ return "FAILED"
38
+ case State.BEGAN:
39
+ return "BEGAN"
40
+ case State.CANCELLED:
41
+ return "CANCELLED"
42
+ case State.ACTIVE:
43
+ return "ACTIVE"
44
+ case State.END:
45
+ return "END"
46
+ }
47
+ }
@@ -0,0 +1,80 @@
1
+ import { Directions, DiagonalDirections } from "./IncomingEvent"
2
+
3
+ type Cosine = number
4
+
5
+ export class Vector2D {
6
+ private static VECTOR_BY_DIRECTION = new Map<
7
+ Directions | DiagonalDirections,
8
+ Vector2D
9
+ >([
10
+ [Directions.LEFT, new Vector2D({ x: -1, y: 0 })],
11
+ [Directions.RIGHT, new Vector2D({ x: 1, y: 0 })],
12
+ [Directions.UP, new Vector2D({ x: 0, y: -1 })],
13
+ [Directions.DOWN, new Vector2D({ x: 0, y: 1 })],
14
+ [DiagonalDirections.UP_RIGHT, new Vector2D({ x: 1, y: -1 })],
15
+ [DiagonalDirections.DOWN_RIGHT, new Vector2D({ x: 1, y: 1 })],
16
+ [DiagonalDirections.UP_LEFT, new Vector2D({ x: -1, y: -1 })],
17
+ [DiagonalDirections.DOWN_LEFT, new Vector2D({ x: -1, y: 1 })],
18
+ ]);
19
+
20
+ static fromDirection(direction: Directions | DiagonalDirections): Vector2D {
21
+ return Vector2D.VECTOR_BY_DIRECTION.get(direction)!;
22
+ }
23
+
24
+
25
+ constructor(
26
+ private val: {
27
+ x: number;
28
+ y: number;
29
+ } = {x: 0, y: 0},
30
+ ) {}
31
+
32
+ get x() {
33
+ return this.val.x;
34
+ }
35
+
36
+ get y() {
37
+ return this.val.y;
38
+ }
39
+
40
+ get value() {
41
+ return {...this.val};
42
+ }
43
+
44
+ public clone() {
45
+ return new Vector2D({...this.val});
46
+ }
47
+
48
+ public subtract(vec: Vector2D) {
49
+ this.val.x -= vec.x;
50
+ this.val.y -= vec.y;
51
+ return this;
52
+ }
53
+
54
+ public add(vec: Vector2D) {
55
+ this.val.x += vec.x;
56
+ this.val.y += vec.y;
57
+ return this;
58
+ }
59
+
60
+ public createUnitVector(): Vector2D {
61
+ const magnitude = this.magnitude
62
+ if (magnitude === 0) {
63
+ return new Vector2D({ x: 0, y: 0 });
64
+ }
65
+ return new Vector2D({
66
+ x: this.val.x / magnitude,
67
+ y: this.val.y / magnitude
68
+ });
69
+ }
70
+
71
+ public computeCosine(other: Vector2D): Cosine {
72
+ const thisUnit = this.createUnitVector();
73
+ const otherUnit = other.createUnitVector();
74
+ return thisUnit.val.x * otherUnit.val.x + thisUnit.val.y * otherUnit.val.y;
75
+ }
76
+
77
+ public get magnitude() {
78
+ return Math.hypot(this.x, this.y);
79
+ }
80
+ }