@react-native-oh-tpl/react-native-gesture-handler 2.14.1-2.14.8 → 2.14.1-2.14.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) 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 +3 -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.cpp +149 -0
  11. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +21 -0
  12. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonComponentDescriptor.h +36 -0
  13. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonJSIBinder.h +32 -0
  14. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.cpp +22 -0
  15. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.h +15 -0
  16. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentDescriptor.h +36 -0
  17. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +25 -0
  18. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerButtonComponentInstance.h +27 -0
  19. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +234 -0
  20. package/harmony/gesture_handler/src/main/ets/core/CircularBuffer.ts +42 -0
  21. package/harmony/gesture_handler/src/main/ets/core/GestureHandler.ts +684 -0
  22. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerOrchestrator.ts +335 -0
  23. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +35 -0
  24. package/harmony/gesture_handler/src/main/ets/core/IncomingEvent.ts +78 -0
  25. package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
  26. package/harmony/gesture_handler/src/main/ets/core/LeastSquareSolver.ts +182 -0
  27. package/harmony/gesture_handler/src/main/ets/core/OutgoingEvent.ts +34 -0
  28. package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
  29. package/harmony/gesture_handler/src/main/ets/core/PointerTracker.ts +239 -0
  30. package/harmony/gesture_handler/src/main/ets/core/RNGHError.ts +5 -0
  31. package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
  32. package/harmony/gesture_handler/src/main/ets/core/State.ts +47 -0
  33. package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
  34. package/harmony/gesture_handler/src/main/ets/core/VelocityTracker.ts +106 -0
  35. package/harmony/gesture_handler/src/main/ets/core/View.ts +19 -0
  36. package/harmony/gesture_handler/src/main/ets/core/index.ts +13 -0
  37. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  38. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
  39. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
  40. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
  41. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
  42. package/harmony/gesture_handler/src/main/ets/gesture-handlers/NativeViewGestureHandler.ts +113 -0
  43. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +342 -0
  44. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
  45. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
  46. package/harmony/gesture_handler/src/main/ets/gesture-handlers/TapGestureHandler.ts +206 -0
  47. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  48. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  49. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +24 -0
  50. package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerButton.ts +139 -0
  51. package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerRootView.ts +101 -0
  52. package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
  53. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -0
  54. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
  55. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerPackage.ts +22 -0
  56. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
  57. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
  58. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +104 -0
  59. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
  60. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerButton.ets +38 -0
  61. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +230 -0
  62. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerRootView.ets +53 -0
  63. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
  64. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
  65. package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +119 -0
  66. package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +95 -0
  67. package/harmony/gesture_handler/src/main/ets/rnoh/types.ts +25 -0
  68. package/harmony/gesture_handler/src/main/module.json5 +9 -0
  69. package/harmony/gesture_handler/src/main/resources/base/element/color.json +8 -0
  70. package/harmony/gesture_handler/src/main/resources/base/element/string.json +16 -0
  71. package/harmony/gesture_handler/src/main/resources/base/media/icon.png +0 -0
  72. package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -0
  73. package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +16 -0
  74. package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +16 -0
  75. package/harmony/gesture_handler/ts.ts +2 -0
  76. package/harmony/gesture_handler.har +0 -0
  77. package/lib/commonjs/RNGestureHandlerModule.js +3 -2
  78. package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
  79. package/lib/commonjs/components/GestureHandlerRootView.js +3 -3
  80. package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
  81. package/lib/commonjs/handlers/createHandler.js +18 -15
  82. package/lib/commonjs/handlers/createHandler.js.map +1 -1
  83. package/lib/commonjs/index.js +8 -5
  84. package/lib/commonjs/index.js.map +1 -1
  85. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js +2 -1
  86. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
  87. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js +3 -2
  88. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  89. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js +3 -2
  90. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  91. package/lib/module/RNGestureHandlerModule.js.map +1 -1
  92. package/lib/module/components/GestureHandlerRootView.js.map +1 -1
  93. package/lib/module/handlers/createHandler.js +15 -12
  94. package/lib/module/handlers/createHandler.js.map +1 -1
  95. package/lib/module/index.js +1 -3
  96. package/lib/module/index.js.map +1 -1
  97. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
  98. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  99. package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  100. package/lib/typescript/RNGestureHandlerModule.d.ts +2 -2
  101. package/lib/typescript/components/GestureHandlerRootView.d.ts +6 -6
  102. package/lib/typescript/handlers/createHandler.d.ts +11 -11
  103. package/lib/typescript/index.d.ts +43 -42
  104. package/lib/typescript/index.d.ts.map +1 -1
  105. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +14 -14
  106. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +14 -14
  107. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +6 -6
  108. package/package.json +68 -69
  109. package/src/RNGestureHandlerModule.ts +4 -4
  110. package/src/components/GestureHandlerRootView.tsx +23 -23
  111. package/src/handlers/createHandler.tsx +534 -534
  112. package/src/index.ts +172 -172
  113. package/src/specs/NativeRNGestureHandlerModule.ts +26 -26
  114. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +18 -18
  115. package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +6 -6
