react-native-gesture-handler 2.19.0 → 2.20.0
Sign up to get free protection for your applications and to get access to all the features.
- package/android/build.gradle +7 -12
- 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/java/com/swmansion/gesturehandler/core/GestureUtils.kt +1 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/HoverGestureHandler.kt +11 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +8 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/StylusData.kt +103 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +24 -15
- 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/RNLongPressHandler.m +2 -0
- 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/RNGestureHandlerButtonComponentView.mm +35 -0
- package/apple/RNGestureHandlerEvents.h +3 -1
- package/apple/RNGestureHandlerEvents.m +11 -3
- 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 +5 -14
- package/lib/commonjs/components/Pressable/Pressable.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/handlers/GestureHandlerEventPayload.js +4 -0
- package/lib/commonjs/handlers/createHandler.js +2 -1
- package/lib/commonjs/handlers/createHandler.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/jestUtils/jestUtils.js +12 -4
- package/lib/commonjs/jestUtils/jestUtils.js.map +1 -1
- package/lib/commonjs/web/handlers/GestureHandler.js +1 -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/PanGestureHandler.js +8 -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 +0 -3
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/commonjs/web/tools/PointerEventManager.js +3 -37
- package/lib/commonjs/web/tools/PointerEventManager.js.map +1 -1
- package/lib/commonjs/web/utils.js +173 -0
- package/lib/commonjs/web/utils.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 +7 -14
- package/lib/module/components/Pressable/Pressable.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/handlers/GestureHandlerEventPayload.js +1 -1
- package/lib/module/handlers/createHandler.js +2 -1
- package/lib/module/handlers/createHandler.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/jestUtils/jestUtils.js +12 -4
- package/lib/module/jestUtils/jestUtils.js.map +1 -1
- package/lib/module/web/handlers/GestureHandler.js +1 -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/PanGestureHandler.js +8 -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 +0 -2
- package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/module/web/tools/PointerEventManager.js +4 -38
- package/lib/module/web/tools/PointerEventManager.js.map +1 -1
- package/lib/module/web/utils.js +170 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/components/GestureComponents.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/gestures/gesture.d.ts +2 -2
- package/lib/typescript/handlers/gestures/hoverGesture.d.ts +1 -6
- package/lib/typescript/handlers/handlersRegistry.d.ts +1 -1
- package/lib/typescript/jestUtils/jestUtils.d.ts +1 -1
- package/lib/typescript/web/handlers/HoverGestureHandler.d.ts +2 -0
- package/lib/typescript/web/handlers/PanGestureHandler.d.ts +3 -1
- package/lib/typescript/web/interfaces.d.ts +8 -3
- package/lib/typescript/web/tools/EventManager.d.ts +2 -2
- package/lib/typescript/web/utils.d.ts +2 -1
- package/package.json +1 -1
- package/src/components/GestureButtons.tsx +2 -1
- package/src/components/GestureComponents.tsx +1 -1
- package/src/components/Pressable/Pressable.tsx +16 -29
- package/src/components/Pressable/utils.ts +5 -49
- package/src/handlers/GestureHandlerEventPayload.ts +42 -0
- package/src/handlers/createHandler.tsx +1 -0
- package/src/handlers/gestures/gesture.ts +3 -1
- package/src/handlers/gestures/hoverGesture.ts +1 -7
- package/src/jestUtils/jestUtils.ts +9 -1
- package/src/web/handlers/GestureHandler.ts +1 -1
- package/src/web/handlers/HoverGestureHandler.ts +16 -2
- package/src/web/handlers/PanGestureHandler.ts +10 -1
- package/src/web/interfaces.ts +9 -3
- package/src/web/tools/EventManager.ts +2 -4
- package/src/web/tools/GestureHandlerWebDelegate.ts +0 -2
- package/src/web/tools/PointerEventManager.ts +2 -38
- package/src/web/utils.ts +174 -1
- 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,3 +1,5 @@
|
|
1
|
+
import { StylusData } from '../web/interfaces';
|
2
|
+
|
1
3
|
export type FlingGestureHandlerEventPayload = {
|
2
4
|
x: number;
|
3
5
|
y: number;
|
@@ -120,6 +122,11 @@ export type PanGestureHandlerEventPayload = {
|
|
120
122
|
* value is expressed in point units per second.
|
121
123
|
*/
|
122
124
|
velocityY: number;
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Object containing additional stylus data.
|
128
|
+
*/
|
129
|
+
stylusData: StylusData | undefined;
|
123
130
|
};
|
124
131
|
|
125
132
|
export type PinchGestureHandlerEventPayload = {
|
@@ -182,3 +189,38 @@ export type RotationGestureHandlerEventPayload = {
|
|
182
189
|
*/
|
183
190
|
velocity: number;
|
184
191
|
};
|
192
|
+
|
193
|
+
export type HoverGestureHandlerEventPayload = {
|
194
|
+
/**
|
195
|
+
* X coordinate of the current position of the pointer relative to the view
|
196
|
+
* attached to the handler. Expressed in point units.
|
197
|
+
*/
|
198
|
+
x: number;
|
199
|
+
|
200
|
+
/**
|
201
|
+
* Y coordinate of the current position of the pointer relative to the view
|
202
|
+
* attached to the handler. Expressed in point units.
|
203
|
+
*/
|
204
|
+
y: number;
|
205
|
+
|
206
|
+
/**
|
207
|
+
* X coordinate of the current position of the pointer relative to the window.
|
208
|
+
* The value is expressed in point units. It is recommended to use it instead
|
209
|
+
* of `x` in cases when the original view can be transformed as an
|
210
|
+
* effect of the gesture.
|
211
|
+
*/
|
212
|
+
absoluteX: number;
|
213
|
+
|
214
|
+
/**
|
215
|
+
* Y coordinate of the current position of the pointer relative to the window.
|
216
|
+
* The value is expressed in point units. It is recommended to use it instead
|
217
|
+
* of `y` in cases when the original view can be transformed as an
|
218
|
+
* effect of the gesture.
|
219
|
+
*/
|
220
|
+
absoluteY: number;
|
221
|
+
|
222
|
+
/**
|
223
|
+
* Object containing additional stylus data.
|
224
|
+
*/
|
225
|
+
stylusData: StylusData | undefined;
|
226
|
+
};
|
@@ -18,6 +18,7 @@ import type {
|
|
18
18
|
RotationGestureHandlerEventPayload,
|
19
19
|
TapGestureHandlerEventPayload,
|
20
20
|
NativeViewGestureHandlerPayload,
|
21
|
+
HoverGestureHandlerEventPayload,
|
21
22
|
} from '../GestureHandlerEventPayload';
|
22
23
|
import { isRemoteDebuggingEnabled } from '../../utils';
|
23
24
|
|
@@ -31,7 +32,8 @@ export type GestureType =
|
|
31
32
|
| BaseGesture<PinchGestureHandlerEventPayload>
|
32
33
|
| BaseGesture<FlingGestureHandlerEventPayload>
|
33
34
|
| BaseGesture<ForceTouchGestureHandlerEventPayload>
|
34
|
-
| BaseGesture<NativeViewGestureHandlerPayload
|
35
|
+
| BaseGesture<NativeViewGestureHandlerPayload>
|
36
|
+
| BaseGesture<HoverGestureHandlerEventPayload>;
|
35
37
|
|
36
38
|
export type GestureRef =
|
37
39
|
| number
|
@@ -1,12 +1,6 @@
|
|
1
1
|
import { BaseGestureConfig, ContinousBaseGesture } from './gesture';
|
2
2
|
import { GestureUpdateEvent } from '../gestureHandlerCommon';
|
3
|
-
|
4
|
-
export type HoverGestureHandlerEventPayload = {
|
5
|
-
x: number;
|
6
|
-
y: number;
|
7
|
-
absoluteX: number;
|
8
|
-
absoluteY: number;
|
9
|
-
};
|
3
|
+
import type { HoverGestureHandlerEventPayload } from '../GestureHandlerEventPayload';
|
10
4
|
|
11
5
|
export type HoverGestureChangeEventPayload = {
|
12
6
|
changeX: number;
|
@@ -138,6 +138,7 @@ const handlersDefaultEvents: DefaultEventsMapping = {
|
|
138
138
|
velocityX: 3,
|
139
139
|
velocityY: 0,
|
140
140
|
numberOfPointers: 1,
|
141
|
+
stylusData: undefined,
|
141
142
|
},
|
142
143
|
[pinchHandlerName]: {
|
143
144
|
focalX: 0,
|
@@ -404,6 +405,7 @@ interface HandlerData {
|
|
404
405
|
emitEvent: EventEmitter;
|
405
406
|
handlerType: HandlerNames;
|
406
407
|
handlerTag: number;
|
408
|
+
enabled: boolean | undefined;
|
407
409
|
}
|
408
410
|
function getHandlerData(
|
409
411
|
componentOrGesture: ReactTestInstance | GestureType
|
@@ -416,6 +418,7 @@ function getHandlerData(
|
|
416
418
|
},
|
417
419
|
handlerType: gesture.handlerName as HandlerNames,
|
418
420
|
handlerTag: gesture.handlerTag,
|
421
|
+
enabled: gesture.config.enabled,
|
419
422
|
};
|
420
423
|
}
|
421
424
|
const gestureHandlerComponent = componentOrGesture;
|
@@ -425,6 +428,7 @@ function getHandlerData(
|
|
425
428
|
},
|
426
429
|
handlerType: gestureHandlerComponent.props.handlerType as HandlerNames,
|
427
430
|
handlerTag: gestureHandlerComponent.props.handlerTag as number,
|
431
|
+
enabled: gestureHandlerComponent.props.enabled,
|
428
432
|
};
|
429
433
|
}
|
430
434
|
type AllGestures =
|
@@ -466,9 +470,13 @@ export function fireGestureHandler<THandler extends AllGestures | AllHandlers>(
|
|
466
470
|
componentOrGesture: ReactTestInstance | GestureType,
|
467
471
|
eventList: Partial<GestureHandlerTestEvent<ExtractConfig<THandler>>>[] = []
|
468
472
|
): void {
|
469
|
-
const { emitEvent, handlerType, handlerTag } =
|
473
|
+
const { emitEvent, handlerType, handlerTag, enabled } =
|
470
474
|
getHandlerData(componentOrGesture);
|
471
475
|
|
476
|
+
if (enabled === false) {
|
477
|
+
return;
|
478
|
+
}
|
479
|
+
|
472
480
|
let _ = fillMissingStatesTransitions(
|
473
481
|
eventList,
|
474
482
|
isDiscreteHandler(handlerType)
|
@@ -507,7 +507,7 @@ export default abstract class GestureHandler implements IGestureHandler {
|
|
507
507
|
nativeEvent: {
|
508
508
|
handlerTag: this.handlerTag,
|
509
509
|
state: this.currentState,
|
510
|
-
eventType:
|
510
|
+
eventType: eventType,
|
511
511
|
changedTouches: changed,
|
512
512
|
allTouches: all,
|
513
513
|
numberOfTouches: numberOfTouches,
|
@@ -1,13 +1,22 @@
|
|
1
1
|
import { State } from '../../State';
|
2
|
-
import { AdaptedEvent, Config } from '../interfaces';
|
2
|
+
import { AdaptedEvent, Config, StylusData } from '../interfaces';
|
3
3
|
import GestureHandlerOrchestrator from '../tools/GestureHandlerOrchestrator';
|
4
4
|
import GestureHandler from './GestureHandler';
|
5
5
|
|
6
6
|
export default class HoverGestureHandler extends GestureHandler {
|
7
|
+
private stylusData: StylusData | undefined;
|
8
|
+
|
7
9
|
public init(ref: number, propsRef: React.RefObject<unknown>) {
|
8
10
|
super.init(ref, propsRef);
|
9
11
|
}
|
10
12
|
|
13
|
+
protected transformNativeEvent(): Record<string, unknown> {
|
14
|
+
return {
|
15
|
+
...super.transformNativeEvent(),
|
16
|
+
stylusData: this.stylusData,
|
17
|
+
};
|
18
|
+
}
|
19
|
+
|
11
20
|
public updateGestureConfig({ enabled = true, ...props }: Config): void {
|
12
21
|
super.updateGestureConfig({ enabled: enabled, ...props });
|
13
22
|
}
|
@@ -16,6 +25,7 @@ export default class HoverGestureHandler extends GestureHandler {
|
|
16
25
|
GestureHandlerOrchestrator.getInstance().recordHandlerIfNotPresent(this);
|
17
26
|
|
18
27
|
this.tracker.addToTracker(event);
|
28
|
+
this.stylusData = event.stylusData;
|
19
29
|
super.onPointerMoveOver(event);
|
20
30
|
|
21
31
|
if (this.getState() === State.UNDETERMINED) {
|
@@ -25,7 +35,9 @@ export default class HoverGestureHandler extends GestureHandler {
|
|
25
35
|
}
|
26
36
|
|
27
37
|
protected onPointerMoveOut(event: AdaptedEvent): void {
|
28
|
-
this.tracker.
|
38
|
+
this.tracker.removeFromTracker(event.pointerId);
|
39
|
+
this.stylusData = event.stylusData;
|
40
|
+
|
29
41
|
super.onPointerMoveOut(event);
|
30
42
|
|
31
43
|
this.end();
|
@@ -33,6 +45,8 @@ export default class HoverGestureHandler extends GestureHandler {
|
|
33
45
|
|
34
46
|
protected onPointerMove(event: AdaptedEvent): void {
|
35
47
|
this.tracker.track(event);
|
48
|
+
this.stylusData = event.stylusData;
|
49
|
+
|
36
50
|
super.onPointerMove(event);
|
37
51
|
}
|
38
52
|
|
@@ -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();
|
@@ -306,6 +313,7 @@ export default class PanGestureHandler extends GestureHandler {
|
|
306
313
|
|
307
314
|
protected onPointerMove(event: AdaptedEvent): void {
|
308
315
|
this.tracker.track(event);
|
316
|
+
this.stylusData = event.stylusData;
|
309
317
|
|
310
318
|
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
311
319
|
this.lastX = lastCoords.x;
|
@@ -326,6 +334,7 @@ export default class PanGestureHandler extends GestureHandler {
|
|
326
334
|
}
|
327
335
|
|
328
336
|
this.tracker.track(event);
|
337
|
+
this.stylusData = event.stylusData;
|
329
338
|
|
330
339
|
const lastCoords = this.tracker.getAbsoluteCoordsAverage();
|
331
340
|
this.lastX = lastCoords.x;
|
package/src/web/interfaces.ts
CHANGED
@@ -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,7 +5,6 @@ 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';
|
@@ -58,7 +57,6 @@ export class GestureHandlerWebDelegate
|
|
58
57
|
this.setContextMenu(config.enabled);
|
59
58
|
|
60
59
|
this.eventManagers.push(new PointerEventManager(this.view));
|
61
|
-
this.eventManagers.push(new TouchEventManager(this.view));
|
62
60
|
this.eventManagers.push(new KeyboardEventManager(this.view));
|
63
61
|
|
64
62
|
this.eventManagers.forEach((manager) =>
|
@@ -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/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();
|
@@ -54,3 +54,176 @@ export function calculateViewScale(view: HTMLElement) {
|
|
54
54
|
|
55
55
|
return resultScales;
|
56
56
|
}
|
57
|
+
|
58
|
+
export function tryExtractStylusData(
|
59
|
+
event: PointerEvent
|
60
|
+
): StylusData | undefined {
|
61
|
+
const pointerType = PointerTypeMapping.get(event.pointerType);
|
62
|
+
|
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 };
|
229
|
+
}
|