@react-native-oh-tpl/react-native-gesture-handler 2.12.6-1 → 2.12.6-2
Sign up to get free protection for your applications and to get access to all the features.
- package/harmony/gesture_handler/LICENSE +21 -0
- package/harmony/gesture_handler/OAT.xml +44 -0
- package/harmony/gesture_handler/README.OpenSource +11 -0
- package/harmony/gesture_handler/README.md +1 -0
- package/harmony/gesture_handler/build-profile.json5 +7 -7
- package/harmony/gesture_handler/hvigorfile.ts +2 -2
- package/harmony/gesture_handler/index.ets +2 -2
- package/harmony/gesture_handler/oh-package.json5 +13 -11
- package/harmony/gesture_handler/src/main/cpp/CMakeLists.txt +8 -8
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +33 -33
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +14 -14
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonComponentDescriptor.h +60 -60
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.cpp +17 -17
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.h +11 -11
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentDescriptor.h +60 -60
- package/harmony/gesture_handler/src/main/ets/CircularBuffer.ts +42 -42
- package/harmony/gesture_handler/src/main/ets/Event.ts +67 -67
- package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +37 -37
- package/harmony/gesture_handler/src/main/ets/GestureHandler.ts +663 -663
- package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ets +201 -201
- package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +44 -44
- package/harmony/gesture_handler/src/main/ets/GestureHandlerOrchestrator.ts +280 -280
- package/harmony/gesture_handler/src/main/ets/GestureHandlerPackage.ts +22 -22
- package/harmony/gesture_handler/src/main/ets/GestureHandlerRegistry.ts +27 -27
- package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +108 -108
- package/harmony/gesture_handler/src/main/ets/LeastSquareSolver.ts +182 -182
- package/harmony/gesture_handler/src/main/ets/NativeViewGestureHandler.ts +114 -114
- package/harmony/gesture_handler/src/main/ets/OutgoingEvent.ts +33 -33
- package/harmony/gesture_handler/src/main/ets/PanGestureHandler.ts +327 -327
- package/harmony/gesture_handler/src/main/ets/PointerTracker.ts +239 -239
- package/harmony/gesture_handler/src/main/ets/RNGHError.ts +4 -4
- package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +28 -28
- package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandler.ets +57 -57
- package/harmony/gesture_handler/src/main/ets/RNGestureHandlerButton.ets +36 -36
- package/harmony/gesture_handler/src/main/ets/RNGestureHandlerModule.ts +125 -125
- package/harmony/gesture_handler/src/main/ets/RNGestureHandlerRootView.ets +56 -55
- package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +10 -10
- package/harmony/gesture_handler/src/main/ets/State.ts +46 -46
- package/harmony/gesture_handler/src/main/ets/TapGestureHandler.ts +205 -205
- package/harmony/gesture_handler/src/main/ets/Vector2D.ts +36 -36
- package/harmony/gesture_handler/src/main/ets/VelocityTracker.ts +98 -98
- package/harmony/gesture_handler/src/main/ets/View.ts +70 -70
- package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +42 -42
- package/harmony/gesture_handler/src/main/ets/pages/Index.ets +16 -16
- package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +41 -41
- package/harmony/gesture_handler/src/main/module.json5 +6 -6
- package/harmony/gesture_handler/src/main/resources/base/element/color.json +7 -7
- package/harmony/gesture_handler/src/main/resources/base/element/string.json +15 -15
- package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -5
- package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +15 -15
- package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +15 -15
- package/harmony/gesture_handler.har +0 -0
- package/lib/commonjs/components/touchables/GenericTouchable.js +9 -9
- package/lib/commonjs/components/touchables/TouchableOpacity.js +2 -2
- package/lib/commonjs/handlers/createNativeWrapper.js +6 -6
- package/lib/commonjs/handlers/gestures/GestureDetector.js +3 -3
- package/lib/module/components/touchables/GenericTouchable.js +9 -9
- package/lib/module/components/touchables/TouchableOpacity.js +2 -2
- package/lib/module/handlers/createNativeWrapper.js +6 -6
- package/lib/module/handlers/gestures/GestureDetector.js +3 -3
- package/package.json +70 -70
- package/src/RNGestureHandlerModule.ts +6 -6
- package/src/components/GestureButtons.tsx +334 -334
- package/src/components/GestureHandlerButton.tsx +5 -5
- package/src/components/GestureHandlerRootView.tsx +34 -34
- package/src/components/RNGestureHandlerButton.tsx +23 -23
- package/src/components/touchables/GenericTouchable.tsx +301 -301
- package/src/components/touchables/TouchableOpacity.tsx +76 -76
- package/src/components/touchables/TouchableWithoutFeedback.tsx +14 -14
- package/src/components/touchables/index.ts +7 -7
- package/src/handlers/NativeViewGestureHandler.ts +55 -55
- package/src/handlers/PanGestureHandler.ts +327 -327
- package/src/handlers/TapGestureHandler.ts +95 -95
- package/src/handlers/createHandler.tsx +535 -535
- package/src/handlers/createNativeWrapper.tsx +81 -81
- package/src/handlers/gestureHandlerCommon.ts +15 -15
- package/src/handlers/gestures/GestureDetector.tsx +823 -823
- package/src/index.ts +172 -172
- package/src/init.ts +18 -18
@@ -1,206 +1,206 @@
|
|
1
|
-
import { GestureHandler, GestureHandlerDependencies } from "./GestureHandler"
|
2
|
-
import { AdaptedEvent, EventType } from "./Event"
|
3
|
-
import { State, getStateName } from "./State"
|
4
|
-
|
5
|
-
const DEFAULT_MAX_DURATION_MS = 500;
|
6
|
-
const DEFAULT_NUMBER_OF_TAPS = 1;
|
7
|
-
const DEFAULT_MAX_DELAY_MS = 500;
|
8
|
-
|
9
|
-
export class TapGestureHandler extends GestureHandler {
|
10
|
-
private startX = 0;
|
11
|
-
private startY = 0;
|
12
|
-
private offsetX = 0;
|
13
|
-
private offsetY = 0;
|
14
|
-
private lastX = 0;
|
15
|
-
private lastY = 0;
|
16
|
-
private maxNumberOfPointersSoFar = 0;
|
17
|
-
private numberOfTapsSoFar: number = 0;
|
18
|
-
private waitTimeout: number | undefined;
|
19
|
-
private delayTimeout: number | undefined;
|
20
|
-
|
21
|
-
constructor(deps: GestureHandlerDependencies) {
|
22
|
-
super({...deps, logger: deps.logger.cloneWithPrefix("TapGestureHandler")})
|
23
|
-
}
|
24
|
-
|
25
|
-
onPointerDown(event) {
|
26
|
-
this.tracker.addToTracker(event);
|
27
|
-
super.onPointerDown(event);
|
28
|
-
this.trySettingPosition(event);
|
29
|
-
this.lastX = event.x;
|
30
|
-
this.lastY = event.y;
|
31
|
-
this.updateState(event);
|
32
|
-
}
|
33
|
-
|
34
|
-
onAdditionalPointerAdd(event: AdaptedEvent): void {
|
35
|
-
super.onAdditionalPointerAdd(event);
|
36
|
-
this.tracker.addToTracker(event);
|
37
|
-
this.trySettingPosition(event);
|
38
|
-
|
39
|
-
this.offsetX += this.lastX - this.startX;
|
40
|
-
this.offsetY += this.lastY - this.startY;
|
41
|
-
|
42
|
-
this.lastX = this.tracker.getLastAvgX();
|
43
|
-
this.lastY = this.tracker.getLastAvgY();
|
44
|
-
|
45
|
-
this.startX = this.tracker.getLastAvgX();
|
46
|
-
this.startY = this.tracker.getLastAvgY();
|
47
|
-
|
48
|
-
this.updateState(event);
|
49
|
-
}
|
50
|
-
|
51
|
-
onPointerUp(event: AdaptedEvent): void {
|
52
|
-
super.onPointerUp(event);
|
53
|
-
this.lastX = this.tracker.getLastAvgX();
|
54
|
-
this.lastY = this.tracker.getLastAvgY();
|
55
|
-
|
56
|
-
this.tracker.removeFromTracker(event.pointerId);
|
57
|
-
|
58
|
-
this.updateState(event);
|
59
|
-
}
|
60
|
-
|
61
|
-
onAdditionalPointerRemove(event: AdaptedEvent): void {
|
62
|
-
super.onAdditionalPointerRemove(event);
|
63
|
-
this.tracker.removeFromTracker(event.pointerId);
|
64
|
-
|
65
|
-
this.offsetX += this.lastX - this.startX;
|
66
|
-
this.offsetY += this.lastY = this.startY;
|
67
|
-
|
68
|
-
this.lastX = this.tracker.getLastAvgX();
|
69
|
-
this.lastY = this.tracker.getLastAvgY();
|
70
|
-
|
71
|
-
this.startX = this.lastX;
|
72
|
-
this.startY = this.lastY;
|
73
|
-
|
74
|
-
this.updateState(event);
|
75
|
-
}
|
76
|
-
|
77
|
-
onPointerMove(event: AdaptedEvent): void {
|
78
|
-
this.trySettingPosition(event);
|
79
|
-
this.tracker.track(event);
|
80
|
-
|
81
|
-
this.lastX = this.tracker.getLastAvgX();
|
82
|
-
this.lastY = this.tracker.getLastAvgY();
|
83
|
-
|
84
|
-
this.updateState(event);
|
85
|
-
|
86
|
-
super.onPointerMove(event);
|
87
|
-
}
|
88
|
-
|
89
|
-
onPointerOutOfBounds(event: AdaptedEvent): void {
|
90
|
-
this.trySettingPosition(event);
|
91
|
-
this.tracker.track(event);
|
92
|
-
|
93
|
-
this.lastX = this.tracker.getLastAvgX();
|
94
|
-
this.lastY = this.tracker.getLastAvgY();
|
95
|
-
|
96
|
-
this.updateState(event);
|
97
|
-
|
98
|
-
super.onPointerOutOfBounds(event);
|
99
|
-
}
|
100
|
-
|
101
|
-
getDefaultConfig() {
|
102
|
-
return {}
|
103
|
-
}
|
104
|
-
|
105
|
-
private trySettingPosition(event: AdaptedEvent): void {
|
106
|
-
if (this.currentState !== State.UNDETERMINED) return;
|
107
|
-
this.offsetX = 0;
|
108
|
-
this.offsetY = 0;
|
109
|
-
this.startX = event.x;
|
110
|
-
this.startY = event.y;
|
111
|
-
}
|
112
|
-
|
113
|
-
private updateState(event: AdaptedEvent): void {
|
114
|
-
const logger = this.logger.cloneWithPrefix("updateState")
|
115
|
-
if (this.maxNumberOfPointersSoFar < this.tracker.getTrackedPointersCount()) {
|
116
|
-
this.maxNumberOfPointersSoFar = this.tracker.getTrackedPointersCount()
|
117
|
-
}
|
118
|
-
if (this.shouldFail()) {
|
119
|
-
logger.info("fail")
|
120
|
-
this.fail()
|
121
|
-
return;
|
122
|
-
}
|
123
|
-
switch (this.currentState) {
|
124
|
-
case State.UNDETERMINED:
|
125
|
-
if (event.eventType === EventType.DOWN) {
|
126
|
-
this.begin()
|
127
|
-
}
|
128
|
-
this.startTap();
|
129
|
-
break;
|
130
|
-
case State.BEGAN:
|
131
|
-
if (event.eventType === EventType.UP) {
|
132
|
-
logger.info("endTap")
|
133
|
-
this.endTap();
|
134
|
-
}
|
135
|
-
if (event.eventType === EventType.DOWN) {
|
136
|
-
this.startTap();
|
137
|
-
}
|
138
|
-
break;
|
139
|
-
default:
|
140
|
-
logger.info(`default case - currentState ${getStateName(this.currentState)}`)
|
141
|
-
break;
|
142
|
-
}
|
143
|
-
}
|
144
|
-
|
145
|
-
private shouldFail(): boolean {
|
146
|
-
const maxDeltaX = this.config.maxDeltaX ?? Number.MIN_SAFE_INTEGER
|
147
|
-
const maxDeltaY = this.config.maxDeltaY ?? Number.MIN_SAFE_INTEGER
|
148
|
-
const maxDistSq = this.config.maxDistSq ?? Number.MIN_SAFE_INTEGER
|
149
|
-
|
150
|
-
const dx = this.lastX - this.startX + this.offsetX;
|
151
|
-
if (
|
152
|
-
maxDeltaX !== Number.MIN_SAFE_INTEGER &&
|
153
|
-
Math.abs(dx) > maxDeltaX
|
154
|
-
) {
|
155
|
-
return true;
|
156
|
-
}
|
157
|
-
const dy = this.lastY - this.startY + this.offsetY;
|
158
|
-
if (
|
159
|
-
maxDeltaY !== Number.MIN_SAFE_INTEGER &&
|
160
|
-
Math.abs(dy) > maxDeltaY
|
161
|
-
) {
|
162
|
-
return true;
|
163
|
-
}
|
164
|
-
const distSq = dy * dy + dx * dx;
|
165
|
-
const result = maxDistSq !== Number.MIN_SAFE_INTEGER && distSq > maxDistSq
|
166
|
-
return result;
|
167
|
-
}
|
168
|
-
|
169
|
-
private startTap() {
|
170
|
-
this.clearTimeouts();
|
171
|
-
this.waitTimeout = setTimeout(() => this.fail(), this.config.maxDurationMs ?? DEFAULT_MAX_DURATION_MS);
|
172
|
-
}
|
173
|
-
|
174
|
-
private clearTimeouts() {
|
175
|
-
clearTimeout(this.waitTimeout);
|
176
|
-
clearTimeout(this.delayTimeout);
|
177
|
-
}
|
178
|
-
|
179
|
-
private endTap() {
|
180
|
-
this.clearTimeouts();
|
181
|
-
if (
|
182
|
-
++this.numberOfTapsSoFar === (this.config.numberOfTaps ?? DEFAULT_NUMBER_OF_TAPS) &&
|
183
|
-
this.maxNumberOfPointersSoFar >= (this.config.minNumberOfPointers ?? 0)
|
184
|
-
) {
|
185
|
-
this.activate();
|
186
|
-
} else {
|
187
|
-
this.delayTimeout = setTimeout(() => this.fail(), this.config.maxDelayMs ?? DEFAULT_MAX_DELAY_MS);
|
188
|
-
}
|
189
|
-
}
|
190
|
-
|
191
|
-
public activate(): void {
|
192
|
-
super.activate();
|
193
|
-
this.end();
|
194
|
-
}
|
195
|
-
|
196
|
-
protected onCancel() {
|
197
|
-
super.onCancel()
|
198
|
-
this.resetProgress()
|
199
|
-
}
|
200
|
-
|
201
|
-
protected resetProgress(): void {
|
202
|
-
this.clearTimeouts();
|
203
|
-
this.numberOfTapsSoFar = 0;
|
204
|
-
this.maxNumberOfPointersSoFar = 0;
|
205
|
-
}
|
1
|
+
import { GestureHandler, GestureHandlerDependencies } from "./GestureHandler"
|
2
|
+
import { AdaptedEvent, EventType } from "./Event"
|
3
|
+
import { State, getStateName } from "./State"
|
4
|
+
|
5
|
+
const DEFAULT_MAX_DURATION_MS = 500;
|
6
|
+
const DEFAULT_NUMBER_OF_TAPS = 1;
|
7
|
+
const DEFAULT_MAX_DELAY_MS = 500;
|
8
|
+
|
9
|
+
export class TapGestureHandler extends GestureHandler {
|
10
|
+
private startX = 0;
|
11
|
+
private startY = 0;
|
12
|
+
private offsetX = 0;
|
13
|
+
private offsetY = 0;
|
14
|
+
private lastX = 0;
|
15
|
+
private lastY = 0;
|
16
|
+
private maxNumberOfPointersSoFar = 0;
|
17
|
+
private numberOfTapsSoFar: number = 0;
|
18
|
+
private waitTimeout: number | undefined;
|
19
|
+
private delayTimeout: number | undefined;
|
20
|
+
|
21
|
+
constructor(deps: GestureHandlerDependencies) {
|
22
|
+
super({...deps, logger: deps.logger.cloneWithPrefix("TapGestureHandler")})
|
23
|
+
}
|
24
|
+
|
25
|
+
onPointerDown(event) {
|
26
|
+
this.tracker.addToTracker(event);
|
27
|
+
super.onPointerDown(event);
|
28
|
+
this.trySettingPosition(event);
|
29
|
+
this.lastX = event.x;
|
30
|
+
this.lastY = event.y;
|
31
|
+
this.updateState(event);
|
32
|
+
}
|
33
|
+
|
34
|
+
onAdditionalPointerAdd(event: AdaptedEvent): void {
|
35
|
+
super.onAdditionalPointerAdd(event);
|
36
|
+
this.tracker.addToTracker(event);
|
37
|
+
this.trySettingPosition(event);
|
38
|
+
|
39
|
+
this.offsetX += this.lastX - this.startX;
|
40
|
+
this.offsetY += this.lastY - this.startY;
|
41
|
+
|
42
|
+
this.lastX = this.tracker.getLastAvgX();
|
43
|
+
this.lastY = this.tracker.getLastAvgY();
|
44
|
+
|
45
|
+
this.startX = this.tracker.getLastAvgX();
|
46
|
+
this.startY = this.tracker.getLastAvgY();
|
47
|
+
|
48
|
+
this.updateState(event);
|
49
|
+
}
|
50
|
+
|
51
|
+
onPointerUp(event: AdaptedEvent): void {
|
52
|
+
super.onPointerUp(event);
|
53
|
+
this.lastX = this.tracker.getLastAvgX();
|
54
|
+
this.lastY = this.tracker.getLastAvgY();
|
55
|
+
|
56
|
+
this.tracker.removeFromTracker(event.pointerId);
|
57
|
+
|
58
|
+
this.updateState(event);
|
59
|
+
}
|
60
|
+
|
61
|
+
onAdditionalPointerRemove(event: AdaptedEvent): void {
|
62
|
+
super.onAdditionalPointerRemove(event);
|
63
|
+
this.tracker.removeFromTracker(event.pointerId);
|
64
|
+
|
65
|
+
this.offsetX += this.lastX - this.startX;
|
66
|
+
this.offsetY += this.lastY = this.startY;
|
67
|
+
|
68
|
+
this.lastX = this.tracker.getLastAvgX();
|
69
|
+
this.lastY = this.tracker.getLastAvgY();
|
70
|
+
|
71
|
+
this.startX = this.lastX;
|
72
|
+
this.startY = this.lastY;
|
73
|
+
|
74
|
+
this.updateState(event);
|
75
|
+
}
|
76
|
+
|
77
|
+
onPointerMove(event: AdaptedEvent): void {
|
78
|
+
this.trySettingPosition(event);
|
79
|
+
this.tracker.track(event);
|
80
|
+
|
81
|
+
this.lastX = this.tracker.getLastAvgX();
|
82
|
+
this.lastY = this.tracker.getLastAvgY();
|
83
|
+
|
84
|
+
this.updateState(event);
|
85
|
+
|
86
|
+
super.onPointerMove(event);
|
87
|
+
}
|
88
|
+
|
89
|
+
onPointerOutOfBounds(event: AdaptedEvent): void {
|
90
|
+
this.trySettingPosition(event);
|
91
|
+
this.tracker.track(event);
|
92
|
+
|
93
|
+
this.lastX = this.tracker.getLastAvgX();
|
94
|
+
this.lastY = this.tracker.getLastAvgY();
|
95
|
+
|
96
|
+
this.updateState(event);
|
97
|
+
|
98
|
+
super.onPointerOutOfBounds(event);
|
99
|
+
}
|
100
|
+
|
101
|
+
getDefaultConfig() {
|
102
|
+
return {}
|
103
|
+
}
|
104
|
+
|
105
|
+
private trySettingPosition(event: AdaptedEvent): void {
|
106
|
+
if (this.currentState !== State.UNDETERMINED) return;
|
107
|
+
this.offsetX = 0;
|
108
|
+
this.offsetY = 0;
|
109
|
+
this.startX = event.x;
|
110
|
+
this.startY = event.y;
|
111
|
+
}
|
112
|
+
|
113
|
+
private updateState(event: AdaptedEvent): void {
|
114
|
+
const logger = this.logger.cloneWithPrefix("updateState")
|
115
|
+
if (this.maxNumberOfPointersSoFar < this.tracker.getTrackedPointersCount()) {
|
116
|
+
this.maxNumberOfPointersSoFar = this.tracker.getTrackedPointersCount()
|
117
|
+
}
|
118
|
+
if (this.shouldFail()) {
|
119
|
+
logger.info("fail")
|
120
|
+
this.fail()
|
121
|
+
return;
|
122
|
+
}
|
123
|
+
switch (this.currentState) {
|
124
|
+
case State.UNDETERMINED:
|
125
|
+
if (event.eventType === EventType.DOWN) {
|
126
|
+
this.begin()
|
127
|
+
}
|
128
|
+
this.startTap();
|
129
|
+
break;
|
130
|
+
case State.BEGAN:
|
131
|
+
if (event.eventType === EventType.UP) {
|
132
|
+
logger.info("endTap")
|
133
|
+
this.endTap();
|
134
|
+
}
|
135
|
+
if (event.eventType === EventType.DOWN) {
|
136
|
+
this.startTap();
|
137
|
+
}
|
138
|
+
break;
|
139
|
+
default:
|
140
|
+
logger.info(`default case - currentState ${getStateName(this.currentState)}`)
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
private shouldFail(): boolean {
|
146
|
+
const maxDeltaX = this.config.maxDeltaX ?? Number.MIN_SAFE_INTEGER
|
147
|
+
const maxDeltaY = this.config.maxDeltaY ?? Number.MIN_SAFE_INTEGER
|
148
|
+
const maxDistSq = this.config.maxDistSq ?? Number.MIN_SAFE_INTEGER
|
149
|
+
|
150
|
+
const dx = this.lastX - this.startX + this.offsetX;
|
151
|
+
if (
|
152
|
+
maxDeltaX !== Number.MIN_SAFE_INTEGER &&
|
153
|
+
Math.abs(dx) > maxDeltaX
|
154
|
+
) {
|
155
|
+
return true;
|
156
|
+
}
|
157
|
+
const dy = this.lastY - this.startY + this.offsetY;
|
158
|
+
if (
|
159
|
+
maxDeltaY !== Number.MIN_SAFE_INTEGER &&
|
160
|
+
Math.abs(dy) > maxDeltaY
|
161
|
+
) {
|
162
|
+
return true;
|
163
|
+
}
|
164
|
+
const distSq = dy * dy + dx * dx;
|
165
|
+
const result = maxDistSq !== Number.MIN_SAFE_INTEGER && distSq > maxDistSq
|
166
|
+
return result;
|
167
|
+
}
|
168
|
+
|
169
|
+
private startTap() {
|
170
|
+
this.clearTimeouts();
|
171
|
+
this.waitTimeout = setTimeout(() => this.fail(), this.config.maxDurationMs ?? DEFAULT_MAX_DURATION_MS);
|
172
|
+
}
|
173
|
+
|
174
|
+
private clearTimeouts() {
|
175
|
+
clearTimeout(this.waitTimeout);
|
176
|
+
clearTimeout(this.delayTimeout);
|
177
|
+
}
|
178
|
+
|
179
|
+
private endTap() {
|
180
|
+
this.clearTimeouts();
|
181
|
+
if (
|
182
|
+
++this.numberOfTapsSoFar === (this.config.numberOfTaps ?? DEFAULT_NUMBER_OF_TAPS) &&
|
183
|
+
this.maxNumberOfPointersSoFar >= (this.config.minNumberOfPointers ?? 0)
|
184
|
+
) {
|
185
|
+
this.activate();
|
186
|
+
} else {
|
187
|
+
this.delayTimeout = setTimeout(() => this.fail(), this.config.maxDelayMs ?? DEFAULT_MAX_DELAY_MS);
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
public activate(): void {
|
192
|
+
super.activate();
|
193
|
+
this.end();
|
194
|
+
}
|
195
|
+
|
196
|
+
protected onCancel() {
|
197
|
+
super.onCancel()
|
198
|
+
this.resetProgress()
|
199
|
+
}
|
200
|
+
|
201
|
+
protected resetProgress(): void {
|
202
|
+
this.clearTimeouts();
|
203
|
+
this.numberOfTapsSoFar = 0;
|
204
|
+
this.maxNumberOfPointersSoFar = 0;
|
205
|
+
}
|
206
206
|
}
|
@@ -1,36 +1,36 @@
|
|
1
|
-
export class Vector2D {
|
2
|
-
constructor(
|
3
|
-
private val: {
|
4
|
-
x: number;
|
5
|
-
y: number;
|
6
|
-
} = {x: 0, y: 0},
|
7
|
-
) {}
|
8
|
-
|
9
|
-
get x() {
|
10
|
-
return this.val.x;
|
11
|
-
}
|
12
|
-
|
13
|
-
get y() {
|
14
|
-
return this.val.y;
|
15
|
-
}
|
16
|
-
|
17
|
-
get value() {
|
18
|
-
return {...this.val};
|
19
|
-
}
|
20
|
-
|
21
|
-
public clone() {
|
22
|
-
return new Vector2D({...this.val});
|
23
|
-
}
|
24
|
-
|
25
|
-
public subtract(vec: Vector2D) {
|
26
|
-
this.val.x -= vec.x;
|
27
|
-
this.val.y -= vec.y;
|
28
|
-
return this;
|
29
|
-
}
|
30
|
-
|
31
|
-
public add(vec: Vector2D) {
|
32
|
-
this.val.x += vec.x;
|
33
|
-
this.val.y += vec.y;
|
34
|
-
return this;
|
35
|
-
}
|
36
|
-
}
|
1
|
+
export class Vector2D {
|
2
|
+
constructor(
|
3
|
+
private val: {
|
4
|
+
x: number;
|
5
|
+
y: number;
|
6
|
+
} = {x: 0, y: 0},
|
7
|
+
) {}
|
8
|
+
|
9
|
+
get x() {
|
10
|
+
return this.val.x;
|
11
|
+
}
|
12
|
+
|
13
|
+
get y() {
|
14
|
+
return this.val.y;
|
15
|
+
}
|
16
|
+
|
17
|
+
get value() {
|
18
|
+
return {...this.val};
|
19
|
+
}
|
20
|
+
|
21
|
+
public clone() {
|
22
|
+
return new Vector2D({...this.val});
|
23
|
+
}
|
24
|
+
|
25
|
+
public subtract(vec: Vector2D) {
|
26
|
+
this.val.x -= vec.x;
|
27
|
+
this.val.y -= vec.y;
|
28
|
+
return this;
|
29
|
+
}
|
30
|
+
|
31
|
+
public add(vec: Vector2D) {
|
32
|
+
this.val.x += vec.x;
|
33
|
+
this.val.y += vec.y;
|
34
|
+
return this;
|
35
|
+
}
|
36
|
+
}
|
@@ -1,98 +1,98 @@
|
|
1
|
-
import { AdaptedEvent } from './Event';
|
2
|
-
import { CircularBuffer } from './CircularBuffer';
|
3
|
-
import { LeastSquareSolver } from './LeastSquareSolver';
|
4
|
-
|
5
|
-
export default class VelocityTracker {
|
6
|
-
private assumePointerMoveStoppedMilliseconds = 40;
|
7
|
-
private historySize = 20;
|
8
|
-
private horizonMilliseconds = 300;
|
9
|
-
private minSampleSize = 3;
|
10
|
-
|
11
|
-
private samples: CircularBuffer<AdaptedEvent>;
|
12
|
-
|
13
|
-
constructor() {
|
14
|
-
this.samples = new CircularBuffer<AdaptedEvent>(this.historySize);
|
15
|
-
}
|
16
|
-
|
17
|
-
public add(event: AdaptedEvent): void {
|
18
|
-
this.samples.push(event);
|
19
|
-
}
|
20
|
-
|
21
|
-
/// Returns an estimate of the velocity of the object being tracked by the
|
22
|
-
/// tracker given the current information available to the tracker.
|
23
|
-
///
|
24
|
-
/// Information is added using [addPosition].
|
25
|
-
///
|
26
|
-
/// Returns null if there is no data on which to base an estimate.
|
27
|
-
private getVelocityEstimate(): [number, number] | null {
|
28
|
-
const x = [];
|
29
|
-
const y = [];
|
30
|
-
const w = [];
|
31
|
-
const time = [];
|
32
|
-
|
33
|
-
let sampleCount = 0;
|
34
|
-
let index = this.samples.size - 1;
|
35
|
-
const newestSample = this.samples.get(index);
|
36
|
-
if (!newestSample) {
|
37
|
-
return null;
|
38
|
-
}
|
39
|
-
|
40
|
-
let previousSample = newestSample;
|
41
|
-
|
42
|
-
// Starting with the most recent PointAtTime sample, iterate backwards while
|
43
|
-
// the samples represent continuous motion.
|
44
|
-
while (sampleCount < this.samples.size) {
|
45
|
-
const sample = this.samples.get(index);
|
46
|
-
|
47
|
-
const age = newestSample.time - sample.time;
|
48
|
-
const delta = Math.abs(sample.time - previousSample.time);
|
49
|
-
previousSample = sample;
|
50
|
-
|
51
|
-
if (
|
52
|
-
age > this.horizonMilliseconds ||
|
53
|
-
delta > this.assumePointerMoveStoppedMilliseconds
|
54
|
-
) {
|
55
|
-
break;
|
56
|
-
}
|
57
|
-
|
58
|
-
x.push(sample.x);
|
59
|
-
y.push(sample.y);
|
60
|
-
w.push(1);
|
61
|
-
time.push(-age);
|
62
|
-
|
63
|
-
sampleCount++;
|
64
|
-
index--;
|
65
|
-
}
|
66
|
-
|
67
|
-
if (sampleCount >= this.minSampleSize) {
|
68
|
-
const xSolver = new LeastSquareSolver(time, x, w);
|
69
|
-
const xFit = xSolver.solve(2);
|
70
|
-
|
71
|
-
if (xFit !== null) {
|
72
|
-
const ySolver = new LeastSquareSolver(time, y, w);
|
73
|
-
const yFit = ySolver.solve(2);
|
74
|
-
|
75
|
-
if (yFit !== null) {
|
76
|
-
const xVelocity = xFit.coefficients[1] * 1000;
|
77
|
-
const yVelocity = yFit.coefficients[1] * 1000;
|
78
|
-
|
79
|
-
return [xVelocity, yVelocity];
|
80
|
-
}
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
return null;
|
85
|
-
}
|
86
|
-
|
87
|
-
public getVelocity(): [number, number] {
|
88
|
-
const estimate = this.getVelocityEstimate();
|
89
|
-
if (estimate !== null) {
|
90
|
-
return estimate;
|
91
|
-
}
|
92
|
-
return [0, 0];
|
93
|
-
}
|
94
|
-
|
95
|
-
public reset(): void {
|
96
|
-
this.samples.clear();
|
97
|
-
}
|
98
|
-
}
|
1
|
+
import { AdaptedEvent } from './Event';
|
2
|
+
import { CircularBuffer } from './CircularBuffer';
|
3
|
+
import { LeastSquareSolver } from './LeastSquareSolver';
|
4
|
+
|
5
|
+
export default class VelocityTracker {
|
6
|
+
private assumePointerMoveStoppedMilliseconds = 40;
|
7
|
+
private historySize = 20;
|
8
|
+
private horizonMilliseconds = 300;
|
9
|
+
private minSampleSize = 3;
|
10
|
+
|
11
|
+
private samples: CircularBuffer<AdaptedEvent>;
|
12
|
+
|
13
|
+
constructor() {
|
14
|
+
this.samples = new CircularBuffer<AdaptedEvent>(this.historySize);
|
15
|
+
}
|
16
|
+
|
17
|
+
public add(event: AdaptedEvent): void {
|
18
|
+
this.samples.push(event);
|
19
|
+
}
|
20
|
+
|
21
|
+
/// Returns an estimate of the velocity of the object being tracked by the
|
22
|
+
/// tracker given the current information available to the tracker.
|
23
|
+
///
|
24
|
+
/// Information is added using [addPosition].
|
25
|
+
///
|
26
|
+
/// Returns null if there is no data on which to base an estimate.
|
27
|
+
private getVelocityEstimate(): [number, number] | null {
|
28
|
+
const x = [];
|
29
|
+
const y = [];
|
30
|
+
const w = [];
|
31
|
+
const time = [];
|
32
|
+
|
33
|
+
let sampleCount = 0;
|
34
|
+
let index = this.samples.size - 1;
|
35
|
+
const newestSample = this.samples.get(index);
|
36
|
+
if (!newestSample) {
|
37
|
+
return null;
|
38
|
+
}
|
39
|
+
|
40
|
+
let previousSample = newestSample;
|
41
|
+
|
42
|
+
// Starting with the most recent PointAtTime sample, iterate backwards while
|
43
|
+
// the samples represent continuous motion.
|
44
|
+
while (sampleCount < this.samples.size) {
|
45
|
+
const sample = this.samples.get(index);
|
46
|
+
|
47
|
+
const age = newestSample.time - sample.time;
|
48
|
+
const delta = Math.abs(sample.time - previousSample.time);
|
49
|
+
previousSample = sample;
|
50
|
+
|
51
|
+
if (
|
52
|
+
age > this.horizonMilliseconds ||
|
53
|
+
delta > this.assumePointerMoveStoppedMilliseconds
|
54
|
+
) {
|
55
|
+
break;
|
56
|
+
}
|
57
|
+
|
58
|
+
x.push(sample.x);
|
59
|
+
y.push(sample.y);
|
60
|
+
w.push(1);
|
61
|
+
time.push(-age);
|
62
|
+
|
63
|
+
sampleCount++;
|
64
|
+
index--;
|
65
|
+
}
|
66
|
+
|
67
|
+
if (sampleCount >= this.minSampleSize) {
|
68
|
+
const xSolver = new LeastSquareSolver(time, x, w);
|
69
|
+
const xFit = xSolver.solve(2);
|
70
|
+
|
71
|
+
if (xFit !== null) {
|
72
|
+
const ySolver = new LeastSquareSolver(time, y, w);
|
73
|
+
const yFit = ySolver.solve(2);
|
74
|
+
|
75
|
+
if (yFit !== null) {
|
76
|
+
const xVelocity = xFit.coefficients[1] * 1000;
|
77
|
+
const yVelocity = yFit.coefficients[1] * 1000;
|
78
|
+
|
79
|
+
return [xVelocity, yVelocity];
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
return null;
|
85
|
+
}
|
86
|
+
|
87
|
+
public getVelocity(): [number, number] {
|
88
|
+
const estimate = this.getVelocityEstimate();
|
89
|
+
if (estimate !== null) {
|
90
|
+
return estimate;
|
91
|
+
}
|
92
|
+
return [0, 0];
|
93
|
+
}
|
94
|
+
|
95
|
+
public reset(): void {
|
96
|
+
this.samples.clear();
|
97
|
+
}
|
98
|
+
}
|