@react-native-oh-tpl/react-native-gesture-handler 2.12.6-1 → 2.12.6-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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,328 +1,328 @@
|
|
|
1
|
-
import { GestureHandler, GestureConfig, GestureHandlerDependencies, DEFAULT_TOUCH_SLOP } from "./GestureHandler"
|
|
2
|
-
import { AdaptedEvent } from "./Event"
|
|
3
|
-
import { State } from "./State"
|
|
4
|
-
import { Vector2D } from "./Vector2D"
|
|
5
|
-
|
|
6
|
-
const DEFAULT_MIN_DIST_SQ = DEFAULT_TOUCH_SLOP * DEFAULT_TOUCH_SLOP;
|
|
7
|
-
|
|
8
|
-
type PanGestureHandlerConfig = GestureConfig
|
|
9
|
-
|
|
10
|
-
export class PanGestureHandler extends GestureHandler<PanGestureHandlerConfig> {
|
|
11
|
-
private startPos = new Vector2D();
|
|
12
|
-
private offset = new Vector2D()
|
|
13
|
-
private lastPos = new Vector2D();
|
|
14
|
-
private velocity = new Vector2D();
|
|
15
|
-
private activationTimeout = 0;
|
|
16
|
-
|
|
17
|
-
private get failOffsetXStart() {
|
|
18
|
-
if (this.config.failOffsetXStart === undefined
|
|
19
|
-
&& this.config.failOffsetXEnd === undefined)
|
|
20
|
-
return undefined
|
|
21
|
-
return this.config.failOffsetXStart ?? Number.MIN_SAFE_INTEGER
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
private get failOffsetXEnd() {
|
|
25
|
-
if (this.config.failOffsetXStart === undefined
|
|
26
|
-
&& this.config.failOffsetXEnd === undefined)
|
|
27
|
-
return undefined
|
|
28
|
-
return this.config.failOffsetXEnd ?? Number.MAX_SAFE_INTEGER
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private get failOffsetYStart() {
|
|
32
|
-
if (this.config.failOffsetYStart === undefined
|
|
33
|
-
&& this.config.failOffsetYEnd === undefined)
|
|
34
|
-
return undefined
|
|
35
|
-
return this.config.failOffsetYStart ?? Number.MIN_SAFE_INTEGER
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private get failOffsetYEnd() {
|
|
39
|
-
return this.config.failOffsetYEnd ?? Number.MAX_SAFE_INTEGER
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private get activeOffsetXStart() {
|
|
43
|
-
if (this.config.activeOffsetXStart === undefined
|
|
44
|
-
&& this.config.activeOffsetXEnd === undefined)
|
|
45
|
-
return undefined
|
|
46
|
-
return this.config.activeOffsetXStart ?? Number.MIN_SAFE_INTEGER
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private get activeOffsetXEnd() {
|
|
50
|
-
if (this.config.activeOffsetXStart === undefined
|
|
51
|
-
&& this.config.activeOffsetXEnd === undefined)
|
|
52
|
-
return undefined
|
|
53
|
-
return this.config.activeOffsetXEnd ?? Number.MAX_SAFE_INTEGER
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private get activeOffsetYStart() {
|
|
57
|
-
if (this.config.activeOffsetYStart === undefined
|
|
58
|
-
&& this.config.activeOffsetYEnd === undefined)
|
|
59
|
-
return undefined
|
|
60
|
-
return this.config.activeOffsetYStart ?? Number.MIN_SAFE_INTEGER
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private get activeOffsetYEnd() {
|
|
64
|
-
if (this.config.activeOffsetYStart === undefined
|
|
65
|
-
&& this.config.activeOffsetYEnd === undefined)
|
|
66
|
-
return undefined
|
|
67
|
-
return this.config.activeOffsetYEnd ?? Number.MAX_SAFE_INTEGER
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private get minVelocityX() {
|
|
71
|
-
return this.config.minVelocityX ?? this.config.minVelocity ?? Number.MAX_SAFE_INTEGER
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
private get minVelocityY() {
|
|
75
|
-
return this.config.minVelocityY ?? this.config.minVelocityY ?? Number.MAX_SAFE_INTEGER
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private minVelocitySq = Number.MAX_SAFE_INTEGER
|
|
79
|
-
|
|
80
|
-
private get minPointers() {
|
|
81
|
-
return this.config.minPointers ?? 1
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private unlockScrolls: (() => void) | undefined
|
|
85
|
-
|
|
86
|
-
public constructor(deps: GestureHandlerDependencies) {
|
|
87
|
-
super({ ...deps, logger: deps.logger.cloneWithPrefix("PanGestureHandler") })
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
public onPointerDown(e) {
|
|
91
|
-
this.tracker.addToTracker(e);
|
|
92
|
-
super.onPointerDown(e);
|
|
93
|
-
this.lastPos = this.tracker.getLastAvgPos()
|
|
94
|
-
this.startPos = this.lastPos.clone()
|
|
95
|
-
this.tryBegin(e);
|
|
96
|
-
this.tryActivating();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private tryActivating(): void {
|
|
100
|
-
if (this.currentState === State.BEGAN) {
|
|
101
|
-
if (this.shouldFail()) {
|
|
102
|
-
this.fail();
|
|
103
|
-
} else if (this.shouldActivate()) {
|
|
104
|
-
this.activate();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
private shouldFail(): boolean {
|
|
110
|
-
const {x: dx, y: dy} = this.getTranslation().value;
|
|
111
|
-
const distanceSq = dx * dx + dy * dy;
|
|
112
|
-
if (this.activateAfterLongPress > 0 && distanceSq > DEFAULT_MIN_DIST_SQ) {
|
|
113
|
-
this.clearActivationTimeout();
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
if (this.failOffsetXStart !== Number.MIN_SAFE_INTEGER && dx < this.failOffsetXStart) {
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
if (this.failOffsetXEnd !== Number.MAX_SAFE_INTEGER && dx > this.failOffsetXEnd) {
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
if (this.failOffsetYStart !== Number.MIN_SAFE_INTEGER && dy < this.failOffsetYStart) {
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
return (this.failOffsetYEnd !== Number.MAX_SAFE_INTEGER && dy > this.failOffsetYEnd);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private getTranslation() {
|
|
129
|
-
return this.lastPos.clone().subtract(this.startPos).add(this.offset)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
private shouldActivate(): boolean {
|
|
133
|
-
const {x: dx, y: dy} = this.getTranslation().value;
|
|
134
|
-
if (this.activeOffsetXStart !== Number.MAX_SAFE_INTEGER && dx < this.activeOffsetXStart
|
|
135
|
-
) {
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
if (this.activeOffsetXEnd !== Number.MIN_SAFE_INTEGER && dx > this.activeOffsetXEnd) {
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
if (this.activeOffsetYStart !== Number.MAX_SAFE_INTEGER && dy < this.activeOffsetYStart) {
|
|
142
|
-
return true;
|
|
143
|
-
}
|
|
144
|
-
if (this.activeOffsetYEnd !== Number.MIN_SAFE_INTEGER && dy > this.activeOffsetYEnd) {
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
147
|
-
const distanceSq: number = dx * dx + dy * dy;
|
|
148
|
-
if (this.minDistSq !== Number.MAX_SAFE_INTEGER && distanceSq >= this.minDistSq) {
|
|
149
|
-
return true;
|
|
150
|
-
}
|
|
151
|
-
const {x: vx, y: vy} = this.velocity
|
|
152
|
-
if (
|
|
153
|
-
this.minVelocityX !== Number.MAX_SAFE_INTEGER &&
|
|
154
|
-
((this.minVelocityX < 0 && vx <= this.minVelocityX) ||
|
|
155
|
-
(this.minVelocityX >= 0 && this.minVelocityX <= vx))
|
|
156
|
-
) {
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
if (
|
|
160
|
-
this.minVelocityY !== Number.MAX_SAFE_INTEGER &&
|
|
161
|
-
((this.minVelocityY < 0 && vy <= this.minVelocityY) ||
|
|
162
|
-
(this.minVelocityY >= 0 && this.minVelocityY <= vy))
|
|
163
|
-
) {
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
const velocitySq: number = vx * vx + vy * vy;
|
|
167
|
-
return (
|
|
168
|
-
this.minVelocitySq !== Number.MAX_SAFE_INTEGER &&
|
|
169
|
-
velocitySq >= this.minVelocitySq
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
private clearActivationTimeout(): void {
|
|
174
|
-
clearTimeout(this.activationTimeout);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
private tryBegin(e: AdaptedEvent): void {
|
|
178
|
-
if (
|
|
179
|
-
this.currentState === State.UNDETERMINED &&
|
|
180
|
-
this.tracker.getTrackedPointersCount() >= this.minPointers
|
|
181
|
-
) {
|
|
182
|
-
this.resetProgress();
|
|
183
|
-
this.offset = new Vector2D();
|
|
184
|
-
this.velocity = new Vector2D();
|
|
185
|
-
|
|
186
|
-
this.begin();
|
|
187
|
-
|
|
188
|
-
if (this.activateAfterLongPress > 0) {
|
|
189
|
-
this.activationTimeout = setTimeout(() => {
|
|
190
|
-
this.activate();
|
|
191
|
-
}, this.activateAfterLongPress);
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
this.velocity = this.tracker.getVelocity(e.pointerId)
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
public getDefaultConfig() {
|
|
199
|
-
return {}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private get activateAfterLongPress() {
|
|
203
|
-
return this.config.activateAfterLongPress ?? 0
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
private get minDistSq() {
|
|
207
|
-
if (this.config.minDist !== undefined) {
|
|
208
|
-
return this.config.minDist * this.config.minDist;
|
|
209
|
-
} else if (this.hasCustomActivationCriteria()) {
|
|
210
|
-
return Number.MAX_SAFE_INTEGER;
|
|
211
|
-
}
|
|
212
|
-
return DEFAULT_MIN_DIST_SQ
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
private hasCustomActivationCriteria() {
|
|
216
|
-
const criterias: (keyof PanGestureHandlerConfig)[] = [
|
|
217
|
-
'activeOffsetXStart',
|
|
218
|
-
'activeOffsetXEnd',
|
|
219
|
-
'failOffsetXStart',
|
|
220
|
-
'failOffsetXEnd',
|
|
221
|
-
'activeOffsetYStart',
|
|
222
|
-
'activeOffsetYEnd',
|
|
223
|
-
'failOffsetYStart',
|
|
224
|
-
'failOffsetYEnd',
|
|
225
|
-
'minVelocityX',
|
|
226
|
-
'minVelocityY',
|
|
227
|
-
]
|
|
228
|
-
for (const key in this.config) {
|
|
229
|
-
if (criterias.indexOf(key as keyof PanGestureHandlerConfig) >= 0) {
|
|
230
|
-
return true
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return false
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
public onAdditionalPointerAdd(event: AdaptedEvent): void {
|
|
237
|
-
this.tracker.addToTracker(event);
|
|
238
|
-
super.onAdditionalPointerAdd(event);
|
|
239
|
-
this.tryBegin(event);
|
|
240
|
-
this.offset.add(this.lastPos).subtract(this.startPos)
|
|
241
|
-
this.lastPos = this.tracker.getLastAvgPos()
|
|
242
|
-
this.startPos = this.lastPos.clone()
|
|
243
|
-
if (this.tracker.getTrackedPointersCount() > (this.config.maxPointers ?? 10)) {
|
|
244
|
-
if (this.currentState === State.ACTIVE) {
|
|
245
|
-
this.cancel();
|
|
246
|
-
} else {
|
|
247
|
-
this.fail();
|
|
248
|
-
}
|
|
249
|
-
} else {
|
|
250
|
-
this.tryActivating();
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
public onPointerUp(event: AdaptedEvent): void {
|
|
255
|
-
super.onPointerUp(event);
|
|
256
|
-
if (this.currentState === State.ACTIVE) {
|
|
257
|
-
this.lastPos = this.tracker.getLastAvgPos();
|
|
258
|
-
}
|
|
259
|
-
this.tracker.removeFromTracker(event.pointerId);
|
|
260
|
-
if (this.currentState === State.ACTIVE) {
|
|
261
|
-
this.end();
|
|
262
|
-
} else {
|
|
263
|
-
this.resetProgress();
|
|
264
|
-
this.fail();
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
public onAdditionalPointerRemove(event: AdaptedEvent): void {
|
|
269
|
-
super.onAdditionalPointerRemove(event);
|
|
270
|
-
this.tracker.removeFromTracker(event.pointerId);
|
|
271
|
-
this.offset.add(this.lastPos).subtract(this.startPos)
|
|
272
|
-
this.lastPos = this.tracker.getLastAvgPos()
|
|
273
|
-
this.startPos = this.lastPos.clone()
|
|
274
|
-
if (
|
|
275
|
-
!(
|
|
276
|
-
this.currentState === State.ACTIVE &&
|
|
277
|
-
this.tracker.getTrackedPointersCount() < this.minPointers
|
|
278
|
-
)
|
|
279
|
-
) {
|
|
280
|
-
this.tryActivating();
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
public onPointerMove(event: AdaptedEvent): void {
|
|
285
|
-
this.tracker.track(event);
|
|
286
|
-
this.lastPos = this.tracker.getLastAvgPos()
|
|
287
|
-
this.velocity = this.tracker.getVelocity(event.pointerId)
|
|
288
|
-
this.tryActivating();
|
|
289
|
-
super.onPointerMove(event);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
public onPointerOutOfBounds(event: AdaptedEvent): void {
|
|
293
|
-
if (this.shouldCancelWhenOutside) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
this.tracker.track(event);
|
|
297
|
-
this.lastPos = this.tracker.getLastAvgPos()
|
|
298
|
-
this.velocity = this.tracker.getVelocity(event.pointerId)
|
|
299
|
-
this.tryActivating();
|
|
300
|
-
if (this.currentState === State.ACTIVE) {
|
|
301
|
-
super.onPointerOutOfBounds(event);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
protected transformNativeEvent() {
|
|
306
|
-
const rect = this.view.getBoundingRect();
|
|
307
|
-
const translation = this.getTranslation()
|
|
308
|
-
return {
|
|
309
|
-
translationX: translation.x,
|
|
310
|
-
translationY: translation.y,
|
|
311
|
-
absoluteX: this.tracker.getLastAvgX(),
|
|
312
|
-
absoluteY: this.tracker.getLastAvgY(),
|
|
313
|
-
velocityX: this.velocity.x,
|
|
314
|
-
velocityY: this.velocity.y,
|
|
315
|
-
x: this.tracker.getLastAvgX() - rect.x,
|
|
316
|
-
y: this.tracker.getLastAvgY() - rect.y,
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
protected stateDidChange(newState: State, oldState: State) {
|
|
321
|
-
super.stateDidChange(newState, oldState)
|
|
322
|
-
if (newState === State.BEGAN) {
|
|
323
|
-
this.unlockScrolls = this.scrollLocker.lockScrollContainingViewTag(this.view.getTag())
|
|
324
|
-
} else if (newState !== State.ACTIVE) {
|
|
325
|
-
this.unlockScrolls?.()
|
|
326
|
-
}
|
|
327
|
-
}
|
|
1
|
+
import { GestureHandler, GestureConfig, GestureHandlerDependencies, DEFAULT_TOUCH_SLOP } from "./GestureHandler"
|
|
2
|
+
import { AdaptedEvent } from "./Event"
|
|
3
|
+
import { State } from "./State"
|
|
4
|
+
import { Vector2D } from "./Vector2D"
|
|
5
|
+
|
|
6
|
+
const DEFAULT_MIN_DIST_SQ = DEFAULT_TOUCH_SLOP * DEFAULT_TOUCH_SLOP;
|
|
7
|
+
|
|
8
|
+
type PanGestureHandlerConfig = GestureConfig
|
|
9
|
+
|
|
10
|
+
export class PanGestureHandler extends GestureHandler<PanGestureHandlerConfig> {
|
|
11
|
+
private startPos = new Vector2D();
|
|
12
|
+
private offset = new Vector2D()
|
|
13
|
+
private lastPos = new Vector2D();
|
|
14
|
+
private velocity = new Vector2D();
|
|
15
|
+
private activationTimeout = 0;
|
|
16
|
+
|
|
17
|
+
private get failOffsetXStart() {
|
|
18
|
+
if (this.config.failOffsetXStart === undefined
|
|
19
|
+
&& this.config.failOffsetXEnd === undefined)
|
|
20
|
+
return undefined
|
|
21
|
+
return this.config.failOffsetXStart ?? Number.MIN_SAFE_INTEGER
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private get failOffsetXEnd() {
|
|
25
|
+
if (this.config.failOffsetXStart === undefined
|
|
26
|
+
&& this.config.failOffsetXEnd === undefined)
|
|
27
|
+
return undefined
|
|
28
|
+
return this.config.failOffsetXEnd ?? Number.MAX_SAFE_INTEGER
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private get failOffsetYStart() {
|
|
32
|
+
if (this.config.failOffsetYStart === undefined
|
|
33
|
+
&& this.config.failOffsetYEnd === undefined)
|
|
34
|
+
return undefined
|
|
35
|
+
return this.config.failOffsetYStart ?? Number.MIN_SAFE_INTEGER
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private get failOffsetYEnd() {
|
|
39
|
+
return this.config.failOffsetYEnd ?? Number.MAX_SAFE_INTEGER
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private get activeOffsetXStart() {
|
|
43
|
+
if (this.config.activeOffsetXStart === undefined
|
|
44
|
+
&& this.config.activeOffsetXEnd === undefined)
|
|
45
|
+
return undefined
|
|
46
|
+
return this.config.activeOffsetXStart ?? Number.MIN_SAFE_INTEGER
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private get activeOffsetXEnd() {
|
|
50
|
+
if (this.config.activeOffsetXStart === undefined
|
|
51
|
+
&& this.config.activeOffsetXEnd === undefined)
|
|
52
|
+
return undefined
|
|
53
|
+
return this.config.activeOffsetXEnd ?? Number.MAX_SAFE_INTEGER
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private get activeOffsetYStart() {
|
|
57
|
+
if (this.config.activeOffsetYStart === undefined
|
|
58
|
+
&& this.config.activeOffsetYEnd === undefined)
|
|
59
|
+
return undefined
|
|
60
|
+
return this.config.activeOffsetYStart ?? Number.MIN_SAFE_INTEGER
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private get activeOffsetYEnd() {
|
|
64
|
+
if (this.config.activeOffsetYStart === undefined
|
|
65
|
+
&& this.config.activeOffsetYEnd === undefined)
|
|
66
|
+
return undefined
|
|
67
|
+
return this.config.activeOffsetYEnd ?? Number.MAX_SAFE_INTEGER
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private get minVelocityX() {
|
|
71
|
+
return this.config.minVelocityX ?? this.config.minVelocity ?? Number.MAX_SAFE_INTEGER
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private get minVelocityY() {
|
|
75
|
+
return this.config.minVelocityY ?? this.config.minVelocityY ?? Number.MAX_SAFE_INTEGER
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private minVelocitySq = Number.MAX_SAFE_INTEGER
|
|
79
|
+
|
|
80
|
+
private get minPointers() {
|
|
81
|
+
return this.config.minPointers ?? 1
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private unlockScrolls: (() => void) | undefined
|
|
85
|
+
|
|
86
|
+
public constructor(deps: GestureHandlerDependencies) {
|
|
87
|
+
super({ ...deps, logger: deps.logger.cloneWithPrefix("PanGestureHandler") })
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public onPointerDown(e) {
|
|
91
|
+
this.tracker.addToTracker(e);
|
|
92
|
+
super.onPointerDown(e);
|
|
93
|
+
this.lastPos = this.tracker.getLastAvgPos()
|
|
94
|
+
this.startPos = this.lastPos.clone()
|
|
95
|
+
this.tryBegin(e);
|
|
96
|
+
this.tryActivating();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private tryActivating(): void {
|
|
100
|
+
if (this.currentState === State.BEGAN) {
|
|
101
|
+
if (this.shouldFail()) {
|
|
102
|
+
this.fail();
|
|
103
|
+
} else if (this.shouldActivate()) {
|
|
104
|
+
this.activate();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private shouldFail(): boolean {
|
|
110
|
+
const {x: dx, y: dy} = this.getTranslation().value;
|
|
111
|
+
const distanceSq = dx * dx + dy * dy;
|
|
112
|
+
if (this.activateAfterLongPress > 0 && distanceSq > DEFAULT_MIN_DIST_SQ) {
|
|
113
|
+
this.clearActivationTimeout();
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (this.failOffsetXStart !== Number.MIN_SAFE_INTEGER && dx < this.failOffsetXStart) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
if (this.failOffsetXEnd !== Number.MAX_SAFE_INTEGER && dx > this.failOffsetXEnd) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
if (this.failOffsetYStart !== Number.MIN_SAFE_INTEGER && dy < this.failOffsetYStart) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
return (this.failOffsetYEnd !== Number.MAX_SAFE_INTEGER && dy > this.failOffsetYEnd);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private getTranslation() {
|
|
129
|
+
return this.lastPos.clone().subtract(this.startPos).add(this.offset)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private shouldActivate(): boolean {
|
|
133
|
+
const {x: dx, y: dy} = this.getTranslation().value;
|
|
134
|
+
if (this.activeOffsetXStart !== Number.MAX_SAFE_INTEGER && dx < this.activeOffsetXStart
|
|
135
|
+
) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
if (this.activeOffsetXEnd !== Number.MIN_SAFE_INTEGER && dx > this.activeOffsetXEnd) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
if (this.activeOffsetYStart !== Number.MAX_SAFE_INTEGER && dy < this.activeOffsetYStart) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
if (this.activeOffsetYEnd !== Number.MIN_SAFE_INTEGER && dy > this.activeOffsetYEnd) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
const distanceSq: number = dx * dx + dy * dy;
|
|
148
|
+
if (this.minDistSq !== Number.MAX_SAFE_INTEGER && distanceSq >= this.minDistSq) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
const {x: vx, y: vy} = this.velocity
|
|
152
|
+
if (
|
|
153
|
+
this.minVelocityX !== Number.MAX_SAFE_INTEGER &&
|
|
154
|
+
((this.minVelocityX < 0 && vx <= this.minVelocityX) ||
|
|
155
|
+
(this.minVelocityX >= 0 && this.minVelocityX <= vx))
|
|
156
|
+
) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
if (
|
|
160
|
+
this.minVelocityY !== Number.MAX_SAFE_INTEGER &&
|
|
161
|
+
((this.minVelocityY < 0 && vy <= this.minVelocityY) ||
|
|
162
|
+
(this.minVelocityY >= 0 && this.minVelocityY <= vy))
|
|
163
|
+
) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
const velocitySq: number = vx * vx + vy * vy;
|
|
167
|
+
return (
|
|
168
|
+
this.minVelocitySq !== Number.MAX_SAFE_INTEGER &&
|
|
169
|
+
velocitySq >= this.minVelocitySq
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private clearActivationTimeout(): void {
|
|
174
|
+
clearTimeout(this.activationTimeout);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private tryBegin(e: AdaptedEvent): void {
|
|
178
|
+
if (
|
|
179
|
+
this.currentState === State.UNDETERMINED &&
|
|
180
|
+
this.tracker.getTrackedPointersCount() >= this.minPointers
|
|
181
|
+
) {
|
|
182
|
+
this.resetProgress();
|
|
183
|
+
this.offset = new Vector2D();
|
|
184
|
+
this.velocity = new Vector2D();
|
|
185
|
+
|
|
186
|
+
this.begin();
|
|
187
|
+
|
|
188
|
+
if (this.activateAfterLongPress > 0) {
|
|
189
|
+
this.activationTimeout = setTimeout(() => {
|
|
190
|
+
this.activate();
|
|
191
|
+
}, this.activateAfterLongPress);
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
this.velocity = this.tracker.getVelocity(e.pointerId)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
public getDefaultConfig() {
|
|
199
|
+
return {}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private get activateAfterLongPress() {
|
|
203
|
+
return this.config.activateAfterLongPress ?? 0
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private get minDistSq() {
|
|
207
|
+
if (this.config.minDist !== undefined) {
|
|
208
|
+
return this.config.minDist * this.config.minDist;
|
|
209
|
+
} else if (this.hasCustomActivationCriteria()) {
|
|
210
|
+
return Number.MAX_SAFE_INTEGER;
|
|
211
|
+
}
|
|
212
|
+
return DEFAULT_MIN_DIST_SQ
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private hasCustomActivationCriteria() {
|
|
216
|
+
const criterias: (keyof PanGestureHandlerConfig)[] = [
|
|
217
|
+
'activeOffsetXStart',
|
|
218
|
+
'activeOffsetXEnd',
|
|
219
|
+
'failOffsetXStart',
|
|
220
|
+
'failOffsetXEnd',
|
|
221
|
+
'activeOffsetYStart',
|
|
222
|
+
'activeOffsetYEnd',
|
|
223
|
+
'failOffsetYStart',
|
|
224
|
+
'failOffsetYEnd',
|
|
225
|
+
'minVelocityX',
|
|
226
|
+
'minVelocityY',
|
|
227
|
+
]
|
|
228
|
+
for (const key in this.config) {
|
|
229
|
+
if (criterias.indexOf(key as keyof PanGestureHandlerConfig) >= 0) {
|
|
230
|
+
return true
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return false
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public onAdditionalPointerAdd(event: AdaptedEvent): void {
|
|
237
|
+
this.tracker.addToTracker(event);
|
|
238
|
+
super.onAdditionalPointerAdd(event);
|
|
239
|
+
this.tryBegin(event);
|
|
240
|
+
this.offset.add(this.lastPos).subtract(this.startPos)
|
|
241
|
+
this.lastPos = this.tracker.getLastAvgPos()
|
|
242
|
+
this.startPos = this.lastPos.clone()
|
|
243
|
+
if (this.tracker.getTrackedPointersCount() > (this.config.maxPointers ?? 10)) {
|
|
244
|
+
if (this.currentState === State.ACTIVE) {
|
|
245
|
+
this.cancel();
|
|
246
|
+
} else {
|
|
247
|
+
this.fail();
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
this.tryActivating();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public onPointerUp(event: AdaptedEvent): void {
|
|
255
|
+
super.onPointerUp(event);
|
|
256
|
+
if (this.currentState === State.ACTIVE) {
|
|
257
|
+
this.lastPos = this.tracker.getLastAvgPos();
|
|
258
|
+
}
|
|
259
|
+
this.tracker.removeFromTracker(event.pointerId);
|
|
260
|
+
if (this.currentState === State.ACTIVE) {
|
|
261
|
+
this.end();
|
|
262
|
+
} else {
|
|
263
|
+
this.resetProgress();
|
|
264
|
+
this.fail();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
public onAdditionalPointerRemove(event: AdaptedEvent): void {
|
|
269
|
+
super.onAdditionalPointerRemove(event);
|
|
270
|
+
this.tracker.removeFromTracker(event.pointerId);
|
|
271
|
+
this.offset.add(this.lastPos).subtract(this.startPos)
|
|
272
|
+
this.lastPos = this.tracker.getLastAvgPos()
|
|
273
|
+
this.startPos = this.lastPos.clone()
|
|
274
|
+
if (
|
|
275
|
+
!(
|
|
276
|
+
this.currentState === State.ACTIVE &&
|
|
277
|
+
this.tracker.getTrackedPointersCount() < this.minPointers
|
|
278
|
+
)
|
|
279
|
+
) {
|
|
280
|
+
this.tryActivating();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
public onPointerMove(event: AdaptedEvent): void {
|
|
285
|
+
this.tracker.track(event);
|
|
286
|
+
this.lastPos = this.tracker.getLastAvgPos()
|
|
287
|
+
this.velocity = this.tracker.getVelocity(event.pointerId)
|
|
288
|
+
this.tryActivating();
|
|
289
|
+
super.onPointerMove(event);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public onPointerOutOfBounds(event: AdaptedEvent): void {
|
|
293
|
+
if (this.shouldCancelWhenOutside) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
this.tracker.track(event);
|
|
297
|
+
this.lastPos = this.tracker.getLastAvgPos()
|
|
298
|
+
this.velocity = this.tracker.getVelocity(event.pointerId)
|
|
299
|
+
this.tryActivating();
|
|
300
|
+
if (this.currentState === State.ACTIVE) {
|
|
301
|
+
super.onPointerOutOfBounds(event);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
protected transformNativeEvent() {
|
|
306
|
+
const rect = this.view.getBoundingRect();
|
|
307
|
+
const translation = this.getTranslation()
|
|
308
|
+
return {
|
|
309
|
+
translationX: translation.x,
|
|
310
|
+
translationY: translation.y,
|
|
311
|
+
absoluteX: this.tracker.getLastAvgX(),
|
|
312
|
+
absoluteY: this.tracker.getLastAvgY(),
|
|
313
|
+
velocityX: this.velocity.x,
|
|
314
|
+
velocityY: this.velocity.y,
|
|
315
|
+
x: this.tracker.getLastAvgX() - rect.x,
|
|
316
|
+
y: this.tracker.getLastAvgY() - rect.y,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
protected stateDidChange(newState: State, oldState: State) {
|
|
321
|
+
super.stateDidChange(newState, oldState)
|
|
322
|
+
if (newState === State.BEGAN) {
|
|
323
|
+
this.unlockScrolls = this.scrollLocker.lockScrollContainingViewTag(this.view.getTag())
|
|
324
|
+
} else if (newState !== State.ACTIVE) {
|
|
325
|
+
this.unlockScrolls?.()
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
328
|
}
|