react-native-gesture-handler 2.18.1 → 2.20.0
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/README.md +1 -0
- package/android/build.gradle +11 -29
- package/android/fabric/src/main/java/com/swmansion/gesturehandler/ReactContextExtensions.kt +1 -1
- package/android/paper/src/main/java/com/swmansion/gesturehandler/ReactContextExtensions.kt +1 -1
- package/android/src/main/AndroidManifest.xml +1 -3
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +21 -21
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +2 -2
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureUtils.kt +1 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/HoverGestureHandler.kt +16 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +80 -4
- package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +8 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt +2 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/ScaleGestureDetector.java +10 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/StylusData.kt +103 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/Vector.kt +2 -2
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +24 -15
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +3 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/eventbuilders/HoverGestureHandlerEventDataBuilder.kt +7 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/eventbuilders/PanGestureHandlerEventDataBuilder.kt +7 -0
- package/android/src/main/jni/CMakeLists.txt +18 -9
- package/apple/Handlers/RNFlingHandler.h +1 -0
- package/apple/Handlers/RNFlingHandler.m +153 -19
- package/apple/Handlers/RNHoverHandler.m +44 -2
- package/apple/Handlers/RNLongPressHandler.m +111 -20
- package/apple/Handlers/RNManualHandler.m +53 -29
- package/apple/Handlers/RNNativeViewHandler.mm +22 -15
- package/apple/Handlers/RNPanHandler.m +57 -7
- package/apple/Handlers/RNRotationHandler.m +1 -1
- package/apple/RNGHStylusData.h +77 -0
- package/apple/RNGHStylusData.m +37 -0
- package/apple/RNGHUIKit.h +2 -0
- package/apple/RNGHVector.h +31 -0
- package/apple/RNGHVector.m +67 -0
- package/apple/RNGestureHandler.h +7 -0
- package/apple/{RNGestureHandler.m → RNGestureHandler.mm} +63 -1
- package/apple/RNGestureHandlerButtonComponentView.mm +41 -0
- package/apple/RNGestureHandlerDirection.h +25 -0
- package/apple/RNGestureHandlerEvents.h +3 -1
- package/apple/RNGestureHandlerEvents.m +11 -3
- package/lib/commonjs/PointerType.js +2 -1
- package/lib/commonjs/PointerType.js.map +1 -1
- package/lib/commonjs/components/GestureButtons.js +5 -1
- package/lib/commonjs/components/GestureButtons.js.map +1 -1
- package/lib/commonjs/components/GestureComponents.js.map +1 -1
- package/lib/commonjs/components/Pressable/Pressable.js +66 -78
- package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
- package/lib/commonjs/components/Pressable/index.js +0 -8
- package/lib/commonjs/components/Pressable/index.js.map +1 -1
- package/lib/commonjs/components/Pressable/utils.js +1 -23
- package/lib/commonjs/components/Pressable/utils.js.map +1 -1
- package/lib/commonjs/components/ReanimatedSwipeable.js +60 -41
- package/lib/commonjs/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/commonjs/handlers/GestureHandlerEventPayload.js +4 -0
- package/lib/commonjs/handlers/LongPressGestureHandler.js +1 -1
- package/lib/commonjs/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/createHandler.js +2 -1
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/utils.js +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/utils.js.map +1 -1
- package/lib/commonjs/handlers/gestures/gesture.js.map +1 -1
- package/lib/commonjs/handlers/gestures/hoverGesture.js.map +1 -1
- package/lib/commonjs/handlers/gestures/longPressGesture.js +10 -0
- package/lib/commonjs/handlers/gestures/longPressGesture.js.map +1 -1
- package/lib/commonjs/jestUtils/jestUtils.js +12 -4
- package/lib/commonjs/jestUtils/jestUtils.js.map +1 -1
- package/lib/commonjs/mocks.js +16 -3
- package/lib/commonjs/mocks.js.map +1 -1
- package/lib/commonjs/utils.js +4 -0
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/commonjs/web/constants.js +3 -3
- package/lib/commonjs/web/constants.js.map +1 -1
- package/lib/commonjs/web/handlers/GestureHandler.js +2 -3
- package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/HoverGestureHandler.js +18 -1
- package/lib/commonjs/web/handlers/HoverGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js +43 -9
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +14 -3
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/PanGestureHandler.js +12 -1
- package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/web/interfaces.js.map +1 -1
- package/lib/commonjs/web/tools/EventManager.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js +55 -11
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/commonjs/web/tools/KeyboardEventManager.js +110 -0
- package/lib/commonjs/web/tools/KeyboardEventManager.js.map +1 -0
- package/lib/commonjs/web/tools/PointerEventManager.js +3 -37
- package/lib/commonjs/web/tools/PointerEventManager.js.map +1 -1
- package/lib/commonjs/web/tools/Vector.js +4 -2
- package/lib/commonjs/web/tools/Vector.js.map +1 -1
- package/lib/commonjs/web/utils.js +187 -13
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/module/PointerType.js +2 -1
- package/lib/module/PointerType.js.map +1 -1
- package/lib/module/components/GestureButtons.js +5 -1
- package/lib/module/components/GestureButtons.js.map +1 -1
- package/lib/module/components/GestureComponents.js.map +1 -1
- package/lib/module/components/Pressable/Pressable.js +67 -78
- package/lib/module/components/Pressable/Pressable.js.map +1 -1
- package/lib/module/components/Pressable/index.js +0 -1
- package/lib/module/components/Pressable/index.js.map +1 -1
- package/lib/module/components/Pressable/utils.js +1 -22
- package/lib/module/components/Pressable/utils.js.map +1 -1
- package/lib/module/components/ReanimatedSwipeable.js +58 -37
- package/lib/module/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/module/handlers/GestureHandlerEventPayload.js +1 -1
- package/lib/module/handlers/LongPressGestureHandler.js +1 -1
- package/lib/module/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/handlers/createHandler.js +2 -1
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/utils.js +2 -2
- package/lib/module/handlers/gestures/GestureDetector/utils.js.map +1 -1
- package/lib/module/handlers/gestures/gesture.js.map +1 -1
- package/lib/module/handlers/gestures/hoverGesture.js.map +1 -1
- package/lib/module/handlers/gestures/longPressGesture.js +10 -0
- package/lib/module/handlers/gestures/longPressGesture.js.map +1 -1
- package/lib/module/jestUtils/jestUtils.js +12 -4
- package/lib/module/jestUtils/jestUtils.js.map +1 -1
- package/lib/module/mocks.js +13 -3
- package/lib/module/mocks.js.map +1 -1
- package/lib/module/utils.js +1 -0
- package/lib/module/utils.js.map +1 -1
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/handlers/GestureHandler.js +2 -3
- package/lib/module/web/handlers/GestureHandler.js.map +1 -1
- package/lib/module/web/handlers/HoverGestureHandler.js +18 -1
- package/lib/module/web/handlers/HoverGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js +43 -9
- package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/NativeViewGestureHandler.js +14 -3
- package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/PanGestureHandler.js +12 -1
- package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/web/interfaces.js.map +1 -1
- package/lib/module/web/tools/EventManager.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerWebDelegate.js +54 -10
- package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/module/web/tools/KeyboardEventManager.js +96 -0
- package/lib/module/web/tools/KeyboardEventManager.js.map +1 -0
- package/lib/module/web/tools/PointerEventManager.js +4 -38
- package/lib/module/web/tools/PointerEventManager.js.map +1 -1
- package/lib/module/web/tools/Vector.js +5 -3
- package/lib/module/web/tools/Vector.js.map +1 -1
- package/lib/module/web/utils.js +184 -13
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/PointerType.d.ts +2 -1
- package/lib/typescript/components/GestureComponents.d.ts +1 -1
- package/lib/typescript/components/Pressable/index.d.ts +1 -1
- package/lib/typescript/components/Pressable/utils.d.ts +3 -5
- package/lib/typescript/handlers/GestureHandlerEventPayload.d.ts +35 -0
- package/lib/typescript/handlers/LongPressGestureHandler.d.ts +5 -1
- package/lib/typescript/handlers/gestures/gesture.d.ts +2 -2
- package/lib/typescript/handlers/gestures/hoverGesture.d.ts +1 -6
- package/lib/typescript/handlers/gestures/longPressGesture.d.ts +5 -0
- package/lib/typescript/handlers/handlersRegistry.d.ts +1 -1
- package/lib/typescript/jestUtils/jestUtils.d.ts +1 -1
- package/lib/typescript/mocks.d.ts +4 -3
- package/lib/typescript/utils.d.ts +1 -0
- package/lib/typescript/web/constants.d.ts +1 -1
- package/lib/typescript/web/handlers/GestureHandler.d.ts +1 -1
- package/lib/typescript/web/handlers/HoverGestureHandler.d.ts +2 -0
- package/lib/typescript/web/handlers/LongPressGestureHandler.d.ts +3 -0
- package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
- package/lib/typescript/web/handlers/PanGestureHandler.d.ts +3 -1
- package/lib/typescript/web/interfaces.d.ts +9 -4
- package/lib/typescript/web/tools/EventManager.d.ts +2 -2
- package/lib/typescript/web/tools/GestureHandlerDelegate.d.ts +1 -0
- package/lib/typescript/web/tools/GestureHandlerWebDelegate.d.ts +6 -0
- package/lib/typescript/web/tools/KeyboardEventManager.d.ts +13 -0
- package/lib/typescript/web/utils.d.ts +2 -1
- package/package.json +3 -3
- package/src/PointerType.ts +1 -0
- package/src/components/GestureButtons.tsx +2 -1
- package/src/components/GestureComponents.tsx +1 -1
- package/src/components/Pressable/Pressable.tsx +77 -70
- package/src/components/Pressable/index.ts +1 -1
- package/src/components/Pressable/utils.ts +5 -49
- package/src/components/ReanimatedSwipeable.tsx +70 -47
- package/src/handlers/GestureHandlerEventPayload.ts +42 -0
- package/src/handlers/LongPressGestureHandler.ts +6 -0
- package/src/handlers/createHandler.tsx +1 -0
- package/src/handlers/gestures/GestureDetector/utils.ts +2 -2
- package/src/handlers/gestures/gesture.ts +3 -1
- package/src/handlers/gestures/hoverGesture.ts +1 -7
- package/src/handlers/gestures/longPressGesture.ts +9 -0
- package/src/jestUtils/jestUtils.ts +9 -1
- package/src/{mocks.ts → mocks.tsx} +8 -3
- package/src/utils.ts +2 -0
- package/src/web/constants.ts +1 -1
- package/src/web/handlers/GestureHandler.ts +4 -2
- package/src/web/handlers/HoverGestureHandler.ts +16 -2
- package/src/web/handlers/LongPressGestureHandler.ts +49 -10
- package/src/web/handlers/NativeViewGestureHandler.ts +14 -4
- package/src/web/handlers/PanGestureHandler.ts +14 -1
- package/src/web/interfaces.ts +10 -4
- package/src/web/tools/EventManager.ts +2 -4
- package/src/web/tools/GestureHandlerDelegate.ts +1 -0
- package/src/web/tools/GestureHandlerWebDelegate.ts +67 -10
- package/src/web/tools/KeyboardEventManager.ts +91 -0
- package/src/web/tools/PointerEventManager.ts +2 -38
- package/src/web/tools/Vector.ts +4 -3
- package/src/web/utils.ts +188 -13
- package/lib/commonjs/web/tools/TouchEventManager.js +0 -164
- package/lib/commonjs/web/tools/TouchEventManager.js.map +0 -1
- package/lib/module/web/tools/TouchEventManager.js +0 -149
- package/lib/module/web/tools/TouchEventManager.js.map +0 -1
- package/lib/typescript/web/tools/TouchEventManager.d.ts +0 -11
- package/src/web/tools/TouchEventManager.ts +0 -175
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { State } from '../../State';
|
|
2
2
|
import { DEFAULT_TOUCH_SLOP } from '../constants';
|
|
3
|
-
import { AdaptedEvent, Config } from '../interfaces';
|
|
3
|
+
import { AdaptedEvent, Config, StylusData } from '../interfaces';
|
|
4
4
|
|
|
5
5
|
import GestureHandler from './GestureHandler';
|
|
6
6
|
|
|
@@ -52,6 +52,8 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
52
52
|
private lastX = 0;
|
|
53
53
|
private lastY = 0;
|
|
54
54
|
|
|
55
|
+
private stylusData: StylusData | undefined;
|
|
56
|
+
|
|
55
57
|
private activateAfterLongPress = 0;
|
|
56
58
|
private activationTimeout = 0;
|
|
57
59
|
|
|
@@ -196,6 +198,7 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
196
198
|
translationY: isNaN(translationY) ? 0 : translationY,
|
|
197
199
|
velocityX: this.velocityX,
|
|
198
200
|
velocityY: this.velocityY,
|
|
201
|
+
stylusData: this.stylusData,
|
|
199
202
|
};
|
|
200
203
|
}
|
|
201
204
|
|
|
@@ -217,6 +220,8 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
217
220
|
}
|
|
218
221
|
|
|
219
222
|
this.tracker.addToTracker(event);
|
|
223
|
+
this.stylusData = event.stylusData;
|
|
224
|
+
|
|
220
225
|
super.onPointerDown(event);
|
|
221
226
|
|
|
222
227
|
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
|
@@ -259,6 +264,8 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
259
264
|
}
|
|
260
265
|
|
|
261
266
|
protected onPointerUp(event: AdaptedEvent): void {
|
|
267
|
+
this.stylusData = event.stylusData;
|
|
268
|
+
|
|
262
269
|
super.onPointerUp(event);
|
|
263
270
|
if (this.currentState === State.ACTIVE) {
|
|
264
271
|
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
|
@@ -268,6 +275,10 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
268
275
|
|
|
269
276
|
this.tracker.removeFromTracker(event.pointerId);
|
|
270
277
|
|
|
278
|
+
if (this.tracker.getTrackedPointersCount() === 0) {
|
|
279
|
+
this.clearActivationTimeout();
|
|
280
|
+
}
|
|
281
|
+
|
|
271
282
|
if (this.currentState === State.ACTIVE) {
|
|
272
283
|
this.end();
|
|
273
284
|
} else {
|
|
@@ -302,6 +313,7 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
302
313
|
|
|
303
314
|
protected onPointerMove(event: AdaptedEvent): void {
|
|
304
315
|
this.tracker.track(event);
|
|
316
|
+
this.stylusData = event.stylusData;
|
|
305
317
|
|
|
306
318
|
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
|
307
319
|
this.lastX = lastCoords.x;
|
|
@@ -322,6 +334,7 @@ export default class PanGestureHandler extends GestureHandler {
|
|
|
322
334
|
}
|
|
323
335
|
|
|
324
336
|
this.tracker.track(event);
|
|
337
|
+
this.stylusData = event.stylusData;
|
|
325
338
|
|
|
326
339
|
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
|
327
340
|
this.lastX = lastCoords.x;
|
package/src/web/interfaces.ts
CHANGED
|
@@ -36,7 +36,7 @@ type ConfigArgs =
|
|
|
36
36
|
| undefined;
|
|
37
37
|
|
|
38
38
|
export interface Config extends Record<string, ConfigArgs> {
|
|
39
|
-
enabled
|
|
39
|
+
enabled: boolean;
|
|
40
40
|
simultaneousHandlers?: Handler[] | null;
|
|
41
41
|
waitFor?: Handler[] | null;
|
|
42
42
|
blocksHandlers?: Handler[] | null;
|
|
@@ -132,6 +132,14 @@ export interface PropsRef {
|
|
|
132
132
|
onGestureHandlerStateChange: () => void;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
export interface StylusData {
|
|
136
|
+
tiltX: number;
|
|
137
|
+
tiltY: number;
|
|
138
|
+
azimuthAngle: number;
|
|
139
|
+
altitudeAngle: number;
|
|
140
|
+
pressure: number;
|
|
141
|
+
}
|
|
142
|
+
|
|
135
143
|
export interface AdaptedEvent {
|
|
136
144
|
x: number;
|
|
137
145
|
y: number;
|
|
@@ -142,9 +150,7 @@ export interface AdaptedEvent {
|
|
|
142
150
|
pointerType: PointerType;
|
|
143
151
|
time: number;
|
|
144
152
|
button?: MouseButton;
|
|
145
|
-
|
|
146
|
-
changedTouches?: TouchList;
|
|
147
|
-
touchEventType?: TouchEventType;
|
|
153
|
+
stylusData?: StylusData;
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
export enum EventTypes {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
-
import { AdaptedEvent, EventTypes
|
|
2
|
+
import { AdaptedEvent, EventTypes } from '../interfaces';
|
|
3
3
|
|
|
4
4
|
type PointerEventCallback = (event: AdaptedEvent) => void;
|
|
5
5
|
|
|
@@ -18,9 +18,7 @@ export default abstract class EventManager<T> {
|
|
|
18
18
|
|
|
19
19
|
protected abstract mapEvent(
|
|
20
20
|
event: Event,
|
|
21
|
-
eventType: EventTypes
|
|
22
|
-
index?: number,
|
|
23
|
-
touchEventType?: TouchEventType
|
|
21
|
+
eventType: EventTypes
|
|
24
22
|
): AdaptedEvent;
|
|
25
23
|
|
|
26
24
|
protected onPointerDown(_event: AdaptedEvent): void {}
|
|
@@ -5,19 +5,29 @@ import {
|
|
|
5
5
|
MeasureResult,
|
|
6
6
|
} from './GestureHandlerDelegate';
|
|
7
7
|
import PointerEventManager from './PointerEventManager';
|
|
8
|
-
import TouchEventManager from './TouchEventManager';
|
|
9
8
|
import { State } from '../../State';
|
|
10
9
|
import { isPointerInBounds } from '../utils';
|
|
11
10
|
import EventManager from './EventManager';
|
|
12
11
|
import { Config } from '../interfaces';
|
|
13
12
|
import { MouseButton } from '../../handlers/gestureHandlerCommon';
|
|
13
|
+
import KeyboardEventManager from './KeyboardEventManager';
|
|
14
|
+
|
|
15
|
+
interface DefaultViewStyles {
|
|
16
|
+
userSelect: string;
|
|
17
|
+
touchAction: string;
|
|
18
|
+
}
|
|
14
19
|
|
|
15
20
|
export class GestureHandlerWebDelegate
|
|
16
21
|
implements GestureHandlerDelegate<HTMLElement, IGestureHandler>
|
|
17
22
|
{
|
|
23
|
+
private isInitialized = false;
|
|
18
24
|
private view!: HTMLElement;
|
|
19
25
|
private gestureHandler!: IGestureHandler;
|
|
20
26
|
private eventManagers: EventManager<unknown>[] = [];
|
|
27
|
+
private defaultViewStyles: DefaultViewStyles = {
|
|
28
|
+
userSelect: '',
|
|
29
|
+
touchAction: '',
|
|
30
|
+
};
|
|
21
31
|
|
|
22
32
|
getView(): HTMLElement {
|
|
23
33
|
return this.view;
|
|
@@ -30,22 +40,24 @@ export class GestureHandlerWebDelegate
|
|
|
30
40
|
);
|
|
31
41
|
}
|
|
32
42
|
|
|
43
|
+
this.isInitialized = true;
|
|
44
|
+
|
|
33
45
|
this.gestureHandler = handler;
|
|
34
46
|
this.view = findNodeHandle(viewRef) as unknown as HTMLElement;
|
|
35
47
|
|
|
36
|
-
|
|
48
|
+
this.defaultViewStyles = {
|
|
49
|
+
userSelect: this.view.style.userSelect,
|
|
50
|
+
touchAction: this.view.style.touchAction,
|
|
51
|
+
};
|
|
37
52
|
|
|
38
|
-
|
|
53
|
+
const config = handler.getConfig();
|
|
39
54
|
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
|
|
43
|
-
this.view.style['touchAction'] = config.touchAction ?? 'none';
|
|
44
|
-
// @ts-ignore This one disables default events on Safari
|
|
45
|
-
this.view.style['WebkitTouchCallout'] = 'none';
|
|
55
|
+
this.setUserSelect(config.enabled);
|
|
56
|
+
this.setTouchAction(config.enabled);
|
|
57
|
+
this.setContextMenu(config.enabled);
|
|
46
58
|
|
|
47
59
|
this.eventManagers.push(new PointerEventManager(this.view));
|
|
48
|
-
this.eventManagers.push(new
|
|
60
|
+
this.eventManagers.push(new KeyboardEventManager(this.view));
|
|
49
61
|
|
|
50
62
|
this.eventManagers.forEach((manager) =>
|
|
51
63
|
this.gestureHandler.attachEventManager(manager)
|
|
@@ -117,6 +129,51 @@ export class GestureHandlerWebDelegate
|
|
|
117
129
|
e.stopPropagation();
|
|
118
130
|
}
|
|
119
131
|
|
|
132
|
+
private setUserSelect(isHandlerEnabled: boolean) {
|
|
133
|
+
const { userSelect } = this.gestureHandler.getConfig();
|
|
134
|
+
|
|
135
|
+
this.view.style['userSelect'] = isHandlerEnabled
|
|
136
|
+
? userSelect ?? 'none'
|
|
137
|
+
: this.defaultViewStyles.userSelect;
|
|
138
|
+
|
|
139
|
+
this.view.style['webkitUserSelect'] = isHandlerEnabled
|
|
140
|
+
? userSelect ?? 'none'
|
|
141
|
+
: this.defaultViewStyles.userSelect;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private setTouchAction(isHandlerEnabled: boolean) {
|
|
145
|
+
const { touchAction } = this.gestureHandler.getConfig();
|
|
146
|
+
|
|
147
|
+
this.view.style['touchAction'] = isHandlerEnabled
|
|
148
|
+
? touchAction ?? 'none'
|
|
149
|
+
: this.defaultViewStyles.touchAction;
|
|
150
|
+
|
|
151
|
+
// @ts-ignore This one disables default events on Safari
|
|
152
|
+
this.view.style['WebkitTouchCallout'] = isHandlerEnabled
|
|
153
|
+
? touchAction ?? 'none'
|
|
154
|
+
: this.defaultViewStyles.touchAction;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private setContextMenu(isHandlerEnabled: boolean) {
|
|
158
|
+
const config = this.gestureHandler.getConfig();
|
|
159
|
+
|
|
160
|
+
if (isHandlerEnabled) {
|
|
161
|
+
this.addContextMenuListeners(config);
|
|
162
|
+
} else {
|
|
163
|
+
this.removeContextMenuListeners(config);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
onEnabledChange(enabled: boolean): void {
|
|
168
|
+
if (!this.isInitialized) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.setUserSelect(enabled);
|
|
173
|
+
this.setTouchAction(enabled);
|
|
174
|
+
this.setContextMenu(enabled);
|
|
175
|
+
}
|
|
176
|
+
|
|
120
177
|
onBegin(): void {
|
|
121
178
|
// no-op for now
|
|
122
179
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { AdaptedEvent, EventTypes } from '../interfaces';
|
|
2
|
+
import EventManager from './EventManager';
|
|
3
|
+
import { PointerType } from '../../PointerType';
|
|
4
|
+
|
|
5
|
+
export default class KeyboardEventManager extends EventManager<HTMLElement> {
|
|
6
|
+
private activationKeys = ['Enter', ' '];
|
|
7
|
+
private cancelationKeys = ['Tab'];
|
|
8
|
+
private isPressed = false;
|
|
9
|
+
|
|
10
|
+
private keyDownCallback = (event: KeyboardEvent): void => {
|
|
11
|
+
if (this.cancelationKeys.indexOf(event.key) !== -1 && this.isPressed) {
|
|
12
|
+
this.dispatchEvent(event, EventTypes.CANCEL);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (this.activationKeys.indexOf(event.key) === -1) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.dispatchEvent(event, EventTypes.DOWN);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
private keyUpCallback = (event: KeyboardEvent): void => {
|
|
24
|
+
if (this.activationKeys.indexOf(event.key) === -1 || !this.isPressed) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.dispatchEvent(event, EventTypes.UP);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
private dispatchEvent(event: KeyboardEvent, eventType: EventTypes) {
|
|
32
|
+
if (!(event.target instanceof HTMLElement)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const adaptedEvent = this.mapEvent(event, eventType);
|
|
37
|
+
|
|
38
|
+
switch (eventType) {
|
|
39
|
+
case EventTypes.UP:
|
|
40
|
+
this.isPressed = false;
|
|
41
|
+
this.onPointerUp(adaptedEvent);
|
|
42
|
+
break;
|
|
43
|
+
case EventTypes.DOWN:
|
|
44
|
+
this.isPressed = true;
|
|
45
|
+
this.onPointerDown(adaptedEvent);
|
|
46
|
+
break;
|
|
47
|
+
case EventTypes.CANCEL:
|
|
48
|
+
this.isPressed = false;
|
|
49
|
+
this.onPointerCancel(adaptedEvent);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public registerListeners(): void {
|
|
55
|
+
this.view.addEventListener('keydown', this.keyDownCallback);
|
|
56
|
+
this.view.addEventListener('keyup', this.keyUpCallback);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public unregisterListeners(): void {
|
|
60
|
+
this.view.addEventListener('keydown', this.keyDownCallback);
|
|
61
|
+
this.view.addEventListener('keyup', this.keyUpCallback);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected mapEvent(
|
|
65
|
+
event: KeyboardEvent,
|
|
66
|
+
eventType: EventTypes
|
|
67
|
+
): AdaptedEvent {
|
|
68
|
+
const viewRect = (event.target as HTMLElement).getBoundingClientRect();
|
|
69
|
+
|
|
70
|
+
const viewportPosition = {
|
|
71
|
+
x: viewRect?.x + viewRect?.width / 2,
|
|
72
|
+
y: viewRect?.y + viewRect?.height / 2,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const relativePosition = {
|
|
76
|
+
x: viewRect?.width / 2,
|
|
77
|
+
y: viewRect?.height / 2,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
x: viewportPosition.x,
|
|
82
|
+
y: viewportPosition.y,
|
|
83
|
+
offsetX: relativePosition.x,
|
|
84
|
+
offsetY: relativePosition.y,
|
|
85
|
+
pointerId: 0,
|
|
86
|
+
eventType: eventType,
|
|
87
|
+
pointerType: PointerType.KEY,
|
|
88
|
+
time: event.timeStamp,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -4,15 +4,12 @@ import { AdaptedEvent, EventTypes, Point } from '../interfaces';
|
|
|
4
4
|
import {
|
|
5
5
|
PointerTypeMapping,
|
|
6
6
|
calculateViewScale,
|
|
7
|
+
tryExtractStylusData,
|
|
7
8
|
isPointerInBounds,
|
|
8
9
|
} from '../utils';
|
|
9
10
|
import { PointerType } from '../../PointerType';
|
|
10
11
|
|
|
11
12
|
const POINTER_CAPTURE_EXCLUDE_LIST = new Set<string>(['SELECT', 'INPUT']);
|
|
12
|
-
const PointerTypes = {
|
|
13
|
-
Touch: 'touch',
|
|
14
|
-
Stylus: 'pen',
|
|
15
|
-
};
|
|
16
13
|
|
|
17
14
|
export default class PointerEventManager extends EventManager<HTMLElement> {
|
|
18
15
|
private trackedPointers = new Set<number>();
|
|
@@ -35,9 +32,6 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
|
|
|
35
32
|
}
|
|
36
33
|
|
|
37
34
|
private pointerDownCallback = (event: PointerEvent) => {
|
|
38
|
-
if (event.pointerType === PointerTypes.Touch) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
35
|
if (!isPointerInBounds(this.view, { x: event.clientX, y: event.clientY })) {
|
|
42
36
|
return;
|
|
43
37
|
}
|
|
@@ -61,10 +55,6 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
|
|
|
61
55
|
};
|
|
62
56
|
|
|
63
57
|
private pointerUpCallback = (event: PointerEvent) => {
|
|
64
|
-
if (event.pointerType === PointerTypes.Touch) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
58
|
// When we call reset on gesture handlers, it also resets their event managers
|
|
69
59
|
// In some handlers (like RotationGestureHandler) reset is called before all pointers leave view
|
|
70
60
|
// This means, that activePointersCounter will be set to 0, while there are still remaining pointers on view
|
|
@@ -92,21 +82,6 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
|
|
|
92
82
|
};
|
|
93
83
|
|
|
94
84
|
private pointerMoveCallback = (event: PointerEvent) => {
|
|
95
|
-
if (event.pointerType === PointerTypes.Touch) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Stylus triggers `pointermove` event when it detects changes in pressure. Since it is very sensitive to those changes,
|
|
100
|
-
// it constantly sends events, even though there was no change in position. To fix that we check whether
|
|
101
|
-
// pointer has actually moved and if not, we do not send event.
|
|
102
|
-
if (
|
|
103
|
-
event.pointerType === PointerTypes.Stylus &&
|
|
104
|
-
event.x === this.lastPosition.x &&
|
|
105
|
-
event.y === this.lastPosition.y
|
|
106
|
-
) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
85
|
const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.MOVE);
|
|
111
86
|
const target = event.target as HTMLElement;
|
|
112
87
|
|
|
@@ -161,10 +136,6 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
|
|
|
161
136
|
};
|
|
162
137
|
|
|
163
138
|
private pointerCancelCallback = (event: PointerEvent) => {
|
|
164
|
-
if (event.pointerType === PointerTypes.Touch) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
139
|
const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.CANCEL);
|
|
169
140
|
|
|
170
141
|
this.onPointerCancel(adaptedEvent);
|
|
@@ -174,20 +145,12 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
|
|
|
174
145
|
};
|
|
175
146
|
|
|
176
147
|
private pointerEnterCallback = (event: PointerEvent) => {
|
|
177
|
-
if (event.pointerType === PointerTypes.Touch) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
148
|
const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.ENTER);
|
|
182
149
|
|
|
183
150
|
this.onPointerMoveOver(adaptedEvent);
|
|
184
151
|
};
|
|
185
152
|
|
|
186
153
|
private pointerLeaveCallback = (event: PointerEvent) => {
|
|
187
|
-
if (event.pointerType === PointerTypes.Touch) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
154
|
const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.LEAVE);
|
|
192
155
|
|
|
193
156
|
this.onPointerMoveOut(adaptedEvent);
|
|
@@ -252,6 +215,7 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
|
|
|
252
215
|
PointerTypeMapping.get(event.pointerType) ?? PointerType.OTHER,
|
|
253
216
|
button: this.mouseButtonsMapper.get(event.button),
|
|
254
217
|
time: event.timeStamp,
|
|
218
|
+
stylusData: tryExtractStylusData(event),
|
|
255
219
|
};
|
|
256
220
|
}
|
|
257
221
|
|
package/src/web/tools/Vector.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DiagonalDirections, Directions } from '../../Directions';
|
|
2
|
-
import {
|
|
2
|
+
import { MINIMAL_RECOGNIZABLE_MAGNITUDE } from '../constants';
|
|
3
3
|
import PointerTracker from './PointerTracker';
|
|
4
4
|
|
|
5
5
|
export default class Vector {
|
|
@@ -14,14 +14,15 @@ export default class Vector {
|
|
|
14
14
|
this.y = y;
|
|
15
15
|
|
|
16
16
|
this._magnitude = Math.hypot(this.x, this.y);
|
|
17
|
-
const isMagnitudeSufficient =
|
|
17
|
+
const isMagnitudeSufficient =
|
|
18
|
+
this._magnitude > MINIMAL_RECOGNIZABLE_MAGNITUDE;
|
|
18
19
|
|
|
19
20
|
this.unitX = isMagnitudeSufficient ? this.x / this._magnitude : 0;
|
|
20
21
|
this.unitY = isMagnitudeSufficient ? this.y / this._magnitude : 0;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
static fromDirection(direction: Directions | DiagonalDirections): Vector {
|
|
24
|
-
return DirectionToVectorMappings.get(direction)
|
|
25
|
+
return DirectionToVectorMappings.get(direction) ?? new Vector(0, 0);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
static fromVelocity(tracker: PointerTracker, pointerId: number) {
|
package/src/web/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PointerType } from '../PointerType';
|
|
2
|
-
import { Point } from './interfaces';
|
|
2
|
+
import type { Point, StylusData } from './interfaces';
|
|
3
3
|
|
|
4
4
|
export function isPointerInBounds(view: HTMLElement, { x, y }: Point): boolean {
|
|
5
5
|
const rect: DOMRect = view.getBoundingClientRect();
|
|
@@ -27,28 +27,203 @@ export function calculateViewScale(view: HTMLElement) {
|
|
|
27
27
|
scaleY: 1,
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
// Get scales from scale property
|
|
31
|
+
if (styles.scale !== undefined && styles.scale !== 'none') {
|
|
32
|
+
const scales = styles.scale.split(' ');
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
if (scales[0]) {
|
|
35
|
+
resultScales.scaleX = parseFloat(scales[0]);
|
|
36
|
+
}
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
resultScales.scaleY = scales[1]
|
|
39
|
+
? parseFloat(scales[1])
|
|
40
|
+
: parseFloat(scales[0]);
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
// Get scales from transform property
|
|
40
44
|
const matrixElements = new RegExp(/matrix\((.+)\)/).exec(
|
|
41
45
|
styles.transform
|
|
42
46
|
)?.[1];
|
|
43
47
|
|
|
44
|
-
if (
|
|
45
|
-
|
|
48
|
+
if (matrixElements) {
|
|
49
|
+
const matrixElementsArray = matrixElements.split(', ');
|
|
50
|
+
|
|
51
|
+
resultScales.scaleX *= parseFloat(matrixElementsArray[0]);
|
|
52
|
+
resultScales.scaleY *= parseFloat(matrixElementsArray[3]);
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
return resultScales;
|
|
56
|
+
}
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
export function tryExtractStylusData(
|
|
59
|
+
event: PointerEvent
|
|
60
|
+
): StylusData | undefined {
|
|
61
|
+
const pointerType = PointerTypeMapping.get(event.pointerType);
|
|
52
62
|
|
|
53
|
-
|
|
63
|
+
if (pointerType !== PointerType.STYLUS) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// @ts-ignore This property exists (https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent#instance_properties)
|
|
68
|
+
const eventAzimuthAngle: number | undefined = event.azimuthAngle;
|
|
69
|
+
// @ts-ignore This property exists (https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent#instance_properties)
|
|
70
|
+
const eventAltitudeAngle: number | undefined = event.altitudeAngle;
|
|
71
|
+
|
|
72
|
+
if (event.tiltX === 0 && event.tiltY === 0) {
|
|
73
|
+
// If we are in this branch, it means that either tilt properties are not supported and we have to calculate them from altitude and azimuth angles,
|
|
74
|
+
// or stylus is perpendicular to the screen and we can use altitude / azimuth instead of tilt
|
|
75
|
+
|
|
76
|
+
// If azimuth and altitude are undefined in this branch, it means that we are either perpendicular to the screen,
|
|
77
|
+
// or that none of the position sets is supported. In that case, we can treat stylus as perpendicular
|
|
78
|
+
if (eventAzimuthAngle === undefined || eventAltitudeAngle === undefined) {
|
|
79
|
+
return {
|
|
80
|
+
tiltX: 0,
|
|
81
|
+
tiltY: 0,
|
|
82
|
+
azimuthAngle: Math.PI / 2,
|
|
83
|
+
altitudeAngle: Math.PI / 2,
|
|
84
|
+
pressure: event.pressure,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const { tiltX, tiltY } = spherical2tilt(
|
|
89
|
+
eventAltitudeAngle,
|
|
90
|
+
eventAzimuthAngle
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
tiltX,
|
|
95
|
+
tiltY,
|
|
96
|
+
azimuthAngle: eventAzimuthAngle,
|
|
97
|
+
altitudeAngle: eventAltitudeAngle,
|
|
98
|
+
pressure: event.pressure,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const { altitudeAngle, azimuthAngle } = tilt2spherical(
|
|
103
|
+
event.tiltX,
|
|
104
|
+
event.tiltY
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
tiltX: event.tiltX,
|
|
109
|
+
tiltY: event.tiltY,
|
|
110
|
+
azimuthAngle,
|
|
111
|
+
altitudeAngle,
|
|
112
|
+
pressure: event.pressure,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// `altitudeAngle` and `azimuthAngle` are experimental properties, which are not supported on Firefox and Safari.
|
|
117
|
+
// Given that, we use `tilt` properties and algorithm that converts one value to another.
|
|
118
|
+
//
|
|
119
|
+
// Source: https://w3c.github.io/pointerevents/#converting-between-tiltx-tilty-and-altitudeangle-azimuthangle
|
|
120
|
+
function tilt2spherical(tiltX: number, tiltY: number) {
|
|
121
|
+
const tiltXrad = (tiltX * Math.PI) / 180;
|
|
122
|
+
const tiltYrad = (tiltY * Math.PI) / 180;
|
|
123
|
+
|
|
124
|
+
// calculate azimuth angle
|
|
125
|
+
let azimuthAngle = 0;
|
|
126
|
+
|
|
127
|
+
if (tiltX === 0) {
|
|
128
|
+
if (tiltY > 0) {
|
|
129
|
+
azimuthAngle = Math.PI / 2;
|
|
130
|
+
} else if (tiltY < 0) {
|
|
131
|
+
azimuthAngle = (3 * Math.PI) / 2;
|
|
132
|
+
}
|
|
133
|
+
} else if (tiltY === 0) {
|
|
134
|
+
if (tiltX < 0) {
|
|
135
|
+
azimuthAngle = Math.PI;
|
|
136
|
+
}
|
|
137
|
+
} else if (Math.abs(tiltX) === 90 || Math.abs(tiltY) === 90) {
|
|
138
|
+
// not enough information to calculate azimuth
|
|
139
|
+
azimuthAngle = 0;
|
|
140
|
+
} else {
|
|
141
|
+
// Non-boundary case: neither tiltX nor tiltY is equal to 0 or +-90
|
|
142
|
+
const tanX = Math.tan(tiltXrad);
|
|
143
|
+
const tanY = Math.tan(tiltYrad);
|
|
144
|
+
|
|
145
|
+
azimuthAngle = Math.atan2(tanY, tanX);
|
|
146
|
+
if (azimuthAngle < 0) {
|
|
147
|
+
azimuthAngle += 2 * Math.PI;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// calculate altitude angle
|
|
152
|
+
let altitudeAngle = 0;
|
|
153
|
+
|
|
154
|
+
if (Math.abs(tiltX) === 90 || Math.abs(tiltY) === 90) {
|
|
155
|
+
altitudeAngle = 0;
|
|
156
|
+
} else if (tiltX === 0) {
|
|
157
|
+
altitudeAngle = Math.PI / 2 - Math.abs(tiltYrad);
|
|
158
|
+
} else if (tiltY === 0) {
|
|
159
|
+
altitudeAngle = Math.PI / 2 - Math.abs(tiltXrad);
|
|
160
|
+
} else {
|
|
161
|
+
// Non-boundary case: neither tiltX nor tiltY is equal to 0 or +-90
|
|
162
|
+
altitudeAngle = Math.atan(
|
|
163
|
+
1.0 /
|
|
164
|
+
Math.sqrt(
|
|
165
|
+
Math.pow(Math.tan(tiltXrad), 2) + Math.pow(Math.tan(tiltYrad), 2)
|
|
166
|
+
)
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { altitudeAngle: altitudeAngle, azimuthAngle: azimuthAngle };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// If we are on a platform that doesn't support `tiltX` and `tiltY`, we have to calculate them from `altitude` and `azimuth` angles.
|
|
174
|
+
//
|
|
175
|
+
// Source: https://w3c.github.io/pointerevents/#converting-between-tiltx-tilty-and-altitudeangle-azimuthangle
|
|
176
|
+
function spherical2tilt(altitudeAngle: number, azimuthAngle: number) {
|
|
177
|
+
const radToDeg = 180 / Math.PI;
|
|
178
|
+
|
|
179
|
+
let tiltXrad = 0;
|
|
180
|
+
let tiltYrad = 0;
|
|
181
|
+
|
|
182
|
+
if (altitudeAngle === 0) {
|
|
183
|
+
// the pen is in the X-Y plane
|
|
184
|
+
if (azimuthAngle === 0 || azimuthAngle === 2 * Math.PI) {
|
|
185
|
+
// pen is on positive X axis
|
|
186
|
+
tiltXrad = Math.PI / 2;
|
|
187
|
+
}
|
|
188
|
+
if (azimuthAngle === Math.PI / 2) {
|
|
189
|
+
// pen is on positive Y axis
|
|
190
|
+
tiltYrad = Math.PI / 2;
|
|
191
|
+
}
|
|
192
|
+
if (azimuthAngle === Math.PI) {
|
|
193
|
+
// pen is on negative X axis
|
|
194
|
+
tiltXrad = -Math.PI / 2;
|
|
195
|
+
}
|
|
196
|
+
if (azimuthAngle === (3 * Math.PI) / 2) {
|
|
197
|
+
// pen is on negative Y axis
|
|
198
|
+
tiltYrad = -Math.PI / 2;
|
|
199
|
+
}
|
|
200
|
+
if (azimuthAngle > 0 && azimuthAngle < Math.PI / 2) {
|
|
201
|
+
tiltXrad = Math.PI / 2;
|
|
202
|
+
tiltYrad = Math.PI / 2;
|
|
203
|
+
}
|
|
204
|
+
if (azimuthAngle > Math.PI / 2 && azimuthAngle < Math.PI) {
|
|
205
|
+
tiltXrad = -Math.PI / 2;
|
|
206
|
+
tiltYrad = Math.PI / 2;
|
|
207
|
+
}
|
|
208
|
+
if (azimuthAngle > Math.PI && azimuthAngle < (3 * Math.PI) / 2) {
|
|
209
|
+
tiltXrad = -Math.PI / 2;
|
|
210
|
+
tiltYrad = -Math.PI / 2;
|
|
211
|
+
}
|
|
212
|
+
if (azimuthAngle > (3 * Math.PI) / 2 && azimuthAngle < 2 * Math.PI) {
|
|
213
|
+
tiltXrad = Math.PI / 2;
|
|
214
|
+
tiltYrad = -Math.PI / 2;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (altitudeAngle !== 0) {
|
|
219
|
+
const tanAlt = Math.tan(altitudeAngle);
|
|
220
|
+
|
|
221
|
+
tiltXrad = Math.atan(Math.cos(azimuthAngle) / tanAlt);
|
|
222
|
+
tiltYrad = Math.atan(Math.sin(azimuthAngle) / tanAlt);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const tiltX = Math.round(tiltXrad * radToDeg);
|
|
226
|
+
const tiltY = Math.round(tiltYrad * radToDeg);
|
|
227
|
+
|
|
228
|
+
return { tiltX, tiltY };
|
|
54
229
|
}
|