@@ -0,0 +1,106 @@
1
+ import { IncomingEvent } from './IncomingEvent';
2
+ import { CircularBuffer } from './CircularBuffer';
3
+ import { LeastSquareSolver } from './LeastSquareSolver';
4
+
5
+ export interface TrackerElement {
6
+ lastX: number;
7
+ lastY: number;
8
+ timeStamp: number;
9
+ velocityX: number;
10
+ velocityY: number;
11
+ }
12
+
13
+ export class VelocityTracker {
14
+ private assumePointerMoveStoppedMilliseconds = 40;
15
+ private historySize = 20;
16
+ private horizonMilliseconds = 300;
17
+ private minSampleSize = 3;
18
+
19
+ private samples: CircularBuffer<IncomingEvent>;
20
+
21
+ constructor() {
22
+ this.samples = new CircularBuffer<IncomingEvent>(this.historySize);
23
+ }
24
+
25
+ public add(event: IncomingEvent): void {
26
+ this.samples.push(event);
27
+ }
28
+
29
+ /// Returns an estimate of the velocity of the object being tracked by the
30
+ /// tracker given the current information available to the tracker.
31
+ ///
32
+ /// Information is added using [addPosition].
33
+ ///
34
+ /// Returns null if there is no data on which to base an estimate.
35
+ private getVelocityEstimate(): [number, number] | null {
36
+ const x = [];
37
+ const y = [];
38
+ const w = [];
39
+ const time = [];
40
+
41
+ let sampleCount = 0;
42
+ let index = this.samples.size - 1;
43
+ const newestSample = this.samples.get(index);
44
+ if (!newestSample) {
45
+ return null;
46
+ }
47
+
48
+ let previousSample = newestSample;
49
+
50
+ // Starting with the most recent PointAtTime sample, iterate backwards while
51
+ // the samples represent continuous motion.
52
+ while (sampleCount < this.samples.size) {
53
+ const sample = this.samples.get(index);
54
+
55
+ const age = newestSample.time - sample.time;
56
+ const delta = Math.abs(sample.time - previousSample.time);
57
+ previousSample = sample;
58
+
59
+ if (
60
+ age > this.horizonMilliseconds ||
61
+ delta > this.assumePointerMoveStoppedMilliseconds
62
+ ) {
63
+ break;
64
+ }
65
+
66
+ x.push(sample.x);
67
+ y.push(sample.y);
68
+ w.push(1);
69
+ time.push(-age);
70
+
71
+ sampleCount++;
72
+ index--;
73
+ }
74
+
75
+ if (sampleCount >= this.minSampleSize) {
76
+ const xSolver = new LeastSquareSolver(time, x, w);
77
+ const xFit = xSolver.solve(2);
78
+
79
+ if (xFit !== null) {
80
+ const ySolver = new LeastSquareSolver(time, y, w);
81
+ const yFit = ySolver.solve(2);
82
+
83
+ if (yFit !== null) {
84
+ const xVelocity = xFit.coefficients[1] * 1000;
85
+ const yVelocity = yFit.coefficients[1] * 1000;
86
+
87
+ return [xVelocity, yVelocity];
88
+ }
89
+ }
90
+ }
91
+
92
+ return null;
93
+ }
94
+
95
+ public getVelocity(): [number, number] {
96
+ const estimate = this.getVelocityEstimate();
97
+ if (estimate !== null) {
98
+ return estimate;
99
+ }
100
+ return [0, 0];
101
+ }
102
+
103
+ public reset(): void {
104
+ this.samples.clear();
105
+ }
106
+ }
@@ -0,0 +1,19 @@
1
+ export type Tag = number
2
+
3
+ export type BoundingBox = {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ };
9
+
10
+ export interface View {
11
+ getTag(): Tag
12
+
13
+ isPositionInBounds({x, y}: {
14
+ x: number;
15
+ y: number
16
+ }): boolean
17
+
18
+ getBoundingRect(): BoundingBox
19
+ }
@@ -0,0 +1,13 @@
1
+ export * from "./OutgoingEventDispatcher"
2
+ export * from "./OutgoingEvent"
3
+ export * from "./RNGHLogger"
4
+ export * from "./View"
5
+ export * from "./Vector2D"
6
+ export * from "./GestureHandler"
7
+ export * from "./IncomingEvent"
8
+ export * from "./GestureHandlerOrchestrator"
9
+ export * from "./InteractionManager"
10
+ export * from "./PointerTracker"
11
+ export * from "./RNGHError"
12
+ export * from "./State"
13
+ export * from "./GestureHandlerRegistry"
@@ -0,0 +1,169 @@
1
+ import { DEFAULT_TOUCH_SLOP, IncomingEvent, EventType, PointerTracker } from '../core';
2
+
3
+ export interface ScaleGestureListener {
4
+ onScaleBegin: (detector: ScaleGestureDetector) => boolean;
5
+ onScale: (detector: ScaleGestureDetector) => boolean;
6
+ onScaleEnd: (detector: ScaleGestureDetector) => void;
7
+ }
8
+
9
+ export default class ScaleGestureDetector implements ScaleGestureListener {
10
+ public onScaleBegin: (detector: ScaleGestureDetector) => boolean;
11
+ public onScale: (detector: ScaleGestureDetector) => boolean;
12
+ public onScaleEnd: (detector: ScaleGestureDetector) => void;
13
+
14
+ private focusX!: number;
15
+ private focusY!: number;
16
+
17
+ private currentSpan!: number;
18
+ private prevSpan!: number;
19
+ private initialSpan!: number;
20
+
21
+ private currentTime!: number;
22
+ private prevTime!: number;
23
+
24
+ private inProgress = false;
25
+
26
+ private spanSlop: number;
27
+ private minSpan: number;
28
+
29
+ public constructor(callbacks: ScaleGestureListener) {
30
+ this.onScaleBegin = callbacks.onScaleBegin;
31
+ this.onScale = callbacks.onScale;
32
+ this.onScaleEnd = callbacks.onScaleEnd;
33
+
34
+ this.spanSlop = DEFAULT_TOUCH_SLOP * 2;
35
+ this.minSpan = 0;
36
+ }
37
+
38
+ public onTouchEvent(event: IncomingEvent, tracker: PointerTracker): boolean {
39
+ this.currentTime = event.time;
40
+
41
+ const action: EventType = event.eventType;
42
+ const numOfPointers = tracker.getTrackedPointersCount();
43
+
44
+ const streamComplete: boolean =
45
+ action === EventType.UP ||
46
+ action === EventType.ADDITIONAL_POINTER_UP ||
47
+ action === EventType.CANCEL;
48
+
49
+ if (action === EventType.DOWN || streamComplete) {
50
+ if (this.inProgress) {
51
+ this.onScaleEnd(this);
52
+ this.inProgress = false;
53
+ this.initialSpan = 0;
54
+ }
55
+
56
+ if (streamComplete) {
57
+ return true;
58
+ }
59
+ }
60
+
61
+ const configChanged: boolean =
62
+ action === EventType.DOWN ||
63
+ action === EventType.ADDITIONAL_POINTER_UP ||
64
+ action === EventType.ADDITIONAL_POINTER_DOWN;
65
+
66
+ const pointerUp = action === EventType.ADDITIONAL_POINTER_UP;
67
+
68
+ const ignoredPointer: number | undefined = pointerUp
69
+ ? event.pointerId
70
+ : undefined;
71
+
72
+ //Determine focal point
73
+
74
+ const div: number = pointerUp ? numOfPointers - 1 : numOfPointers;
75
+
76
+ const sumX = tracker.getSumX(ignoredPointer);
77
+ const sumY = tracker.getSumY(ignoredPointer);
78
+
79
+ const focusX = sumX / div;
80
+ const focusY = sumY / div;
81
+
82
+ //Determine average deviation from focal point
83
+
84
+ let devSumX = 0;
85
+ let devSumY = 0;
86
+
87
+ tracker.getData().forEach((value, key) => {
88
+ if (key === ignoredPointer) {
89
+ return;
90
+ }
91
+
92
+ devSumX += Math.abs(value.lastX - focusX);
93
+ devSumY += Math.abs(value.lastY - focusY);
94
+ });
95
+
96
+ const devX: number = devSumX / div;
97
+ const devY: number = devSumY / div;
98
+
99
+ const spanX: number = devX * 2;
100
+ const spanY: number = devY * 2;
101
+
102
+ const span = Math.hypot(spanX, spanY);
103
+
104
+ //Begin/end events
105
+ const wasInProgress: boolean = this.inProgress;
106
+ this.focusX = focusX;
107
+ this.focusY = focusY;
108
+
109
+ if (this.inProgress && (span < this.minSpan || configChanged)) {
110
+ this.onScaleEnd(this);
111
+ this.inProgress = false;
112
+ this.initialSpan = span;
113
+ }
114
+
115
+ if (configChanged) {
116
+ this.initialSpan = this.prevSpan = this.currentSpan = span;
117
+ }
118
+
119
+ if (
120
+ !this.inProgress &&
121
+ span >= this.minSpan &&
122
+ (wasInProgress || Math.abs(span - this.initialSpan) > this.spanSlop)
123
+ ) {
124
+ this.prevSpan = this.currentSpan = span;
125
+ this.prevTime = this.currentTime;
126
+ this.inProgress = this.onScaleBegin(this);
127
+ }
128
+
129
+ //Handle motion
130
+ if (action !== EventType.MOVE) {
131
+ return true;
132
+ }
133
+
134
+ this.currentSpan = span;
135
+
136
+ if (this.inProgress && !this.onScale(this)) {
137
+ return true;
138
+ }
139
+
140
+ this.prevSpan = this.currentSpan;
141
+ this.prevTime = this.currentTime;
142
+
143
+ return true;
144
+ }
145
+
146
+ public getCurrentSpan(): number {
147
+ return this.currentSpan;
148
+ }
149
+
150
+ public getFocusX(): number {
151
+ return this.focusX;
152
+ }
153
+
154
+ public getFocusY(): number {
155
+ return this.focusY;
156
+ }
157
+
158
+ public getTimeDelta(): number {
159
+ return this.currentTime - this.prevTime;
160
+ }
161
+
162
+ public getScaleFactor(numOfPointers: number): number {
163
+ if (numOfPointers < 2) {
164
+ return 1;
165
+ }
166
+
167
+ return this.prevSpan > 0 ? this.currentSpan / this.prevSpan : 1;
168
+ }
169
+ }
@@ -0,0 +1,211 @@
1
+ import {
2
+ GestureHandler,
3
+ State,
4
+ DiagonalDirections,
5
+ Directions,
6
+ Vector2D,
7
+ IncomingEvent,
8
+ GestureHandlerDependencies
9
+ } from '../core';
10
+
11
+ const DEFAULT_MAX_DURATION_MS = 800;
12
+ const DEFAULT_MIN_VELOCITY = 700;
13
+ /**
14
+ * DEFAULT_ALIGNMENT_CONE defines the angular tolerance for fling gestures in degrees.
15
+ * *
16
+ * *
17
+ * *
18
+ * *------------>
19
+ * *
20
+ * *
21
+ * *
22
+ */
23
+ const DEFAULT_ALIGNMENT_CONE = 30;
24
+ const DEFAULT_DIRECTION: Directions = Directions.RIGHT;
25
+ const DEFAULT_NUMBER_OF_TOUCHES_REQUIRED = 1;
26
+ const AXIAL_DEVIATION_COSINE = coneToDeviation(DEFAULT_ALIGNMENT_CONE);
27
+ const DIAGONAL_DEVIATION_COSINE = coneToDeviation(90 - DEFAULT_ALIGNMENT_CONE);
28
+
29
+ export class FlingGestureHandler extends GestureHandler {
30
+ constructor(deps: GestureHandlerDependencies) {
31
+ super({ ...deps, logger: deps.logger.cloneWithPrefix("FlingGestureHandler") })
32
+ }
33
+
34
+ getDefaultConfig() {
35
+ return {}
36
+ }
37
+
38
+ private get direction(): Directions {
39
+ return this.config.direction ?? DEFAULT_DIRECTION
40
+ }
41
+
42
+ private get numberOfPointersRequired() {
43
+ return this.config.numberOfPointers ?? DEFAULT_NUMBER_OF_TOUCHES_REQUIRED
44
+ }
45
+
46
+ private get maxDurationMs() {
47
+ return this.config.maxDurationMs ?? DEFAULT_MAX_DURATION_MS
48
+ }
49
+
50
+ private get minVelocity() {
51
+ return this.config.minVelocity ?? DEFAULT_MIN_VELOCITY
52
+ }
53
+
54
+ private delayTimeout!: number;
55
+ private maxNumberOfPointersSimultaneously = 0;
56
+ private keyPointer = NaN;
57
+
58
+ private startFling(): void {
59
+ this.logger.info("startFling")
60
+ this.begin();
61
+
62
+ this.maxNumberOfPointersSimultaneously = 1;
63
+
64
+ this.delayTimeout = setTimeout(() => this.fail(), this.maxDurationMs);
65
+ }
66
+
67
+ private tryEndFling(): boolean {
68
+ const logger = this.logger.cloneWithPrefix("tryEndFling")
69
+ const velocityVector = this.tracker.getVelocity(this.keyPointer);
70
+
71
+ const getAlignment = (
72
+ direction: Directions | DiagonalDirections,
73
+ minimalAlignmentCosine: number
74
+ ) => {
75
+ return (
76
+ (direction & this.direction) === direction &&
77
+ velocityVector.computeCosine(
78
+ Vector2D.fromDirection(direction),
79
+ ) > minimalAlignmentCosine
80
+ );
81
+ };
82
+
83
+ const axialDirectionsList = Object.values(Directions);
84
+ const diagonalDirectionsList = Object.values(DiagonalDirections);
85
+
86
+ // list of alignments to all activated directions
87
+ const axialAlignmentList = axialDirectionsList.map((direction) =>
88
+ getAlignment(direction, AXIAL_DEVIATION_COSINE)
89
+ );
90
+
91
+ const diagonalAlignmentList = diagonalDirectionsList.map((direction) =>
92
+ getAlignment(direction, DIAGONAL_DEVIATION_COSINE)
93
+ );
94
+
95
+ const isAligned =
96
+ axialAlignmentList.some(Boolean) || diagonalAlignmentList.some(Boolean);
97
+
98
+ const isFast = velocityVector.magnitude > this.minVelocity;
99
+
100
+ if (
101
+ this.maxNumberOfPointersSimultaneously ===
102
+ this.numberOfPointersRequired &&
103
+ isAligned &&
104
+ isFast
105
+ ) {
106
+ clearTimeout(this.delayTimeout);
107
+ this.activate();
108
+
109
+ return true;
110
+ }
111
+
112
+ return false;
113
+ }
114
+
115
+ private endFling() {
116
+ this.logger.info("endFling")
117
+ if (!this.tryEndFling()) {
118
+ this.fail();
119
+ }
120
+ }
121
+
122
+ public onPointerDown(event: IncomingEvent): void {
123
+ this.tracker.addToTracker(event);
124
+ this.keyPointer = event.pointerId;
125
+
126
+ super.onPointerDown(event);
127
+ this.newPointerAction();
128
+ }
129
+
130
+ public onAdditionalPointerAdd(event: IncomingEvent): void {
131
+ this.tracker.addToTracker(event);
132
+ super.onAdditionalPointerAdd(event);
133
+ this.newPointerAction();
134
+ }
135
+
136
+ private newPointerAction(): void {
137
+ if (this.currentState === State.UNDETERMINED) {
138
+ this.startFling();
139
+ }
140
+
141
+ if (this.currentState !== State.BEGAN) {
142
+ return;
143
+ }
144
+
145
+ this.tryEndFling();
146
+
147
+ if (
148
+ this.tracker.getTrackedPointersCount() >
149
+ this.maxNumberOfPointersSimultaneously
150
+ ) {
151
+ this.maxNumberOfPointersSimultaneously =
152
+ this.tracker.getTrackedPointersCount();
153
+ }
154
+ }
155
+
156
+ private pointerMoveAction(event: IncomingEvent): void {
157
+ this.logger.cloneWithPrefix("pointerMoveAction").info(JSON.stringify(event))
158
+ this.tracker.track(event);
159
+
160
+ if (this.currentState !== State.BEGAN) {
161
+ return;
162
+ }
163
+
164
+ this.tryEndFling();
165
+ }
166
+
167
+ public onPointerMove(event: IncomingEvent): void {
168
+ this.pointerMoveAction(event);
169
+ super.onPointerMove(event);
170
+ }
171
+
172
+ public onPointerOutOfBounds(event: IncomingEvent): void {
173
+ this.pointerMoveAction(event);
174
+ super.onPointerOutOfBounds(event);
175
+ }
176
+
177
+ public onPointerUp(event: IncomingEvent): void {
178
+ super.onPointerUp(event);
179
+ this.onUp(event);
180
+
181
+ this.keyPointer = NaN;
182
+ }
183
+
184
+ public onAdditionalPointerRemove(event: IncomingEvent): void {
185
+ super.onAdditionalPointerRemove(event);
186
+ this.onUp(event);
187
+ }
188
+
189
+ private onUp(event: IncomingEvent): void {
190
+ const logger = this.logger.cloneWithPrefix("onUp")
191
+ logger.info("start")
192
+ if (this.currentState === State.BEGAN) {
193
+ this.endFling();
194
+ }
195
+ logger.info(`removeFromTracker: pointerId=${event.pointerId}`)
196
+ this.tracker.removeFromTracker(event.pointerId);
197
+ }
198
+
199
+ public activate(): void {
200
+ super.activate();
201
+ this.end();
202
+ }
203
+ }
204
+
205
+ function coneToDeviation(degrees: number) {
206
+ return Math.cos(degToRad(degrees / 2));
207
+ }
208
+
209
+ function degToRad(degrees: number) {
210
+ return (degrees * Math.PI) / 180;
211
+ }
@@ -0,0 +1,64 @@
1
+ import {
2
+ RNGHLogger,
3
+ InteractionManager,
4
+ RNGHError,
5
+ PointerTracker,
6
+ GestureHandler,
7
+ GestureHandlerDependencies,
8
+ ScrollLocker,
9
+ GestureHandlerOrchestrator,
10
+ RNGestureResponder
11
+ } from "../core"
12
+ import { TapGestureHandler } from './TapGestureHandler';
13
+ import { PanGestureHandler } from "./PanGestureHandler"
14
+ import { PinchGestureHandler } from "./PinchGestureHandler"
15
+ import { NativeViewGestureHandler } from "./NativeViewGestureHandler"
16
+ import { ManualGestureHandler } from './ManualGestureHandler';
17
+ import { LongPressGestureHandler } from "./LongPressGestureHandler"
18
+ import { FlingGestureHandler } from "./FlingGestureHandler"
19
+ import { RotationGestureHandler } from "./RotationGestureHandler"
20
+
21
+ export class GestureHandlerFactory {
22
+ private orchestrator: GestureHandlerOrchestrator
23
+ private logger: RNGHLogger
24
+
25
+ constructor(private cleanLogger: RNGHLogger, private scrollLocker: ScrollLocker, private interactionManager: InteractionManager, private rnGestureResponder: RNGestureResponder) {
26
+ this.logger = cleanLogger.cloneWithPrefix("Factory")
27
+ this.orchestrator = new GestureHandlerOrchestrator(cleanLogger.cloneWithPrefix("Orchestrator"))
28
+ }
29
+
30
+ create(handlerName: string, handlerTag: number): GestureHandler {
31
+ this.logger.info(`create ${handlerName} with handlerTag: ${handlerTag}`)
32
+ const deps: GestureHandlerDependencies = {
33
+ tracker: new PointerTracker(),
34
+ orchestrator: this.orchestrator,
35
+ handlerTag,
36
+ interactionManager: this.interactionManager,
37
+ logger: this.cleanLogger.cloneWithPrefix("GestureHandler"),
38
+ scrollLocker: this.scrollLocker,
39
+ rnGestureResponder: this.rnGestureResponder,
40
+ }
41
+ switch (handlerName) {
42
+ case "TapGestureHandler":
43
+ return new TapGestureHandler(deps)
44
+ case "PanGestureHandler":
45
+ return new PanGestureHandler(deps)
46
+ case "PinchGestureHandler":
47
+ return new PinchGestureHandler(deps)
48
+ case "NativeViewGestureHandler":
49
+ return new NativeViewGestureHandler(deps)
50
+ case "ManualGestureHandler":
51
+ return new ManualGestureHandler(deps)
52
+ case "LongPressGestureHandler":
53
+ return new LongPressGestureHandler(deps)
54
+ case "FlingGestureHandler":
55
+ return new FlingGestureHandler(deps)
56
+ case "RotationGestureHandler":
57
+ return new RotationGestureHandler(deps)
58
+ default:
59
+ const msg = `Unknown handler type: ${handlerName}`
60
+ this.logger.info(msg)
61
+ throw new RNGHError(msg)
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,127 @@
1
+ import { GestureHandler, IncomingEvent, GestureConfig, State, GestureHandlerDependencies } from '../core';
2
+
3
+ const DEFAULT_MIN_DURATION_MS = 500;
4
+ const DEFAULT_MAX_DIST_DP = 10;
5
+ const SCALING_FACTOR = 10;
6
+
7
+ export class LongPressGestureHandler extends GestureHandler {
8
+ private minDurationMs = DEFAULT_MIN_DURATION_MS;
9
+ private defaultMaxDistSq = DEFAULT_MAX_DIST_DP * SCALING_FACTOR;
10
+
11
+ private maxDistSq = this.defaultMaxDistSq;
12
+ private startX = 0;
13
+ private startY = 0;
14
+
15
+ private startTime = 0;
16
+ private previousTime = 0;
17
+
18
+ private activationTimeout: number | undefined;
19
+
20
+ constructor(deps: GestureHandlerDependencies) {
21
+ super({...deps, logger: deps.logger.cloneWithPrefix("LongPressGestureHandler")})
22
+ }
23
+
24
+ public getDefaultConfig() {
25
+ return {}
26
+ }
27
+
28
+ protected transformNativeEvent() {
29
+ return {
30
+ ...super.transformNativeEvent(),
31
+ duration: Date.now() - this.startTime,
32
+ };
33
+ }
34
+
35
+ public updateGestureConfig({ enabled = true, ...props }: GestureConfig): void {
36
+ super.updateGestureConfig({ enabled: enabled, ...props });
37
+
38
+ if (this.config.minDurationMs !== undefined) {
39
+ this.minDurationMs = this.config.minDurationMs;
40
+ }
41
+
42
+ if (this.config.maxDist !== undefined) {
43
+ this.maxDistSq = this.config.maxDist * this.config.maxDist;
44
+ }
45
+ }
46
+
47
+
48
+
49
+ protected resetConfig(): void {
50
+ super.resetConfig();
51
+ this.minDurationMs = DEFAULT_MIN_DURATION_MS;
52
+ this.maxDistSq = this.defaultMaxDistSq;
53
+ }
54
+
55
+ protected onStateChange(newState: State, oldState: State): void {
56
+ super.onStateChange(newState, oldState)
57
+ clearTimeout(this.activationTimeout);
58
+ }
59
+
60
+ public onPointerDown(event: IncomingEvent): void {
61
+ this.tracker.addToTracker(event);
62
+ super.onPointerDown(event);
63
+ this.tryBegin(event);
64
+ this.tryActivate();
65
+ this.checkDistanceFail(event);
66
+ }
67
+
68
+ public onPointerMove(event: IncomingEvent): void {
69
+ super.onPointerMove(event);
70
+ this.tracker.track(event);
71
+ this.checkDistanceFail(event);
72
+ }
73
+
74
+ public onPointerUp(event: IncomingEvent): void {
75
+ super.onPointerUp(event);
76
+ this.tracker.removeFromTracker(event.pointerId);
77
+
78
+ if (this.currentState === State.ACTIVE) {
79
+ this.end();
80
+ } else {
81
+ this.fail();
82
+ }
83
+ }
84
+
85
+ private tryBegin(event: IncomingEvent): void {
86
+ if (this.currentState !== State.UNDETERMINED) {
87
+ return;
88
+ }
89
+
90
+ this.previousTime = Date.now();
91
+ this.startTime = this.previousTime;
92
+
93
+ this.begin();
94
+
95
+ this.startX = event.x;
96
+ this.startY = event.y;
97
+ }
98
+
99
+ private tryActivate(): void {
100
+ if (this.minDurationMs > 0) {
101
+ if (this.activationTimeout) {
102
+ clearTimeout(this.activationTimeout)
103
+ }
104
+ this.activationTimeout = setTimeout(() => {
105
+ this.activate();
106
+ }, this.minDurationMs);
107
+ } else if (this.minDurationMs === 0) {
108
+ this.activate();
109
+ }
110
+ }
111
+
112
+ private checkDistanceFail(event: IncomingEvent): void {
113
+ const dx = event.x - this.startX;
114
+ const dy = event.y - this.startY;
115
+ const distSq = dx * dx + dy * dy;
116
+
117
+ if (distSq <= this.maxDistSq) {
118
+ return;
119
+ }
120
+
121
+ if (this.currentState === State.ACTIVE) {
122
+ this.cancel();
123
+ } else {
124
+ this.fail();
125
+ }
126
+ }
127
+ }