@react-native-oh-tpl/react-native-gesture-handler 2.12.9 → 2.14.1-2.14.9
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/DrawerLayout/index.ts +2 -0
- package/Swipeable/index.ts +2 -0
- package/harmony/gesture_handler/BuildProfile.ets +15 -3
- package/harmony/gesture_handler/hvigorfile.ts +1 -1
- package/harmony/gesture_handler/index.ets +2 -2
- package/harmony/gesture_handler/oh-package-lock.json5 +4 -3
- package/harmony/gesture_handler/oh-package.json5 +4 -4
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +63 -17
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +3 -3
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +2 -2
- package/harmony/gesture_handler/src/main/cpp/{RNGestureHandlerButtonComponentInstance.h → componentInstances/RNGestureHandlerButtonComponentInstance.h} +2 -2
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +234 -0
- package/harmony/gesture_handler/src/main/ets/{GestureHandler.ts → core/GestureHandler.ts} +46 -25
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerOrchestrator.ts → core/GestureHandlerOrchestrator.ts} +122 -67
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerRegistry.ts → core/GestureHandlerRegistry.ts} +7 -0
- package/harmony/gesture_handler/src/main/ets/{Event.ts → core/IncomingEvent.ts} +30 -20
- package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
- package/harmony/gesture_handler/src/main/ets/{OutgoingEvent.ts → core/OutgoingEvent.ts} +1 -1
- package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/{PointerTracker.ts → core/PointerTracker.ts} +4 -4
- package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
- package/harmony/gesture_handler/src/main/ets/{VelocityTracker.ts → core/VelocityTracker.ts} +13 -5
- package/harmony/gesture_handler/src/main/ets/core/View.ts +19 -0
- package/harmony/gesture_handler/src/main/ets/core/index.ts +13 -0
- package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
- package/harmony/gesture_handler/src/main/ets/{NativeViewGestureHandler.ts → gesture-handlers/NativeViewGestureHandler.ts} +10 -12
- package/harmony/gesture_handler/src/main/ets/{PanGestureHandler.ts → gesture-handlers/PanGestureHandler.ts} +27 -13
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
- package/harmony/gesture_handler/src/main/ets/{TapGestureHandler.ts → gesture-handlers/TapGestureHandler.ts} +11 -11
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
- package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +8 -9
- package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerButton.ts → components/RNGestureHandlerButton.ts} +35 -36
- package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerRootView.ts → components/RNGestureHandlerRootView.ts} +23 -23
- package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
- package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -3
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerPackage.ts → rnoh/GestureHandlerPackage.ts} +4 -4
- package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +104 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerButton.ets → rnoh/RNGestureHandlerButton.ets} +3 -3
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerModule.ts → rnoh/RNGestureHandlerModule.ts} +74 -27
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerRootView.ets → rnoh/RNGestureHandlerRootView.ets} +3 -3
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +119 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +95 -0
- package/harmony/gesture_handler/src/main/module.json5 +8 -6
- package/harmony/gesture_handler/ts.ts +2 -2
- package/harmony/gesture_handler.har +0 -0
- package/lib/commonjs/index.js +98 -138
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +9 -142
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +35 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +13 -10
- package/src/index.ts +136 -136
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +0 -72
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +0 -78
- package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +0 -53
- package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ts +0 -203
- package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +0 -45
- package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +0 -109
- package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +0 -48
- package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerArkTS.ts +0 -60
- package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +0 -87
- package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +0 -23
- package/harmony/gesture_handler/src/main/ets/Vector2D.ts +0 -36
- package/harmony/gesture_handler/src/main/ets/View.ts +0 -71
- package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +0 -43
- package/harmony/gesture_handler/src/main/ets/pages/Index.ets +0 -17
- package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +0 -41
- /package/harmony/gesture_handler/src/main/ets/{CircularBuffer.ts → core/CircularBuffer.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{LeastSquareSolver.ts → core/LeastSquareSolver.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{RNGHError.ts → core/RNGHError.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{State.ts → core/State.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{types.ts → rnoh/types.ts} +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { GestureHandler, Handler, GestureConfig as Config, GHTag } from "./GestureHandler"
|
|
2
|
+
import { RNGHLogger } from "./RNGHLogger"
|
|
3
|
+
|
|
4
|
+
export class InteractionManager {
|
|
5
|
+
private readonly waitForRelations: Map<GHTag, Set<GHTag>> = new Map()
|
|
6
|
+
private readonly simultaneousRelations: Map<GHTag, GHTag[]> = new Map()
|
|
7
|
+
private readonly blocksHandlersRelations: Map<GHTag, GHTag[]> = new Map();
|
|
8
|
+
|
|
9
|
+
private logger: RNGHLogger
|
|
10
|
+
|
|
11
|
+
constructor(logger: RNGHLogger) {
|
|
12
|
+
this.logger = logger.cloneWithPrefix("InteractionManager")
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public configureInteractions(handler: GestureHandler, config: Config) {
|
|
16
|
+
this.dropRelationsForHandlerWithTag(handler.getTag());
|
|
17
|
+
|
|
18
|
+
if (config.waitFor) {
|
|
19
|
+
const waitFor = new Set<GHTag>();
|
|
20
|
+
config.waitFor.forEach((otherHandler: Handler): void => {
|
|
21
|
+
// New API reference
|
|
22
|
+
if (typeof otherHandler === 'number') {
|
|
23
|
+
waitFor.add(otherHandler);
|
|
24
|
+
} else {
|
|
25
|
+
// Old API reference
|
|
26
|
+
waitFor.add(otherHandler.handlerTag);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
this.waitForRelations.set(handler.getTag(), waitFor);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (config.simultaneousHandlers) {
|
|
34
|
+
const simultaneousHandlers: number[] = [];
|
|
35
|
+
config.simultaneousHandlers.forEach((otherHandler: Handler): void => {
|
|
36
|
+
if (typeof otherHandler === 'number') {
|
|
37
|
+
simultaneousHandlers.push(otherHandler);
|
|
38
|
+
} else {
|
|
39
|
+
simultaneousHandlers.push(otherHandler.handlerTag);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
this.simultaneousRelations.set(handler.getTag(), simultaneousHandlers);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (config.blocksHandlers) {
|
|
47
|
+
const blocksHandlers: number[] = [];
|
|
48
|
+
config.blocksHandlers.forEach((otherHandler: Handler): void => {
|
|
49
|
+
if (typeof otherHandler === 'number') {
|
|
50
|
+
blocksHandlers.push(otherHandler);
|
|
51
|
+
} else {
|
|
52
|
+
blocksHandlers.push(otherHandler.handlerTag);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
this.blocksHandlersRelations.set(handler.getTag(), blocksHandlers);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public shouldWaitForHandlerFailure(
|
|
60
|
+
handler: GestureHandler,
|
|
61
|
+
otherHandler: GestureHandler
|
|
62
|
+
): boolean {
|
|
63
|
+
const logger = this.logger.cloneWithPrefix(`shouldWaitForHandlerFailure(${handler.getTag()}, ${otherHandler.getTag()})`)
|
|
64
|
+
const waitFor = this.waitForRelations.get(
|
|
65
|
+
handler.getTag()
|
|
66
|
+
);
|
|
67
|
+
logger.debug({waitFor: Array.from(waitFor ?? [])})
|
|
68
|
+
if (!waitFor) {
|
|
69
|
+
logger.debug("false")
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let shouldWait = false;
|
|
74
|
+
waitFor.forEach((tag: number): void => {
|
|
75
|
+
if (tag === otherHandler.getTag()) {
|
|
76
|
+
shouldWait = true;
|
|
77
|
+
return; //Returns from callback
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
logger.debug(shouldWait)
|
|
81
|
+
return shouldWait;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public shouldRecognizeSimultaneously(
|
|
85
|
+
handler: GestureHandler,
|
|
86
|
+
otherHandler: GestureHandler
|
|
87
|
+
): boolean {
|
|
88
|
+
const logger = this.logger.cloneWithPrefix(`shouldRecognizeSimultaneously(${handler.getTag()}, ${otherHandler.getTag()})`)
|
|
89
|
+
const simultaneousHandlers: number[] | undefined =
|
|
90
|
+
this.simultaneousRelations.get(handler.getTag());
|
|
91
|
+
if (!simultaneousHandlers) {
|
|
92
|
+
logger.debug(`false - Handler ${handler.getTag()} doesn't have simultaneousRelations specified`)
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
let shouldRecognizeSimultaneously = false;
|
|
96
|
+
simultaneousHandlers.forEach((tag: number): void => {
|
|
97
|
+
if (tag === otherHandler.getTag()) {
|
|
98
|
+
shouldRecognizeSimultaneously = true;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
logger.debug(`${shouldRecognizeSimultaneously} ${JSON.stringify({ simultaneousHandlers })}`)
|
|
103
|
+
return shouldRecognizeSimultaneously;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public shouldRequireHandlerToWaitForFailure(
|
|
107
|
+
handler: GestureHandler,
|
|
108
|
+
otherHandler: GestureHandler
|
|
109
|
+
): boolean {
|
|
110
|
+
const waitFor: number[] | undefined = this.blocksHandlersRelations.get(
|
|
111
|
+
handler.getTag()
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
waitFor?.find((tag: number) => {
|
|
116
|
+
return tag === otherHandler.getTag();
|
|
117
|
+
}) !== undefined
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public shouldHandlerBeCancelledBy(
|
|
122
|
+
handler: GestureHandler,
|
|
123
|
+
otherHandler: GestureHandler
|
|
124
|
+
): boolean {
|
|
125
|
+
const logger = this.logger.cloneWithPrefix(`shouldHandlerBeCancelledBy(handler=${handler.getTag()}, otherHandler=${otherHandler.getTag()})`)
|
|
126
|
+
// We check constructor name instead of using `instanceof` in order do avoid circular dependencies
|
|
127
|
+
// const isNativeHandler =
|
|
128
|
+
// otherHandler.constructor.name === 'NativeViewGestureHandler';
|
|
129
|
+
// const isActive = otherHandler.getState() === State.ACTIVE;
|
|
130
|
+
// const isButton = otherHandler.isButton?.() === true;
|
|
131
|
+
// return isNativeHandler && isActive && !isButton;
|
|
132
|
+
return false
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public dropRelationsForHandlerWithTag(handlerTag: number): void {
|
|
136
|
+
this.waitForRelations.delete(handlerTag);
|
|
137
|
+
this.simultaneousRelations.delete(handlerTag);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public reset() {
|
|
141
|
+
this.waitForRelations.clear();
|
|
142
|
+
this.simultaneousRelations.clear();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GestureStateChangeEvent,
|
|
3
|
+
GestureUpdateEvent,
|
|
4
|
+
GestureTouchEvent,
|
|
5
|
+
} from './OutgoingEvent';
|
|
6
|
+
|
|
7
|
+
export interface OutgoingEventDispatcher {
|
|
8
|
+
onGestureHandlerStateChange(event: GestureStateChangeEvent): void;
|
|
9
|
+
onGestureHandlerEvent(
|
|
10
|
+
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
|
11
|
+
): void;
|
|
12
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import VelocityTracker from './VelocityTracker';
|
|
2
|
-
import {
|
|
1
|
+
import { VelocityTracker, TrackerElement } from './VelocityTracker';
|
|
2
|
+
import { IncomingEvent } from "./IncomingEvent"
|
|
3
3
|
import { Vector2D } from './Vector2D';
|
|
4
4
|
|
|
5
5
|
const MAX_POINTERS = 20;
|
|
@@ -25,7 +25,7 @@ export class PointerTracker {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
public addToTracker(event:
|
|
28
|
+
public addToTracker(event: IncomingEvent): void {
|
|
29
29
|
if (this.trackedPointers.has(event.pointerId)) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
@@ -54,7 +54,7 @@ export class PointerTracker {
|
|
|
54
54
|
this.removeMappedTouchId(pointerId);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
public track(event:
|
|
57
|
+
public track(event: IncomingEvent): void {
|
|
58
58
|
const element: TrackerElement = this.trackedPointers.get(
|
|
59
59
|
event.pointerId
|
|
60
60
|
) as TrackerElement;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Directions, DiagonalDirections } from "./IncomingEvent"
|
|
2
|
+
|
|
3
|
+
type Cosine = number
|
|
4
|
+
|
|
5
|
+
export class Vector2D {
|
|
6
|
+
private static VECTOR_BY_DIRECTION = new Map<
|
|
7
|
+
Directions | DiagonalDirections,
|
|
8
|
+
Vector2D
|
|
9
|
+
>([
|
|
10
|
+
[Directions.LEFT, new Vector2D({ x: -1, y: 0 })],
|
|
11
|
+
[Directions.RIGHT, new Vector2D({ x: 1, y: 0 })],
|
|
12
|
+
[Directions.UP, new Vector2D({ x: 0, y: -1 })],
|
|
13
|
+
[Directions.DOWN, new Vector2D({ x: 0, y: 1 })],
|
|
14
|
+
[DiagonalDirections.UP_RIGHT, new Vector2D({ x: 1, y: -1 })],
|
|
15
|
+
[DiagonalDirections.DOWN_RIGHT, new Vector2D({ x: 1, y: 1 })],
|
|
16
|
+
[DiagonalDirections.UP_LEFT, new Vector2D({ x: -1, y: -1 })],
|
|
17
|
+
[DiagonalDirections.DOWN_LEFT, new Vector2D({ x: -1, y: 1 })],
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
static fromDirection(direction: Directions | DiagonalDirections): Vector2D {
|
|
21
|
+
return Vector2D.VECTOR_BY_DIRECTION.get(direction)!;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
private val: {
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
} = {x: 0, y: 0},
|
|
30
|
+
) {}
|
|
31
|
+
|
|
32
|
+
get x() {
|
|
33
|
+
return this.val.x;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get y() {
|
|
37
|
+
return this.val.y;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get value() {
|
|
41
|
+
return {...this.val};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public clone() {
|
|
45
|
+
return new Vector2D({...this.val});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public subtract(vec: Vector2D) {
|
|
49
|
+
this.val.x -= vec.x;
|
|
50
|
+
this.val.y -= vec.y;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public add(vec: Vector2D) {
|
|
55
|
+
this.val.x += vec.x;
|
|
56
|
+
this.val.y += vec.y;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public createUnitVector(): Vector2D {
|
|
61
|
+
const magnitude = this.magnitude
|
|
62
|
+
if (magnitude === 0) {
|
|
63
|
+
return new Vector2D({ x: 0, y: 0 });
|
|
64
|
+
}
|
|
65
|
+
return new Vector2D({
|
|
66
|
+
x: this.val.x / magnitude,
|
|
67
|
+
y: this.val.y / magnitude
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public computeCosine(other: Vector2D): Cosine {
|
|
72
|
+
const thisUnit = this.createUnitVector();
|
|
73
|
+
const otherUnit = other.createUnitVector();
|
|
74
|
+
return thisUnit.val.x * otherUnit.val.x + thisUnit.val.y * otherUnit.val.y;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public get magnitude() {
|
|
78
|
+
return Math.hypot(this.x, this.y);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IncomingEvent } from './IncomingEvent';
|
|
2
2
|
import { CircularBuffer } from './CircularBuffer';
|
|
3
3
|
import { LeastSquareSolver } from './LeastSquareSolver';
|
|
4
4
|
|
|
5
|
-
export
|
|
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 {
|
|
6
14
|
private assumePointerMoveStoppedMilliseconds = 40;
|
|
7
15
|
private historySize = 20;
|
|
8
16
|
private horizonMilliseconds = 300;
|
|
9
17
|
private minSampleSize = 3;
|
|
10
18
|
|
|
11
|
-
private samples: CircularBuffer<
|
|
19
|
+
private samples: CircularBuffer<IncomingEvent>;
|
|
12
20
|
|
|
13
21
|
constructor() {
|
|
14
|
-
this.samples = new CircularBuffer<
|
|
22
|
+
this.samples = new CircularBuffer<IncomingEvent>(this.historySize);
|
|
15
23
|
}
|
|
16
24
|
|
|
17
|
-
public add(event:
|
|
25
|
+
public add(event: IncomingEvent): void {
|
|
18
26
|
this.samples.push(event);
|
|
19
27
|
}
|
|
20
28
|
|
|
@@ -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
|
+
}
|