react-native-gesture-handler 1.2.1 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. package/DrawerLayout.js +5 -4
  2. package/GestureButtons.js +166 -0
  3. package/GestureComponents.js +63 -0
  4. package/GestureComponents.web.js +35 -0
  5. package/GestureHandler.js +10 -621
  6. package/GestureHandlerButton.web.js +4 -12
  7. package/GestureHandlerPropTypes.js +45 -0
  8. package/Gestures.js +278 -0
  9. package/NativeViewGestureHandler.js +14 -0
  10. package/PlatformConstants.web.js +3 -1
  11. package/RNGestureHandler.podspec +1 -1
  12. package/RNGestureHandlerModule.web.js +49 -0
  13. package/State.js +12 -1
  14. package/Swipeable.js +6 -11
  15. package/android/build.gradle +3 -7
  16. package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerOrchestrator.java +1 -1
  17. package/android/lib/src/main/java/com/swmansion/gesturehandler/PanGestureHandler.java +1 -1
  18. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEnabledRootView.java +1 -1
  19. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEvent.java +2 -2
  20. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.java +1 -1
  21. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerPackage.java +1 -1
  22. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRegistry.java +1 -1
  23. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootInterface.java +1 -1
  24. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.java +1 -1
  25. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.java +1 -1
  26. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerStateChangeEvent.java +2 -2
  27. package/createHandler.js +46 -20
  28. package/createNativeWrapper.js +86 -0
  29. package/ios/RNGestureHandler.xcodeproj/project.pbxproj +4 -4
  30. package/package.json +20 -17
  31. package/react-native-gesture-handler.d.ts +25 -3
  32. package/touchables/GenericTouchable.js +3 -1
  33. package/touchables/TouchableHighlight.js +1 -3
  34. package/touchables/TouchableOpacity.web.js +2 -0
  35. package/touchables/TouchableWithoutFeedback.js +4 -2
  36. package/web/DiscreteGestureHandler.js +66 -0
  37. package/web/DraggingGestureHandler.js +22 -0
  38. package/web/Errors.js +5 -0
  39. package/web/FlingGestureHandler.js +137 -0
  40. package/web/GestureHandler.js +442 -0
  41. package/web/IndiscreteGestureHandler.js +33 -0
  42. package/web/LongPressGestureHandler.js +50 -0
  43. package/web/NativeViewGestureHandler.js +38 -0
  44. package/web/NodeManager.js +24 -0
  45. package/web/PanGestureHandler.js +213 -0
  46. package/web/PinchGestureHandler.js +24 -0
  47. package/web/PressGestureHandler.js +147 -0
  48. package/web/RotationGestureHandler.js +24 -0
  49. package/web/TapGestureHandler.js +160 -0
  50. package/web/constants.js +48 -0
  51. package/web/utils.js +14 -0
  52. package/Directions.web.js +0 -6
  53. package/Swipeable.web.js +0 -4
  54. package/createHandler.web.js +0 -205
