@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.
Files changed (86) hide show
  1. package/DrawerLayout/index.ts +2 -0
  2. package/Swipeable/index.ts +2 -0
  3. package/harmony/gesture_handler/BuildProfile.ets +15 -3
  4. package/harmony/gesture_handler/hvigorfile.ts +1 -1
  5. package/harmony/gesture_handler/index.ets +2 -2
  6. package/harmony/gesture_handler/oh-package-lock.json5 +4 -3
  7. package/harmony/gesture_handler/oh-package.json5 +4 -4
  8. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +63 -17
  9. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +3 -3
  10. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +2 -2
  11. package/harmony/gesture_handler/src/main/cpp/{RNGestureHandlerButtonComponentInstance.h → componentInstances/RNGestureHandlerButtonComponentInstance.h} +2 -2
  12. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +234 -0
  13. package/harmony/gesture_handler/src/main/ets/{GestureHandler.ts → core/GestureHandler.ts} +46 -25
  14. package/harmony/gesture_handler/src/main/ets/{GestureHandlerOrchestrator.ts → core/GestureHandlerOrchestrator.ts} +122 -67
  15. package/harmony/gesture_handler/src/main/ets/{GestureHandlerRegistry.ts → core/GestureHandlerRegistry.ts} +7 -0
  16. package/harmony/gesture_handler/src/main/ets/{Event.ts → core/IncomingEvent.ts} +30 -20
  17. package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
  18. package/harmony/gesture_handler/src/main/ets/{OutgoingEvent.ts → core/OutgoingEvent.ts} +1 -1
  19. package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
  20. package/harmony/gesture_handler/src/main/ets/{PointerTracker.ts → core/PointerTracker.ts} +4 -4
  21. package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
  22. package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
  23. package/harmony/gesture_handler/src/main/ets/{VelocityTracker.ts → core/VelocityTracker.ts} +13 -5
  24. package/harmony/gesture_handler/src/main/ets/core/View.ts +19 -0
  25. package/harmony/gesture_handler/src/main/ets/core/index.ts +13 -0
  26. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  27. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
  28. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
  29. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
  30. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
  31. package/harmony/gesture_handler/src/main/ets/{NativeViewGestureHandler.ts → gesture-handlers/NativeViewGestureHandler.ts} +10 -12
  32. package/harmony/gesture_handler/src/main/ets/{PanGestureHandler.ts → gesture-handlers/PanGestureHandler.ts} +27 -13
  33. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
  34. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
  35. package/harmony/gesture_handler/src/main/ets/{TapGestureHandler.ts → gesture-handlers/TapGestureHandler.ts} +11 -11
  36. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  37. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  38. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +8 -9
  39. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerButton.ts → components/RNGestureHandlerButton.ts} +35 -36
  40. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerRootView.ts → components/RNGestureHandlerRootView.ts} +23 -23
  41. package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
  42. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -3
  43. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
  44. package/harmony/gesture_handler/src/main/ets/{GestureHandlerPackage.ts → rnoh/GestureHandlerPackage.ts} +4 -4
  45. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
  46. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
  47. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +104 -0
  48. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
  49. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerButton.ets → rnoh/RNGestureHandlerButton.ets} +3 -3
  50. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerModule.ts → rnoh/RNGestureHandlerModule.ts} +74 -27
  51. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerRootView.ets → rnoh/RNGestureHandlerRootView.ets} +3 -3
  52. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
  53. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
  54. package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +119 -0
  55. package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +95 -0
  56. package/harmony/gesture_handler/src/main/module.json5 +8 -6
  57. package/harmony/gesture_handler/ts.ts +2 -2
  58. package/harmony/gesture_handler.har +0 -0
  59. package/lib/commonjs/index.js +98 -138
  60. package/lib/commonjs/index.js.map +1 -1
  61. package/lib/module/index.js +9 -142
  62. package/lib/module/index.js.map +1 -1
  63. package/lib/typescript/index.d.ts +35 -1
  64. package/lib/typescript/index.d.ts.map +1 -1
  65. package/package.json +13 -10
  66. package/src/index.ts +136 -136
  67. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +0 -72
  68. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +0 -78
  69. package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +0 -53
  70. package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ts +0 -203
  71. package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +0 -45
  72. package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +0 -109
  73. package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +0 -48
  74. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerArkTS.ts +0 -60
  75. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +0 -87
  76. package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +0 -23
  77. package/harmony/gesture_handler/src/main/ets/Vector2D.ts +0 -36
  78. package/harmony/gesture_handler/src/main/ets/View.ts +0 -71
  79. package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +0 -43
  80. package/harmony/gesture_handler/src/main/ets/pages/Index.ets +0 -17
  81. package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +0 -41
  82. /package/harmony/gesture_handler/src/main/ets/{CircularBuffer.ts → core/CircularBuffer.ts} +0 -0
  83. /package/harmony/gesture_handler/src/main/ets/{LeastSquareSolver.ts → core/LeastSquareSolver.ts} +0 -0
  84. /package/harmony/gesture_handler/src/main/ets/{RNGHError.ts → core/RNGHError.ts} +0 -0
  85. /package/harmony/gesture_handler/src/main/ets/{State.ts → core/State.ts} +0 -0
  86. /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
+ }
@@ -1,5 +1,5 @@
1
1
  import { State } from "./State"
2
- import { TouchEventType } from "./Event"
2
+ import { TouchEventType } from "./IncomingEvent"
3
3
 
4
4
  export interface GestureEventPayload {
5
5
  handlerTag: number;
@@ -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 { TrackerElement, AdaptedEvent } from "./Event"
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: AdaptedEvent): void {
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: AdaptedEvent): void {
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,12 @@
1
+ export type RNGHLoggerMessage = string | Object
2
+
3
+ export interface RNGHLogger {
4
+ info(msg: string): void;
5
+
6
+ cloneWithPrefix(prefix: string): RNGHLogger;
7
+
8
+ debug(msg: RNGHLoggerMessage);
9
+
10
+ error(msg: string);
11
+ }
12
+
@@ -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 { AdaptedEvent } from './Event';
1
+ import { IncomingEvent } from './IncomingEvent';
2
2
  import { CircularBuffer } from './CircularBuffer';
3
3
  import { LeastSquareSolver } from './LeastSquareSolver';
4
4
 
5
- export default class VelocityTracker {
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<AdaptedEvent>;
19
+ private samples: CircularBuffer<IncomingEvent>;
12
20
 
13
21
  constructor() {
14
- this.samples = new CircularBuffer<AdaptedEvent>(this.historySize);
22
+ this.samples = new CircularBuffer<IncomingEvent>(this.historySize);
15
23
  }
16
24
 
17
- public add(event: AdaptedEvent): void {
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
+ }