react-native-gesture-handler 2.20.2 → 2.21.1
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/RNGestureHandler.podspec +9 -0
- package/ReanimatedDrawerLayout/package.json +6 -0
- package/android/build.gradle +19 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +6 -2
- package/android/src/main/java/com/swmansion/gesturehandler/core/RotationGestureDetector.kt +53 -21
- package/apple/RNGestureHandlerPointerTracker.m +4 -2
- package/lib/commonjs/RNGestureHandlerModule.web.js +15 -2
- package/lib/commonjs/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/commonjs/components/Pressable/Pressable.js +2 -6
- package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
- package/lib/commonjs/components/ReanimatedDrawerLayout.js +389 -0
- package/lib/commonjs/components/ReanimatedDrawerLayout.js.map +1 -0
- package/lib/commonjs/components/ReanimatedSwipeable.js +117 -148
- package/lib/commonjs/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/commonjs/findNodeHandle.js +12 -0
- package/lib/commonjs/findNodeHandle.js.map +1 -0
- package/lib/commonjs/findNodeHandle.web.js +40 -0
- package/lib/commonjs/findNodeHandle.web.js.map +1 -0
- package/lib/commonjs/handlers/createHandler.js +4 -2
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.web.js +51 -0
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.web.js.map +1 -0
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js +3 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js +5 -3
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js +4 -2
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/GestureHandler.js +4 -0
- package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/PanGestureHandler.js +59 -0
- package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/web/interfaces.js +10 -1
- package/lib/commonjs/web/interfaces.js.map +1 -1
- package/lib/commonjs/web/tools/EventManager.js +6 -0
- package/lib/commonjs/web/tools/EventManager.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +1 -3
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js +5 -2
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/commonjs/web/tools/KeyboardEventManager.js +2 -2
- package/lib/commonjs/web/tools/KeyboardEventManager.js.map +1 -1
- package/lib/commonjs/web/tools/PointerTracker.js +6 -30
- package/lib/commonjs/web/tools/PointerTracker.js.map +1 -1
- package/lib/commonjs/web/tools/WheelEventManager.js +74 -0
- package/lib/commonjs/web/tools/WheelEventManager.js.map +1 -0
- package/lib/commonjs/web/utils.js +16 -0
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/module/RNGestureHandlerModule.web.js +16 -3
- package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/module/components/Pressable/Pressable.js +2 -6
- package/lib/module/components/Pressable/Pressable.js.map +1 -1
- package/lib/module/components/ReanimatedDrawerLayout.js +365 -0
- package/lib/module/components/ReanimatedDrawerLayout.js.map +1 -0
- package/lib/module/components/ReanimatedSwipeable.js +119 -145
- package/lib/module/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/module/findNodeHandle.js +3 -0
- package/lib/module/findNodeHandle.js.map +1 -0
- package/lib/module/findNodeHandle.web.js +32 -0
- package/lib/module/findNodeHandle.web.js.map +1 -0
- package/lib/module/handlers/createHandler.js +2 -1
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/Wrap.web.js +34 -0
- package/lib/module/handlers/gestures/GestureDetector/Wrap.web.js.map +1 -0
- package/lib/module/handlers/gestures/GestureDetector/index.js +2 -1
- package/lib/module/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -2
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/module/web/handlers/GestureHandler.js +4 -0
- package/lib/module/web/handlers/GestureHandler.js.map +1 -1
- package/lib/module/web/handlers/PanGestureHandler.js +58 -0
- package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/web/interfaces.js +8 -0
- package/lib/module/web/interfaces.js.map +1 -1
- package/lib/module/web/tools/EventManager.js +6 -0
- package/lib/module/web/tools/EventManager.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerOrchestrator.js +1 -3
- package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerWebDelegate.js +3 -1
- package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/module/web/tools/KeyboardEventManager.js +2 -2
- package/lib/module/web/tools/KeyboardEventManager.js.map +1 -1
- package/lib/module/web/tools/PointerTracker.js +6 -30
- package/lib/module/web/tools/PointerTracker.js.map +1 -1
- package/lib/module/web/tools/WheelEventManager.js +60 -0
- package/lib/module/web/tools/WheelEventManager.js.map +1 -0
- package/lib/module/web/utils.js +15 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/components/ReanimatedDrawerLayout.d.ts +162 -0
- package/lib/typescript/components/ReanimatedSwipeable.d.ts +22 -16
- package/lib/typescript/findNodeHandle.d.ts +2 -0
- package/lib/typescript/findNodeHandle.web.d.ts +2 -0
- package/lib/typescript/handlers/gestures/GestureDetector/Wrap.web.d.ts +7 -0
- package/lib/typescript/web/handlers/GestureHandler.d.ts +2 -1
- package/lib/typescript/web/handlers/PanGestureHandler.d.ts +5 -0
- package/lib/typescript/web/interfaces.d.ts +16 -0
- package/lib/typescript/web/tools/EventManager.d.ts +2 -0
- package/lib/typescript/web/tools/PointerTracker.d.ts +2 -8
- package/lib/typescript/web/tools/WheelEventManager.d.ts +11 -0
- package/lib/typescript/web/utils.d.ts +2 -1
- package/package.json +3 -2
- package/src/RNGestureHandlerModule.web.ts +23 -4
- package/src/components/Pressable/Pressable.tsx +2 -6
- package/src/components/ReanimatedDrawerLayout.tsx +741 -0
- package/src/components/ReanimatedSwipeable.tsx +361 -305
- package/src/findNodeHandle.ts +3 -0
- package/src/findNodeHandle.web.ts +35 -0
- package/src/handlers/createHandler.tsx +2 -1
- package/src/handlers/gestures/GestureDetector/Wrap.web.tsx +44 -0
- package/src/handlers/gestures/GestureDetector/index.tsx +2 -1
- package/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +1 -1
- package/src/handlers/gestures/GestureDetector/useViewRefHandler.ts +1 -1
- package/src/web/handlers/GestureHandler.ts +5 -1
- package/src/web/handlers/PanGestureHandler.ts +69 -1
- package/src/web/interfaces.ts +17 -0
- package/src/web/tools/EventManager.ts +4 -0
- package/src/web/tools/GestureHandlerOrchestrator.ts +1 -7
- package/src/web/tools/GestureHandlerWebDelegate.ts +3 -1
- package/src/web/tools/KeyboardEventManager.ts +2 -2
- package/src/web/tools/PointerTracker.ts +6 -28
- package/src/web/tools/WheelEventManager.ts +48 -0
- package/src/web/utils.ts +47 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { GestureHandlerRef, SVGRef } from './web/interfaces';
|
|
2
|
+
import { isRNSVGElement } from './web/utils';
|
|
3
|
+
|
|
4
|
+
export default function findNodeHandle(
|
|
5
|
+
viewRef: GestureHandlerRef | SVGRef | HTMLElement | SVGElement
|
|
6
|
+
): HTMLElement | SVGElement | number {
|
|
7
|
+
// Old API assumes that child handler is HTMLElement.
|
|
8
|
+
// However, if we nest handlers, we will get ref to another handler.
|
|
9
|
+
// In that case, we want to recursively call findNodeHandle with new handler viewTag (which can also be ref to another handler).
|
|
10
|
+
if ((viewRef as GestureHandlerRef)?.viewTag !== undefined) {
|
|
11
|
+
return findNodeHandle((viewRef as GestureHandlerRef).viewTag);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (viewRef instanceof Element) {
|
|
15
|
+
if (viewRef.style.display === 'contents') {
|
|
16
|
+
return findNodeHandle(viewRef.firstChild as HTMLElement);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return viewRef;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (isRNSVGElement(viewRef)) {
|
|
23
|
+
return (viewRef as SVGRef).elementRef.current;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// In new API, we receive ref object which `current` field points to wrapper `div` with `display: contents;`.
|
|
27
|
+
// We want to return the first descendant (in DFS order) that doesn't have this property.
|
|
28
|
+
let element = (viewRef as GestureHandlerRef)?.current;
|
|
29
|
+
|
|
30
|
+
while (element && element.style.display === 'contents') {
|
|
31
|
+
element = element.firstChild as HTMLElement;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return element;
|
|
35
|
+
}
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
GestureEvent,
|
|
17
17
|
HandlerStateChangeEvent,
|
|
18
18
|
} from './gestureHandlerCommon';
|
|
19
|
-
import { filterConfig,
|
|
19
|
+
import { filterConfig, scheduleFlushOperations } from './utils';
|
|
20
|
+
import findNodeHandle from '../findNodeHandle';
|
|
20
21
|
import { ValueOf } from '../typeUtils';
|
|
21
22
|
import { deepEqual, isFabric, isJestEnv, tagMessage } from '../utils';
|
|
22
23
|
import { ActionType } from '../ActionType';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import type { LegacyRef, PropsWithChildren } from 'react';
|
|
3
|
+
import { tagMessage } from '../../../utils';
|
|
4
|
+
|
|
5
|
+
export const Wrap = forwardRef<HTMLDivElement, PropsWithChildren<{}>>(
|
|
6
|
+
({ children }, ref) => {
|
|
7
|
+
try {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
const child: any = React.Children.only(children);
|
|
10
|
+
|
|
11
|
+
const isRNSVGNode =
|
|
12
|
+
Object.getPrototypeOf(child?.type)?.name === 'WebShape';
|
|
13
|
+
|
|
14
|
+
if (isRNSVGNode) {
|
|
15
|
+
const clone = React.cloneElement(
|
|
16
|
+
child,
|
|
17
|
+
{ ref },
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
19
|
+
child.props.children
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
return clone;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div
|
|
27
|
+
ref={ref as LegacyRef<HTMLDivElement>}
|
|
28
|
+
style={{ display: 'contents' }}>
|
|
29
|
+
{child}
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
tagMessage(
|
|
35
|
+
`GestureDetector got more than one view as a child. If you want the gesture to work on multiple views, wrap them with a common parent and attach the gesture to that view.`
|
|
36
|
+
)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// On web we never take a path with Reanimated,
|
|
43
|
+
// therefore we can simply export Wrap
|
|
44
|
+
export const AnimatedWrap = Wrap;
|
|
@@ -6,7 +6,8 @@ import React, {
|
|
|
6
6
|
useMemo,
|
|
7
7
|
useRef,
|
|
8
8
|
} from 'react';
|
|
9
|
-
import { Platform
|
|
9
|
+
import { Platform } from 'react-native';
|
|
10
|
+
import findNodeHandle from '../../../findNodeHandle';
|
|
10
11
|
import { GestureType } from '../gesture';
|
|
11
12
|
import { UserSelect, TouchAction } from '../../gestureHandlerCommon';
|
|
12
13
|
import { ComposedGesture } from '../gestureComposition';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
|
-
import { findNodeHandle } from 'react-native';
|
|
3
2
|
import { GestureType } from '../gesture';
|
|
4
3
|
import { ComposedGesture } from '../gestureComposition';
|
|
5
4
|
|
|
@@ -13,6 +12,7 @@ import { updateHandlers } from './updateHandlers';
|
|
|
13
12
|
import { needsToReattach } from './needsToReattach';
|
|
14
13
|
import { dropHandlers } from './dropHandlers';
|
|
15
14
|
import { useForceRender, validateDetectorChildren } from './utils';
|
|
15
|
+
import findNodeHandle from '../../../findNodeHandle';
|
|
16
16
|
|
|
17
17
|
// Returns a function that's responsible for updating the attached gestures
|
|
18
18
|
// If the view has changed, it will reattach the handlers to the new view
|
|
@@ -3,7 +3,7 @@ import { getShadowNodeFromRef } from '../../../getShadowNodeFromRef';
|
|
|
3
3
|
|
|
4
4
|
import { GestureDetectorState } from './types';
|
|
5
5
|
import React, { useCallback } from 'react';
|
|
6
|
-
import
|
|
6
|
+
import findNodeHandle from '../../../findNodeHandle';
|
|
7
7
|
|
|
8
8
|
declare const global: {
|
|
9
9
|
isFormsStackingContext: (node: unknown) => boolean | null; // JSI function
|
|
@@ -74,6 +74,7 @@ export default abstract class GestureHandler implements IGestureHandler {
|
|
|
74
74
|
manager.setOnPointerOutOfBounds(this.onPointerOutOfBounds.bind(this));
|
|
75
75
|
manager.setOnPointerMoveOver(this.onPointerMoveOver.bind(this));
|
|
76
76
|
manager.setOnPointerMoveOut(this.onPointerMoveOut.bind(this));
|
|
77
|
+
manager.setOnWheel(this.onWheel.bind(this));
|
|
77
78
|
|
|
78
79
|
manager.registerListeners();
|
|
79
80
|
}
|
|
@@ -338,7 +339,10 @@ export default abstract class GestureHandler implements IGestureHandler {
|
|
|
338
339
|
protected onPointerMoveOut(_event: AdaptedEvent): void {
|
|
339
340
|
// Used only by hover gesture handler atm
|
|
340
341
|
}
|
|
341
|
-
|
|
342
|
+
protected onWheel(_event: AdaptedEvent): void {
|
|
343
|
+
// Used only by pan gesture handler
|
|
344
|
+
}
|
|
345
|
+
protected tryToSendMoveEvent(out: boolean, event: AdaptedEvent): void {
|
|
342
346
|
if ((out && this.shouldCancelWhenOutside) || !this.enabled) {
|
|
343
347
|
return;
|
|
344
348
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { State } from '../../State';
|
|
2
2
|
import { DEFAULT_TOUCH_SLOP } from '../constants';
|
|
3
|
-
import { AdaptedEvent, Config, StylusData } from '../interfaces';
|
|
3
|
+
import { AdaptedEvent, Config, StylusData, WheelDevice } from '../interfaces';
|
|
4
4
|
|
|
5
5
|
import GestureHandler from './GestureHandler';
|
|
6
6
|
|
|
@@ -57,6 +57,10 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
57
57
|
private activateAfterLongPress = 0;
|
|
58
58
|
private activationTimeout = 0;
|
|
59
59
|
|
|
60
|
+
private enableTrackpadTwoFingerGesture = false;
|
|
61
|
+
private endWheelTimeout = 0;
|
|
62
|
+
private wheelDevice = WheelDevice.UNDETERMINED;
|
|
63
|
+
|
|
60
64
|
public init(ref: number, propsRef: React.RefObject<unknown>): void {
|
|
61
65
|
super.init(ref, propsRef);
|
|
62
66
|
}
|
|
@@ -161,6 +165,11 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
161
165
|
this.failOffsetYStart = Number.MIN_SAFE_INTEGER;
|
|
162
166
|
}
|
|
163
167
|
}
|
|
168
|
+
|
|
169
|
+
if (this.config.enableTrackpadTwoFingerGesture !== undefined) {
|
|
170
|
+
this.enableTrackpadTwoFingerGesture =
|
|
171
|
+
this.config.enableTrackpadTwoFingerGesture;
|
|
172
|
+
}
|
|
164
173
|
}
|
|
165
174
|
|
|
166
175
|
protected resetConfig(): void {
|
|
@@ -351,6 +360,65 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
351
360
|
}
|
|
352
361
|
}
|
|
353
362
|
|
|
363
|
+
private scheduleWheelEnd(event: AdaptedEvent) {
|
|
364
|
+
clearTimeout(this.endWheelTimeout);
|
|
365
|
+
|
|
366
|
+
this.endWheelTimeout = setTimeout(() => {
|
|
367
|
+
if (this.currentState === State.ACTIVE) {
|
|
368
|
+
this.end();
|
|
369
|
+
this.tracker.removeFromTracker(event.pointerId);
|
|
370
|
+
this.currentState = State.UNDETERMINED;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
this.wheelDevice = WheelDevice.UNDETERMINED;
|
|
374
|
+
}, 30);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
protected onWheel(event: AdaptedEvent): void {
|
|
378
|
+
if (
|
|
379
|
+
this.wheelDevice === WheelDevice.MOUSE ||
|
|
380
|
+
!this.enableTrackpadTwoFingerGesture
|
|
381
|
+
) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (this.currentState === State.UNDETERMINED) {
|
|
386
|
+
this.wheelDevice =
|
|
387
|
+
event.wheelDeltaY! % 120 !== 0
|
|
388
|
+
? WheelDevice.TOUCHPAD
|
|
389
|
+
: WheelDevice.MOUSE;
|
|
390
|
+
|
|
391
|
+
if (this.wheelDevice === WheelDevice.MOUSE) {
|
|
392
|
+
this.scheduleWheelEnd(event);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
this.tracker.addToTracker(event);
|
|
397
|
+
|
|
398
|
+
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
|
399
|
+
this.lastX = lastCoords.x;
|
|
400
|
+
this.lastY = lastCoords.y;
|
|
401
|
+
|
|
402
|
+
this.startX = this.lastX;
|
|
403
|
+
this.startY = this.lastY;
|
|
404
|
+
|
|
405
|
+
this.begin();
|
|
406
|
+
this.activate();
|
|
407
|
+
}
|
|
408
|
+
this.tracker.track(event);
|
|
409
|
+
|
|
410
|
+
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
|
411
|
+
this.lastX = lastCoords.x;
|
|
412
|
+
this.lastY = lastCoords.y;
|
|
413
|
+
|
|
414
|
+
const velocity = this.tracker.getVelocity(event.pointerId);
|
|
415
|
+
this.velocityX = velocity.x;
|
|
416
|
+
this.velocityY = velocity.y;
|
|
417
|
+
|
|
418
|
+
this.tryToSendMoveEvent(false, event);
|
|
419
|
+
this.scheduleWheelEnd(event);
|
|
420
|
+
}
|
|
421
|
+
|
|
354
422
|
private shouldActivate(): boolean {
|
|
355
423
|
const dx: number = this.getTranslationX();
|
|
356
424
|
|
package/src/web/interfaces.ts
CHANGED
|
@@ -78,6 +78,7 @@ export interface Config extends Record<string, ConfigArgs> {
|
|
|
78
78
|
shouldActivateOnStart?: boolean;
|
|
79
79
|
disallowInterruption?: boolean;
|
|
80
80
|
direction?: Directions;
|
|
81
|
+
enableTrackpadTwoFingerGesture?: boolean;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
type NativeEventArgs = number | State | boolean | undefined;
|
|
@@ -151,6 +152,7 @@ export interface AdaptedEvent {
|
|
|
151
152
|
time: number;
|
|
152
153
|
button?: MouseButton;
|
|
153
154
|
stylusData?: StylusData;
|
|
155
|
+
wheelDeltaY?: number;
|
|
154
156
|
}
|
|
155
157
|
|
|
156
158
|
export enum EventTypes {
|
|
@@ -171,3 +173,18 @@ export enum TouchEventType {
|
|
|
171
173
|
UP,
|
|
172
174
|
CANCELLED,
|
|
173
175
|
}
|
|
176
|
+
|
|
177
|
+
export enum WheelDevice {
|
|
178
|
+
UNDETERMINED,
|
|
179
|
+
MOUSE,
|
|
180
|
+
TOUCHPAD,
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export type GestureHandlerRef = {
|
|
184
|
+
viewTag: GestureHandlerRef;
|
|
185
|
+
current: HTMLElement;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export type SVGRef = {
|
|
189
|
+
elementRef: { current: SVGElement };
|
|
190
|
+
};
|
|
@@ -37,6 +37,7 @@ export default abstract class EventManager<T> {
|
|
|
37
37
|
protected onPointerOutOfBounds(_event: AdaptedEvent): void {}
|
|
38
38
|
protected onPointerMoveOver(_event: AdaptedEvent): void {}
|
|
39
39
|
protected onPointerMoveOut(_event: AdaptedEvent): void {}
|
|
40
|
+
protected onWheel(_event: AdaptedEvent): void {}
|
|
40
41
|
|
|
41
42
|
public setOnPointerDown(callback: PointerEventCallback): void {
|
|
42
43
|
this.onPointerDown = callback;
|
|
@@ -71,6 +72,9 @@ export default abstract class EventManager<T> {
|
|
|
71
72
|
public setOnPointerMoveOut(callback: PointerEventCallback): void {
|
|
72
73
|
this.onPointerMoveOut = callback;
|
|
73
74
|
}
|
|
75
|
+
public setOnWheel(callback: PointerEventCallback): void {
|
|
76
|
+
this.onWheel = callback;
|
|
77
|
+
}
|
|
74
78
|
|
|
75
79
|
protected markAsInBounds(pointerId: number): void {
|
|
76
80
|
if (this.pointersInBounds.indexOf(pointerId) >= 0) {
|
|
@@ -343,13 +343,7 @@ export default class GestureHandlerOrchestrator {
|
|
|
343
343
|
);
|
|
344
344
|
};
|
|
345
345
|
|
|
346
|
-
|
|
347
|
-
const otherPointers: number[] = otherHandler.getTrackedPointersID();
|
|
348
|
-
|
|
349
|
-
return (
|
|
350
|
-
handlerPointers.some(isPointerWithinBothBounds) ||
|
|
351
|
-
otherPointers.some(isPointerWithinBothBounds)
|
|
352
|
-
);
|
|
346
|
+
return handler.getTrackedPointersID().some(isPointerWithinBothBounds);
|
|
353
347
|
}
|
|
354
348
|
|
|
355
349
|
private isFinished(state: State): boolean {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import findNodeHandle from '../../findNodeHandle';
|
|
2
2
|
import type IGestureHandler from '../handlers/IGestureHandler';
|
|
3
3
|
import {
|
|
4
4
|
GestureHandlerDelegate,
|
|
@@ -11,6 +11,7 @@ import EventManager from './EventManager';
|
|
|
11
11
|
import { Config } from '../interfaces';
|
|
12
12
|
import { MouseButton } from '../../handlers/gestureHandlerCommon';
|
|
13
13
|
import KeyboardEventManager from './KeyboardEventManager';
|
|
14
|
+
import WheelEventManager from './WheelEventManager';
|
|
14
15
|
|
|
15
16
|
interface DefaultViewStyles {
|
|
16
17
|
userSelect: string;
|
|
@@ -58,6 +59,7 @@ export class GestureHandlerWebDelegate
|
|
|
58
59
|
|
|
59
60
|
this.eventManagers.push(new PointerEventManager(this.view));
|
|
60
61
|
this.eventManagers.push(new KeyboardEventManager(this.view));
|
|
62
|
+
this.eventManagers.push(new WheelEventManager(this.view));
|
|
61
63
|
|
|
62
64
|
this.eventManagers.forEach((manager) =>
|
|
63
65
|
this.gestureHandler.attachEventManager(manager)
|
|
@@ -57,8 +57,8 @@ export default class KeyboardEventManager extends EventManager<HTMLElement> {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
public unregisterListeners(): void {
|
|
60
|
-
this.view.
|
|
61
|
-
this.view.
|
|
60
|
+
this.view.removeEventListener('keydown', this.keyDownCallback);
|
|
61
|
+
this.view.removeEventListener('keyup', this.keyUpCallback);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
protected mapEvent(
|
|
@@ -22,8 +22,8 @@ export default class PointerTracker {
|
|
|
22
22
|
|
|
23
23
|
private lastMovedPointerId: number;
|
|
24
24
|
|
|
25
|
-
private cachedAbsoluteAverages:
|
|
26
|
-
private cachedRelativeAverages:
|
|
25
|
+
private cachedAbsoluteAverages: Point = { x: 0, y: 0 };
|
|
26
|
+
private cachedRelativeAverages: Point = { x: 0, y: 0 };
|
|
27
27
|
|
|
28
28
|
public constructor() {
|
|
29
29
|
this.lastMovedPointerId = NaN;
|
|
@@ -121,35 +121,13 @@ export default class PointerTracker {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
public getLastAbsoluteCoords(pointerId?: number) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
x: this.trackedPointers.get(pointerId)?.abosoluteCoords.x as number,
|
|
127
|
-
y: this.trackedPointers.get(pointerId)?.abosoluteCoords.y as number,
|
|
128
|
-
};
|
|
129
|
-
} else {
|
|
130
|
-
return {
|
|
131
|
-
x: this.trackedPointers.get(this.lastMovedPointerId)?.abosoluteCoords
|
|
132
|
-
.x as number,
|
|
133
|
-
y: this.trackedPointers.get(this.lastMovedPointerId)?.abosoluteCoords
|
|
134
|
-
.y as number,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
124
|
+
return this.trackedPointers.get(pointerId ?? this.lastMovedPointerId)
|
|
125
|
+
?.abosoluteCoords as Point;
|
|
137
126
|
}
|
|
138
127
|
|
|
139
128
|
public getLastRelativeCoords(pointerId?: number) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
x: this.trackedPointers.get(pointerId)?.relativeCoords.x as number,
|
|
143
|
-
y: this.trackedPointers.get(pointerId)?.relativeCoords.y as number,
|
|
144
|
-
};
|
|
145
|
-
} else {
|
|
146
|
-
return {
|
|
147
|
-
x: this.trackedPointers.get(this.lastMovedPointerId)?.relativeCoords
|
|
148
|
-
.x as number,
|
|
149
|
-
y: this.trackedPointers.get(this.lastMovedPointerId)?.relativeCoords
|
|
150
|
-
.y as number,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
129
|
+
return this.trackedPointers.get(pointerId ?? this.lastMovedPointerId)
|
|
130
|
+
?.relativeCoords as Point;
|
|
153
131
|
}
|
|
154
132
|
|
|
155
133
|
// Some handlers use these methods to send average values in native event.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import EventManager from './EventManager';
|
|
2
|
+
import { AdaptedEvent, EventTypes } from '../interfaces';
|
|
3
|
+
import { PointerType } from '../../PointerType';
|
|
4
|
+
|
|
5
|
+
export default class WheelEventManager extends EventManager<HTMLElement> {
|
|
6
|
+
private wheelDelta = { x: 0, y: 0 };
|
|
7
|
+
|
|
8
|
+
private resetDelta = (_event: PointerEvent) => {
|
|
9
|
+
this.wheelDelta = { x: 0, y: 0 };
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
private wheelCallback = (event: WheelEvent) => {
|
|
13
|
+
this.wheelDelta.x += event.deltaX;
|
|
14
|
+
this.wheelDelta.y += event.deltaY;
|
|
15
|
+
|
|
16
|
+
const adaptedEvent = this.mapEvent(event);
|
|
17
|
+
this.onWheel(adaptedEvent);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
public registerListeners(): void {
|
|
21
|
+
this.view.addEventListener('pointermove', this.resetDelta);
|
|
22
|
+
this.view.addEventListener('wheel', this.wheelCallback);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public unregisterListeners(): void {
|
|
26
|
+
this.view.removeEventListener('pointermove', this.resetDelta);
|
|
27
|
+
this.view.removeEventListener('wheel', this.wheelCallback);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected mapEvent(event: WheelEvent): AdaptedEvent {
|
|
31
|
+
return {
|
|
32
|
+
x: event.clientX + this.wheelDelta.x,
|
|
33
|
+
y: event.clientY + this.wheelDelta.y,
|
|
34
|
+
offsetX: event.offsetX - event.deltaX,
|
|
35
|
+
offsetY: event.offsetY - event.deltaY,
|
|
36
|
+
pointerId: -1,
|
|
37
|
+
eventType: EventTypes.MOVE,
|
|
38
|
+
pointerType: PointerType.OTHER,
|
|
39
|
+
time: event.timeStamp,
|
|
40
|
+
// @ts-ignore It does exist, but it's deprecated
|
|
41
|
+
wheelDeltaY: event.wheelDeltaY,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public resetManager(): void {
|
|
46
|
+
super.resetManager();
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/web/utils.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { PointerType } from '../PointerType';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
GestureHandlerRef,
|
|
4
|
+
Point,
|
|
5
|
+
StylusData,
|
|
6
|
+
SVGRef,
|
|
7
|
+
} from './interfaces';
|
|
3
8
|
|
|
4
9
|
export function isPointerInBounds(view: HTMLElement, { x, y }: Point): boolean {
|
|
5
10
|
const rect: DOMRect = view.getBoundingClientRect();
|
|
@@ -227,3 +232,44 @@ function spherical2tilt(altitudeAngle: number, azimuthAngle: number) {
|
|
|
227
232
|
|
|
228
233
|
return { tiltX, tiltY };
|
|
229
234
|
}
|
|
235
|
+
|
|
236
|
+
const RNSVGElements = [
|
|
237
|
+
'Circle',
|
|
238
|
+
'ClipPath',
|
|
239
|
+
'Ellipse',
|
|
240
|
+
'ForeignObject',
|
|
241
|
+
'G',
|
|
242
|
+
'Image',
|
|
243
|
+
'Line',
|
|
244
|
+
'Marker',
|
|
245
|
+
'Mask',
|
|
246
|
+
'Path',
|
|
247
|
+
'Pattern',
|
|
248
|
+
'Polygon',
|
|
249
|
+
'Polyline',
|
|
250
|
+
'Rect',
|
|
251
|
+
'Svg',
|
|
252
|
+
'Symbol',
|
|
253
|
+
'TSpan',
|
|
254
|
+
'Text',
|
|
255
|
+
'TextPath',
|
|
256
|
+
'Use',
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
// This function helps us determine whether given node is SVGElement or not. In our implementation of
|
|
260
|
+
// findNodeHandle, we can encounter such element in 2 forms - SVG tag or ref to SVG Element. Since Gesture Handler
|
|
261
|
+
// does not depend on SVG, we use our simplified SVGRef type that has `elementRef` field. This is something that is present
|
|
262
|
+
// in actual SVG ref object.
|
|
263
|
+
//
|
|
264
|
+
// In order to make sure that node passed into this function is in fact SVG element, first we check if its constructor name
|
|
265
|
+
// corresponds to one of the possible SVG elements. Then we also check if `elementRef` field exists.
|
|
266
|
+
// By doing both steps we decrease probability of detecting situations where, for example, user makes custom `Circle` and
|
|
267
|
+
// we treat it as SVG.
|
|
268
|
+
export function isRNSVGElement(viewRef: SVGRef | GestureHandlerRef) {
|
|
269
|
+
const componentClassName = Object.getPrototypeOf(viewRef).constructor.name;
|
|
270
|
+
|
|
271
|
+
return (
|
|
272
|
+
RNSVGElements.indexOf(componentClassName) >= 0 &&
|
|
273
|
+
Object.hasOwn(viewRef, 'elementRef')
|
|
274
|
+
);
|
|
275
|
+
}
|