@@ -0,0 +1,213 @@
1
+ import Hammer from 'hammerjs';
2
+
3
+ import {
4
+ MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD,
5
+ MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD,
6
+ } from './constants';
7
+ import DraggingGestureHandler from './DraggingGestureHandler';
8
+ import { isnan, TEST_MIN_IF_NOT_NAN, VEC_LEN_SQ } from './utils';
9
+
10
+ class PanGestureHandler extends DraggingGestureHandler {
11
+ get name() {
12
+ return 'pan';
13
+ }
14
+
15
+ get NativeGestureClass() {
16
+ return Hammer.Pan;
17
+ }
18
+
19
+ getHammerConfig() {
20
+ return {
21
+ ...super.getHammerConfig(),
22
+ direction: this.getDirection(),
23
+ };
24
+ }
25
+
26
+ getDirection() {
27
+ const config = this.getConfig();
28
+ const {
29
+ activeOffsetXStart,
30
+ activeOffsetXEnd,
31
+ activeOffsetYStart,
32
+ activeOffsetYEnd,
33
+ minDist,
34
+ } = config;
35
+ let directions = [];
36
+ let horizontalDirections = [];
37
+
38
+ if (!isnan(minDist)) {
39
+ return Hammer.DIRECTION_ALL;
40
+ }
41
+
42
+ if (!isnan(activeOffsetXStart)) horizontalDirections.push(Hammer.DIRECTION_LEFT);
43
+ if (!isnan(activeOffsetXEnd)) horizontalDirections.push(Hammer.DIRECTION_RIGHT);
44
+ if (horizontalDirections.length === 2) horizontalDirections = [Hammer.DIRECTION_HORIZONTAL];
45
+
46
+ directions = directions.concat(horizontalDirections);
47
+ let verticalDirections = [];
48
+
49
+ if (!isnan(activeOffsetYStart)) verticalDirections.push(Hammer.DIRECTION_UP);
50
+ if (!isnan(activeOffsetYEnd)) verticalDirections.push(Hammer.DIRECTION_DOWN);
51
+
52
+ if (verticalDirections.length === 2) verticalDirections = [Hammer.DIRECTION_VERTICAL];
53
+
54
+ directions = directions.concat(verticalDirections);
55
+
56
+ if (!directions.length) {
57
+ return Hammer.DIRECTION_NONE;
58
+ }
59
+ if (
60
+ directions[0] === Hammer.DIRECTION_HORIZONTAL &&
61
+ directions[1] === Hammer.DIRECTION_VERTICAL
62
+ ) {
63
+ return Hammer.DIRECTION_ALL;
64
+ }
65
+ if (horizontalDirections.length && verticalDirections.length) {
66
+ return Hammer.DIRECTION_ALL;
67
+ }
68
+
69
+ return directions[0];
70
+ }
71
+
72
+ getConfig() {
73
+ if (!this._hasCustomActivationCriteria) {
74
+ // Default config
75
+ // If no params have been defined then this config should emulate the native gesture as closely as possible.
76
+ return {
77
+ minDistSq: 10,
78
+ };
79
+ }
80
+ return this.config;
81
+ }
82
+
83
+ shouldFailUnderCustomCriteria({ deltaX, deltaY }, criteria) {
84
+ return (
85
+ (!isnan(criteria.failOffsetXStart) && deltaX < criteria.failOffsetXStart) ||
86
+ (!isnan(criteria.failOffsetXEnd) && deltaX > criteria.failOffsetXEnd) ||
87
+ (!isnan(criteria.failOffsetYStart) && deltaY < criteria.failOffsetYStart) ||
88
+ (!isnan(criteria.failOffsetYEnd) && deltaY > criteria.failOffsetYEnd)
89
+ );
90
+ }
91
+
92
+ shouldActivateUnderCustomCriteria({ deltaX, deltaY, velocity }, criteria) {
93
+ return (
94
+ (!isnan(criteria.activeOffsetXStart) && deltaX < criteria.activeOffsetXStart) ||
95
+ (!isnan(criteria.activeOffsetXEnd) && deltaX > criteria.activeOffsetXEnd) ||
96
+ (!isnan(criteria.activeOffsetYStart) && deltaY < criteria.activeOffsetYStart) ||
97
+ (!isnan(criteria.activeOffsetYEnd) && deltaY > criteria.activeOffsetYEnd) ||
98
+ TEST_MIN_IF_NOT_NAN(VEC_LEN_SQ({ x: deltaX, y: deltaY }), criteria.minDistSq) ||
99
+ TEST_MIN_IF_NOT_NAN(velocity.x, criteria.minVelocityX) ||
100
+ TEST_MIN_IF_NOT_NAN(velocity.y, criteria.minVelocityY) ||
101
+ TEST_MIN_IF_NOT_NAN(VEC_LEN_SQ(velocity), criteria.minVelocitySq)
102
+ );
103
+ }
104
+
105
+ shouldMultiFingerPanFail({ pointerLength, scale, deltaRotation }) {
106
+ if (pointerLength <= 1) {
107
+ return false;
108
+ }
109
+
110
+ // Test if the pan had too much pinching or rotating.
111
+ const deltaScale = Math.abs(scale - 1);
112
+ const absDeltaRotation = Math.abs(deltaRotation);
113
+ if (deltaScale > MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD) {
114
+ // > If the threshold doesn't seem right.
115
+ // You can log the value which it failed at here:
116
+ return true;
117
+ }
118
+ if (absDeltaRotation > MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD) {
119
+ // > If the threshold doesn't seem right.
120
+ // You can log the value which it failed at here:
121
+ return true;
122
+ }
123
+
124
+ return false;
125
+ }
126
+
127
+ updateHasCustomActivationCriteria(criteria) {
128
+ return (
129
+ !isnan(criteria.minDistSq) ||
130
+ !isnan(criteria.minVelocityX) ||
131
+ !isnan(criteria.minVelocityY) ||
132
+ !isnan(criteria.minVelocitySq) ||
133
+ !isnan(criteria.activeOffsetXStart) ||
134
+ !isnan(criteria.activeOffsetXEnd) ||
135
+ !isnan(criteria.activeOffsetYStart) ||
136
+ !isnan(criteria.activeOffsetYEnd)
137
+ );
138
+ }
139
+
140
+ isGestureEnabledForEvent(props, recognizer, inputData) {
141
+ if (this.shouldFailUnderCustomCriteria(inputData, props)) {
142
+ return { failed: true };
143
+ }
144
+
145
+ const velocity = { x: inputData.velocityX, y: inputData.velocityY };
146
+ if (
147
+ this._hasCustomActivationCriteria &&
148
+ this.shouldActivateUnderCustomCriteria(
149
+ { deltaX: inputData.deltaX, deltaY: inputData.deltaY, velocity },
150
+ props
151
+ )
152
+ ) {
153
+ if (
154
+ this.shouldMultiFingerPanFail({
155
+ pointerLength: inputData.maxPointers,
156
+ scale: inputData.scale,
157
+ deltaRotation: inputData.deltaRotation,
158
+ })
159
+ ) {
160
+ return {
161
+ failed: true,
162
+ };
163
+ }
164
+ return { success: true };
165
+ }
166
+ return { success: false };
167
+ }
168
+ }
169
+
170
+ function validateConfig(config = {}) {
171
+ const isNum = v => isnan(v) || typeof v === 'number';
172
+ const isBool = v => typeof v === 'boolean';
173
+
174
+ const valid = {
175
+ enabled: isBool,
176
+ minDistSq: isNum,
177
+ minVelocityX: isNum,
178
+ minVelocityY: isNum,
179
+ // TODO: Bacon: remove `minVelocity`
180
+ minVelocity: isNum,
181
+ minVelocitySq: isNum,
182
+ activeOffsetXStart: isNum,
183
+ activeOffsetXEnd: isNum,
184
+ failOffsetXStart: isNum,
185
+ failOffsetXEnd: isNum,
186
+ activeOffsetYStart: isNum,
187
+ activeOffsetYEnd: isNum,
188
+ failOffsetYStart: isNum,
189
+ failOffsetYEnd: isNum,
190
+ hasCustomActivationCriteria: isBool,
191
+ minPointers: isNum,
192
+ maxPointers: isNum,
193
+ };
194
+ const keys = Object.keys(valid);
195
+
196
+ let invalidKeys = [];
197
+ for (const key of Object.keys(config)) {
198
+ if (keys.includes(key)) {
199
+ if (valid[key](config[key])) {
200
+ console.warn('Invalid type: ' + key + ': ' + config[key]);
201
+ }
202
+ } else {
203
+ invalidKeys.push(key);
204
+ }
205
+ }
206
+
207
+ if (invalidKeys.length) {
208
+ throw new Error('Invalid config props found: ' + invalidKeys.join(', '));
209
+ }
210
+ return config;
211
+ }
212
+
213
+ export default PanGestureHandler;
@@ -0,0 +1,24 @@
1
+ import Hammer from 'hammerjs';
2
+
3
+ import IndiscreteGestureHandler from './IndiscreteGestureHandler';
4
+
5
+ class PinchGestureHandler extends IndiscreteGestureHandler {
6
+ get name() {
7
+ return 'pinch';
8
+ }
9
+
10
+ get NativeGestureClass() {
11
+ return Hammer.Pinch;
12
+ }
13
+
14
+ transformNativeEvent({ scale, velocity, center }) {
15
+ return {
16
+ focalX: center.x,
17
+ focalY: center.y,
18
+ velocity,
19
+ scale,
20
+ };
21
+ }
22
+ }
23
+
24
+ export default PinchGestureHandler;
@@ -0,0 +1,147 @@
1
+ import Hammer from 'hammerjs';
2
+
3
+ import State from '../State';
4
+ import { CONTENT_TOUCHES_DELAY, CONTENT_TOUCHES_QUICK_TAP_END_DELAY } from './constants';
5
+ import DiscreteGestureHandler from './DiscreteGestureHandler';
6
+ import { fireAfterInterval, isnan } from './utils';
7
+
8
+ class PressGestureHandler extends DiscreteGestureHandler {
9
+ get name() {
10
+ return 'press';
11
+ }
12
+
13
+ get minDurationMs() {
14
+ return isnan(this.config.minDurationMs) ? 5 : this.config.minDurationMs;
15
+ }
16
+
17
+ get maxDist() {
18
+ return isnan(this.config.maxDist) ? 9 : this.config.maxDist;
19
+ }
20
+
21
+ get NativeGestureClass() {
22
+ return Hammer.Press;
23
+ }
24
+
25
+ shouldDelayTouches = true;
26
+
27
+ simulateCancelEvent(inputData) {
28
+ // Long press never starts so we can't rely on the running event boolean.
29
+ this.hasGestureFailed = true;
30
+ this.cancelEvent(inputData);
31
+ }
32
+
33
+ updateHasCustomActivationCriteria({ shouldCancelWhenOutside, maxDistSq }) {
34
+ return shouldCancelWhenOutside || !isnan(maxDistSq);
35
+ }
36
+
37
+ getState(type) {
38
+ return {
39
+ [Hammer.INPUT_START]: State.BEGAN,
40
+ [Hammer.INPUT_MOVE]: State.ACTIVE,
41
+ [Hammer.INPUT_END]: State.END,
42
+ [Hammer.INPUT_CANCEL]: State.CANCELLED,
43
+ }[type];
44
+ }
45
+
46
+ getConfig() {
47
+ if (!this._hasCustomActivationCriteria) {
48
+ // Default config
49
+ // If no params have been defined then this config should emulate the native gesture as closely as possible.
50
+ return {
51
+ shouldCancelWhenOutside: true,
52
+ maxDistSq: 10,
53
+ };
54
+ }
55
+ return this.config;
56
+ }
57
+
58
+ getHammerConfig() {
59
+ return {
60
+ ...super.getHammerConfig(),
61
+ // threshold: this.maxDist,
62
+ time: this.minDurationMs,
63
+ };
64
+ }
65
+
66
+ onGestureActivated(ev) {
67
+ this.onGestureStart(ev);
68
+ }
69
+
70
+ shouldDelayTouchForEvent({ pointerType }) {
71
+ // Don't disable event for mouse input
72
+ return this.shouldDelayTouches && pointerType === 'touch';
73
+ }
74
+
75
+ onGestureStart(ev) {
76
+ this.isGestureRunning = true;
77
+ clearTimeout(this.visualFeedbackTimer);
78
+ this.initialEvent = ev;
79
+ this.visualFeedbackTimer = fireAfterInterval(() => {
80
+ this.sendGestureStartedEvent(this.initialEvent);
81
+ this.initialEvent = null;
82
+ }, this.shouldDelayTouchForEvent(ev) && CONTENT_TOUCHES_DELAY);
83
+ }
84
+
85
+ sendGestureStartedEvent(ev) {
86
+ clearTimeout(this.visualFeedbackTimer);
87
+ this.visualFeedbackTimer = null;
88
+ this.sendEvent({
89
+ ...ev,
90
+ eventType: Hammer.INPUT_MOVE,
91
+ isFirst: true,
92
+ });
93
+ }
94
+
95
+ forceInvalidate(event) {
96
+ super.forceInvalidate(event);
97
+ clearTimeout(this.visualFeedbackTimer);
98
+ this.visualFeedbackTimer = null;
99
+ this.initialEvent = null;
100
+ }
101
+
102
+ onRawEvent(ev) {
103
+ super.onRawEvent(ev);
104
+ if (ev.isFinal && this.isGestureRunning) {
105
+ let timeout;
106
+ if (this.visualFeedbackTimer) {
107
+ // Aesthetic timing for a quick tap.
108
+ // We haven't activated the tap right away to emulate iOS `delaysContentTouches`
109
+ // Now we must send the initial activation event and wait a set amount of time before firing the end event.
110
+ timeout = CONTENT_TOUCHES_QUICK_TAP_END_DELAY;
111
+ this.sendGestureStartedEvent(this.initialEvent);
112
+ this.initialEvent = null;
113
+ }
114
+ fireAfterInterval(() => {
115
+ this.sendEvent({
116
+ ...ev,
117
+ eventType: Hammer.INPUT_END,
118
+ isFinal: true,
119
+ });
120
+ this.onGestureEnded();
121
+ }, timeout);
122
+ }
123
+ }
124
+
125
+ updateGestureConfig({
126
+ shouldActivateOnStart = false,
127
+ disallowInterruption = false,
128
+ shouldCancelWhenOutside = true,
129
+ minDurationMs = Number.NaN,
130
+ maxDist = Number.NaN,
131
+ minPointers = 1,
132
+ maxPointers = 1,
133
+ ...props
134
+ }) {
135
+ return super.updateGestureConfig({
136
+ shouldActivateOnStart,
137
+ disallowInterruption,
138
+ shouldCancelWhenOutside,
139
+ minDurationMs,
140
+ maxDist,
141
+ minPointers,
142
+ maxPointers,
143
+ ...props,
144
+ });
145
+ }
146
+ }
147
+ export default PressGestureHandler;
@@ -0,0 +1,24 @@
1
+ import Hammer from 'hammerjs';
2
+
3
+ import { DEG_RAD } from './constants';
4
+ import IndiscreteGestureHandler from './IndiscreteGestureHandler';
5
+
6
+ class RotationGestureHandler extends IndiscreteGestureHandler {
7
+ get name() {
8
+ return 'rotate';
9
+ }
10
+
11
+ get NativeGestureClass() {
12
+ return Hammer.Rotate;
13
+ }
14
+
15
+ transformNativeEvent({ rotation, velocity, center }) {
16
+ return {
17
+ rotation: (rotation - this.initialRotation) * DEG_RAD,
18
+ anchorX: center.x,
19
+ anchorY: center.y,
20
+ velocity,
21
+ };
22
+ }
23
+ }
24
+ export default RotationGestureHandler;
@@ -0,0 +1,160 @@
1
+ import Hammer from 'hammerjs';
2
+
3
+ import DiscreteGestureHandler from './DiscreteGestureHandler';
4
+ import { isnan } from './utils';
5
+
6
+ class TapGestureHandler extends DiscreteGestureHandler {
7
+ get name() {
8
+ return 'tap';
9
+ }
10
+
11
+ get NativeGestureClass() {
12
+ return Hammer.Tap;
13
+ }
14
+
15
+ get maxDelayMs() {
16
+ return isnan(this.config.maxDelayMs) ? 300 : this.config.maxDelayMs;
17
+ }
18
+
19
+ simulateCancelEvent(inputData) {
20
+ if (this.isGestureRunning) {
21
+ this.cancelEvent(inputData);
22
+ }
23
+ }
24
+
25
+ onGestureActivated(ev) {
26
+ if (this.isGestureRunning) {
27
+ this.onSuccessfulTap(ev);
28
+ }
29
+ }
30
+
31
+ onSuccessfulTap = ev => {
32
+ if (this._getPendingGestures().length) {
33
+ this._shouldFireEndEvent = ev;
34
+ return;
35
+ }
36
+ if (ev.eventType === Hammer.INPUT_END) {
37
+ this.sendEvent({ ...ev, eventType: Hammer.INPUT_MOVE });
38
+ }
39
+ // When handler gets activated it will turn into State.END immediately.
40
+ this.sendEvent({ ...ev, isFinal: true });
41
+ this.onGestureEnded(ev);
42
+ };
43
+
44
+ onRawEvent(ev) {
45
+ super.onRawEvent(ev);
46
+
47
+ // Attempt to create a touch-down event by checking if a valid tap hasn't started yet, then validating the input.
48
+ if (
49
+ !this.hasGestureFailed &&
50
+ !this.isGestureRunning &&
51
+ // Prevent multi-pointer events from misfiring.
52
+ !ev.isFinal
53
+ ) {
54
+ // Tap Gesture start event
55
+ const gesture = this.hammer.get(this.name);
56
+ if (gesture.options.enable(gesture, ev)) {
57
+ clearTimeout(this._multiTapTimer);
58
+
59
+ this.onStart(ev);
60
+ this.sendEvent(ev);
61
+ }
62
+ }
63
+ if (ev.isFinal && ev.maxPointers > 1) {
64
+ setTimeout(() => {
65
+ // Handle case where one finger presses slightly
66
+ // after the first finger on a multi-tap event
67
+ if (this.isGestureRunning) {
68
+ this.cancelEvent(ev);
69
+ }
70
+ });
71
+ }
72
+
73
+ if (this.hasGestureFailed) {
74
+ return;
75
+ }
76
+ // Hammer doesn't send a `cancel` event for taps.
77
+ // Manually fail the event.
78
+ if (ev.isFinal) {
79
+ // Handle case where one finger presses slightly
80
+ // after the first finger on a multi-tap event
81
+ if (ev.maxPointers > 1) {
82
+ setTimeout(() => {
83
+ if (this.isGestureRunning) {
84
+ this.cancelEvent(ev);
85
+ }
86
+ });
87
+ }
88
+
89
+ // Clear last timer
90
+ clearTimeout(this._timer);
91
+ // Create time out for multi-taps.
92
+ this._timer = setTimeout(() => {
93
+ this.hasGestureFailed = true;
94
+ this.cancelEvent(ev);
95
+ }, this.maxDelayMs);
96
+ } else if (!this.hasGestureFailed && !this.isGestureRunning) {
97
+ // Tap Gesture start event
98
+ const gesture = this.hammer.get(this.name);
99
+ if (gesture.options.enable(gesture, ev)) {
100
+ clearTimeout(this._multiTapTimer);
101
+
102
+ this.onStart(ev);
103
+ this.sendEvent(ev);
104
+ }
105
+ }
106
+ }
107
+
108
+ getHammerConfig() {
109
+ return {
110
+ ...super.getHammerConfig(),
111
+ event: this.name,
112
+ taps: isnan(this.config.numberOfTaps) ? 1 : this.config.numberOfTaps,
113
+ interval: this.maxDelayMs,
114
+ time:
115
+ isnan(this.config.maxDurationMs) || this.config.maxDurationMs == null
116
+ ? 250
117
+ : this.config.maxDurationMs,
118
+ };
119
+ }
120
+
121
+ updateGestureConfig({
122
+ shouldCancelWhenOutside = true,
123
+ maxDeltaX = Number.NaN,
124
+ maxDeltaY = Number.NaN,
125
+ numberOfTaps = 1,
126
+ minDurationMs = 525,
127
+ maxDelayMs = Number.NaN,
128
+ maxDurationMs = Number.NaN,
129
+ maxDist = 2,
130
+ minPointers = 1,
131
+ maxPointers = 1,
132
+ ...props
133
+ }) {
134
+ return super.updateGestureConfig({
135
+ shouldCancelWhenOutside,
136
+ numberOfTaps,
137
+ maxDeltaX,
138
+ maxDeltaY,
139
+ minDurationMs,
140
+ maxDelayMs,
141
+ maxDist,
142
+ minPointers,
143
+ maxPointers,
144
+ ...props,
145
+ });
146
+ }
147
+
148
+ onGestureEnded(...props) {
149
+ clearTimeout(this._timer);
150
+ super.onGestureEnded(...props);
151
+ }
152
+
153
+ onWaitingEnded(gesture) {
154
+ if (this._shouldFireEndEvent) {
155
+ this.onSuccessfulTap(this._shouldFireEndEvent);
156
+ this._shouldFireEndEvent = null;
157
+ }
158
+ }
159
+ }
160
+ export default TapGestureHandler;
@@ -0,0 +1,48 @@
1
+ import Hammer from 'hammerjs';
2
+
3
+ import State from '../State';
4
+
5
+ export const CONTENT_TOUCHES_DELAY = 240;
6
+ export const CONTENT_TOUCHES_QUICK_TAP_END_DELAY = 50;
7
+ export const MULTI_FINGER_PAN_MAX_PINCH_THRESHOLD = 0.1;
8
+ export const MULTI_FINGER_PAN_MAX_ROTATION_THRESHOLD = 7;
9
+ export const DEG_RAD = Math.PI / 180;
10
+
11
+ // Map Hammer values to RNGH
12
+ export const EventMap = {
13
+ [Hammer.INPUT_START]: State.BEGAN,
14
+ [Hammer.INPUT_MOVE]: State.ACTIVE,
15
+ [Hammer.INPUT_END]: State.END,
16
+ [Hammer.INPUT_CANCEL]: State.FAILED,
17
+ };
18
+
19
+ export const Direction = {
20
+ RIGHT: 1,
21
+ LEFT: 2,
22
+ UP: 4,
23
+ DOWN: 8,
24
+ };
25
+
26
+ export const DirectionMap = {
27
+ [Hammer.DIRECTION_RIGHT]: Direction.RIGHT,
28
+ [Hammer.DIRECTION_LEFT]: Direction.LEFT,
29
+ [Hammer.DIRECTION_UP]: Direction.UP,
30
+ [Hammer.DIRECTION_DOWN]: Direction.DOWN,
31
+ };
32
+
33
+ export const HammerInputNames = {
34
+ [Hammer.INPUT_START]: 'START',
35
+ [Hammer.INPUT_MOVE]: 'MOVE',
36
+ [Hammer.INPUT_END]: 'END',
37
+ [Hammer.INPUT_CANCEL]: 'CANCEL',
38
+ };
39
+ export const HammerDirectionNames = {
40
+ [Hammer.DIRECTION_HORIZONTAL]: 'HORIZONTAL',
41
+ [Hammer.DIRECTION_UP]: 'UP',
42
+ [Hammer.DIRECTION_DOWN]: 'DOWN',
43
+ [Hammer.DIRECTION_VERTICAL]: 'VERTICAL',
44
+ [Hammer.DIRECTION_NONE]: 'NONE',
45
+ [Hammer.DIRECTION_ALL]: 'ALL',
46
+ [Hammer.DIRECTION_RIGHT]: 'RIGHT',
47
+ [Hammer.DIRECTION_LEFT]: 'LEFT',
48
+ };
package/web/utils.js ADDED
@@ -0,0 +1,14 @@
1
+ export const isnan = v => Number.isNaN(v);
2
+ export const TEST_MIN_IF_NOT_NAN = (value, limit) =>
3
+ !isnan(limit) && ((limit < 0 && value <= limit) || (limit >= 0 && value >= limit));
4
+ export const VEC_LEN_SQ = ({ x = 0, y = 0 } = {}) => x * x + y * y;
5
+ export const TEST_MAX_IF_NOT_NAN = (value, max) =>
6
+ !isnan(max) && ((max < 0 && value < max) || (max >= 0 && value > max));
7
+
8
+ export function fireAfterInterval(method, interval) {
9
+ if (!interval) {
10
+ method();
11
+ return null;
12
+ }
13
+ return setTimeout(() => method(), interval);
14
+ }
package/Directions.web.js DELETED
@@ -1,6 +0,0 @@
1
- export default {
2
- RIGHT: 1,
3
- LEFT: 2,
4
- UP: 4,
5
- DOWN: 8,
6
- };
package/Swipeable.web.js DELETED
@@ -1,4 +0,0 @@
1
- export default function Swipeable({ children }) {
2
- console.warn('Swipeable is not yet supported on web.');
3
- return children;
4
- }