@react-native-oh-tpl/react-native-gesture-handler 2.14.7 → 2.14.13
Sign up to get free protection for your applications and to get access to all the features.
- package/DrawerLayout/index.ts +2 -2
- package/Swipeable/index.ts +2 -2
- package/harmony/gesture_handler/BuildProfile.ets +17 -0
- package/harmony/gesture_handler/build-profile.json5 +19 -0
- package/harmony/gesture_handler/hvigorfile.ts +2 -0
- package/harmony/gesture_handler/index.ets +3 -0
- package/harmony/gesture_handler/oh-package-lock.json5 +18 -0
- package/harmony/gesture_handler/oh-package.json5 +12 -0
- package/harmony/gesture_handler/src/main/cpp/CMakeLists.txt +8 -0
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +149 -0
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +21 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonComponentDescriptor.h +36 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonJSIBinder.h +32 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.cpp +22 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.h +15 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentDescriptor.h +36 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +25 -0
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerButtonComponentInstance.h +27 -0
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +242 -0
- package/harmony/gesture_handler/src/main/ets/core/CircularBuffer.ts +42 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandler.ts +690 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerOrchestrator.ts +335 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +63 -0
- package/harmony/gesture_handler/src/main/ets/core/IncomingEvent.ts +78 -0
- package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
- package/harmony/gesture_handler/src/main/ets/core/LeastSquareSolver.ts +182 -0
- package/harmony/gesture_handler/src/main/ets/core/OutgoingEvent.ts +34 -0
- package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/core/PointerTracker.ts +239 -0
- package/harmony/gesture_handler/src/main/ets/core/RNGHError.ts +5 -0
- package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/core/State.ts +47 -0
- package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
- package/harmony/gesture_handler/src/main/ets/core/VelocityTracker.ts +106 -0
- package/harmony/gesture_handler/src/main/ets/core/View.ts +21 -0
- package/harmony/gesture_handler/src/main/ets/core/ViewFinder.ts +11 -0
- package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +8 -0
- package/harmony/gesture_handler/src/main/ets/core/index.ts +15 -0
- package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/NativeViewGestureHandler.ts +115 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +342 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/TapGestureHandler.ts +206 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
- package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +24 -0
- package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerButton.ts +139 -0
- package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerRootView.ts +101 -0
- package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
- package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerPackage.ts +22 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +98 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerButton.ets +38 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +233 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerRootView.ets +53 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +134 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +97 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/types.ts +25 -0
- package/harmony/gesture_handler/src/main/module.json5 +9 -0
- package/harmony/gesture_handler/src/main/resources/base/element/color.json +8 -0
- package/harmony/gesture_handler/src/main/resources/base/element/string.json +16 -0
- package/harmony/gesture_handler/src/main/resources/base/media/icon.png +0 -0
- package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -0
- package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +16 -0
- package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +16 -0
- package/harmony/gesture_handler/ts.ts +2 -0
- package/harmony/gesture_handler.har +0 -0
- package/lib/commonjs/RNGestureHandlerModule.js +3 -2
- package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/components/GestureHandlerRootView.js +3 -3
- package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
- package/lib/commonjs/handlers/createHandler.js +18 -15
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/index.js +36 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js +2 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js +3 -2
- package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js +3 -2
- package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
- package/lib/module/RNGestureHandlerModule.js.map +1 -1
- package/lib/module/components/GestureHandlerRootView.js.map +1 -1
- package/lib/module/handlers/createHandler.js +15 -12
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/index.js +5 -7
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
- package/lib/typescript/RNGestureHandlerModule.d.ts +2 -2
- package/lib/typescript/components/GestureHandlerRootView.d.ts +6 -6
- package/lib/typescript/handlers/createHandler.d.ts +11 -11
- package/lib/typescript/index.d.ts +47 -42
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +14 -14
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +14 -14
- package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +6 -6
- package/package.json +73 -72
- package/src/RNGestureHandlerModule.ts +4 -4
- package/src/components/GestureHandlerRootView.tsx +23 -23
- package/src/handlers/createHandler.tsx +534 -534
- package/src/index.ts +172 -172
- package/src/specs/NativeRNGestureHandlerModule.ts +26 -26
- package/src/specs/RNGestureHandlerButtonNativeComponent.ts +18 -18
- 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,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,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
|
+
}
|