1 | "use strict";
|
2 |
|
3 | var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
4 |
|
5 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
6 |
|
7 | Object.defineProperty(exports, "__esModule", {
|
8 | value: true
|
9 | });
|
10 | exports.default = useTouchMove;
|
11 |
|
12 | var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
13 |
|
14 | var React = _interopRequireWildcard(require("react"));
|
15 |
|
16 | var MIN_SWIPE_DISTANCE = 0.1;
|
17 | var STOP_SWIPE_DISTANCE = 0.01;
|
18 | var REFRESH_INTERVAL = 20;
|
19 | var SPEED_OFF_MULTIPLE = Math.pow(0.995, REFRESH_INTERVAL);
|
20 |
|
21 | function useTouchMove(ref, onOffset) {
|
22 | var _useState = (0, React.useState)(),
|
23 | _useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
24 | touchPosition = _useState2[0],
|
25 | setTouchPosition = _useState2[1];
|
26 |
|
27 | var _useState3 = (0, React.useState)(0),
|
28 | _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
29 | lastTimestamp = _useState4[0],
|
30 | setLastTimestamp = _useState4[1];
|
31 |
|
32 | var _useState5 = (0, React.useState)(0),
|
33 | _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
|
34 | lastTimeDiff = _useState6[0],
|
35 | setLastTimeDiff = _useState6[1];
|
36 |
|
37 | var _useState7 = (0, React.useState)(),
|
38 | _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
|
39 | lastOffset = _useState8[0],
|
40 | setLastOffset = _useState8[1];
|
41 |
|
42 | var motionRef = (0, React.useRef)();
|
43 |
|
44 |
|
45 | function onTouchStart(e) {
|
46 | var _e$touches$ = e.touches[0],
|
47 | screenX = _e$touches$.screenX,
|
48 | screenY = _e$touches$.screenY;
|
49 | setTouchPosition({
|
50 | x: screenX,
|
51 | y: screenY
|
52 | });
|
53 | window.clearInterval(motionRef.current);
|
54 | }
|
55 |
|
56 | function onTouchMove(e) {
|
57 | if (!touchPosition) return;
|
58 | e.preventDefault();
|
59 | var _e$touches$2 = e.touches[0],
|
60 | screenX = _e$touches$2.screenX,
|
61 | screenY = _e$touches$2.screenY;
|
62 | setTouchPosition({
|
63 | x: screenX,
|
64 | y: screenY
|
65 | });
|
66 | var offsetX = screenX - touchPosition.x;
|
67 | var offsetY = screenY - touchPosition.y;
|
68 | onOffset(offsetX, offsetY);
|
69 | var now = Date.now();
|
70 | setLastTimestamp(now);
|
71 | setLastTimeDiff(now - lastTimestamp);
|
72 | setLastOffset({
|
73 | x: offsetX,
|
74 | y: offsetY
|
75 | });
|
76 | }
|
77 |
|
78 | function onTouchEnd() {
|
79 | if (!touchPosition) return;
|
80 | setTouchPosition(null);
|
81 | setLastOffset(null);
|
82 |
|
83 | if (lastOffset) {
|
84 | var distanceX = lastOffset.x / lastTimeDiff;
|
85 | var distanceY = lastOffset.y / lastTimeDiff;
|
86 | var absX = Math.abs(distanceX);
|
87 | var absY = Math.abs(distanceY);
|
88 |
|
89 | if (Math.max(absX, absY) < MIN_SWIPE_DISTANCE) return;
|
90 | var currentX = distanceX;
|
91 | var currentY = distanceY;
|
92 | motionRef.current = window.setInterval(function () {
|
93 | if (Math.abs(currentX) < STOP_SWIPE_DISTANCE && Math.abs(currentY) < STOP_SWIPE_DISTANCE) {
|
94 | window.clearInterval(motionRef.current);
|
95 | return;
|
96 | }
|
97 |
|
98 | currentX *= SPEED_OFF_MULTIPLE;
|
99 | currentY *= SPEED_OFF_MULTIPLE;
|
100 | onOffset(currentX * REFRESH_INTERVAL, currentY * REFRESH_INTERVAL);
|
101 | }, REFRESH_INTERVAL);
|
102 | }
|
103 | }
|
104 |
|
105 |
|
106 | var lastWheelDirectionRef = (0, React.useRef)();
|
107 |
|
108 | function onWheel(e) {
|
109 | var deltaX = e.deltaX,
|
110 | deltaY = e.deltaY;
|
111 |
|
112 | var mixed = 0;
|
113 | var absX = Math.abs(deltaX);
|
114 | var absY = Math.abs(deltaY);
|
115 |
|
116 | if (absX === absY) {
|
117 | mixed = lastWheelDirectionRef.current === 'x' ? deltaX : deltaY;
|
118 | } else if (absX > absY) {
|
119 | mixed = deltaX;
|
120 | lastWheelDirectionRef.current = 'x';
|
121 | } else {
|
122 | mixed = deltaY;
|
123 | lastWheelDirectionRef.current = 'y';
|
124 | }
|
125 |
|
126 | if (onOffset(-mixed, -mixed)) {
|
127 | e.preventDefault();
|
128 | }
|
129 | }
|
130 |
|
131 |
|
132 | var touchEventsRef = (0, React.useRef)(null);
|
133 | touchEventsRef.current = {
|
134 | onTouchStart: onTouchStart,
|
135 | onTouchMove: onTouchMove,
|
136 | onTouchEnd: onTouchEnd,
|
137 | onWheel: onWheel
|
138 | };
|
139 | React.useEffect(function () {
|
140 | function onProxyTouchStart(e) {
|
141 | touchEventsRef.current.onTouchStart(e);
|
142 | }
|
143 |
|
144 | function onProxyTouchMove(e) {
|
145 | touchEventsRef.current.onTouchMove(e);
|
146 | }
|
147 |
|
148 | function onProxyTouchEnd(e) {
|
149 | touchEventsRef.current.onTouchEnd(e);
|
150 | }
|
151 |
|
152 | function onProxyWheel(e) {
|
153 | touchEventsRef.current.onWheel(e);
|
154 | }
|
155 |
|
156 | document.addEventListener('touchmove', onProxyTouchMove, {
|
157 | passive: false
|
158 | });
|
159 | document.addEventListener('touchend', onProxyTouchEnd, {
|
160 | passive: false
|
161 | });
|
162 |
|
163 | ref.current.addEventListener('touchstart', onProxyTouchStart, {
|
164 | passive: false
|
165 | });
|
166 | ref.current.addEventListener('wheel', onProxyWheel);
|
167 | return function () {
|
168 | document.removeEventListener('touchmove', onProxyTouchMove);
|
169 | document.removeEventListener('touchend', onProxyTouchEnd);
|
170 | };
|
171 | }, []);
|
172 | } |
\ | No newline at end of file |