1
- import { closest , distance } from 'shared/utils' ;
1
+ import { closest , distance as euclideanDistance , touchCoords } from 'shared/utils' ;
2
2
import Sensor from '../Sensor' ;
3
3
import { DragStartSensorEvent , DragMoveSensorEvent , DragStopSensorEvent } from '../SensorEvent' ;
4
4
@@ -52,7 +52,7 @@ export default class TouchSensor extends Sensor {
52
52
this . currentScrollableParent = null ;
53
53
54
54
/**
55
- * TimeoutID for long touch
55
+ * TimeoutID for managing delay
56
56
* @property tapTimeout
57
57
* @type {Number }
58
58
*/
@@ -97,27 +97,26 @@ export default class TouchSensor extends Sensor {
97
97
if ( ! container ) {
98
98
return ;
99
99
}
100
+ const { distance = 0 , delay = 0 } = this . options ;
101
+ const { pageX, pageY} = touchCoords ( event ) ;
100
102
103
+ Object . assign ( this , { pageX, pageY} ) ;
104
+ this . onTouchStartAt = Date . now ( ) ;
101
105
this . startEvent = event ;
106
+ this . currentContainer = container ;
102
107
103
- document . addEventListener ( 'touchmove' , this [ onTouchMove ] ) ;
104
108
document . addEventListener ( 'touchend' , this [ onTouchEnd ] ) ;
105
109
document . addEventListener ( 'touchcancel' , this [ onTouchEnd ] ) ;
106
110
document . addEventListener ( 'touchmove' , this [ onDistanceChange ] ) ;
107
111
container . addEventListener ( 'contextmenu' , onContextMenu ) ;
108
112
109
- if ( this . options . distance ) {
113
+ if ( distance ) {
110
114
preventScrolling = true ;
111
115
}
112
116
113
- this . currentContainer = container ;
114
- this . tapTimeout = setTimeout ( ( ) => {
115
- this . delayOver = true ;
116
- if ( this . touchMoved || this . distance < this . options . distance ) {
117
- return ;
118
- }
119
- this [ startDrag ] ( ) ;
120
- } , this . options . delay ) ;
117
+ this . tapTimeout = window . setTimeout ( ( ) => {
118
+ this [ onDistanceChange ] ( { touches : [ { pageX : this . pageX , pageY : this . pageY } ] } ) ;
119
+ } , delay ) ;
121
120
}
122
121
123
122
/**
@@ -127,7 +126,7 @@ export default class TouchSensor extends Sensor {
127
126
[ startDrag ] ( ) {
128
127
const startEvent = this . startEvent ;
129
128
const container = this . currentContainer ;
130
- const touch = startEvent . touches [ 0 ] || startEvent . changedTouches [ 0 ] ;
129
+ const touch = touchCoords ( startEvent ) ;
131
130
132
131
const dragStartEvent = new DragStartSensorEvent ( {
133
132
clientX : touch . pageX ,
@@ -140,47 +139,49 @@ export default class TouchSensor extends Sensor {
140
139
this . trigger ( this . currentContainer , dragStartEvent ) ;
141
140
142
141
this . dragging = ! dragStartEvent . canceled ( ) ;
142
+
143
+ if ( this . dragging ) {
144
+ document . addEventListener ( 'touchmove' , this [ onTouchMove ] ) ;
145
+ }
143
146
preventScrolling = this . dragging ;
144
147
}
145
148
146
149
/**
147
- * Detect change in distance
150
+ * Touch move handler prior to drag start.
148
151
* @private
149
152
* @param {Event } event - Touch move event
150
153
*/
151
154
[ onDistanceChange ] ( event ) {
152
- if ( this . dragging || ! this . options . distance ) {
153
- return ;
154
- }
155
-
156
- const tap = this . startEvent . touches [ 0 ] || this . startEvent . changedTouches [ 0 ] ;
157
- const touch = event . touches [ 0 ] || event . changedTouches [ 0 ] ;
158
-
159
- this . distance = distance ( tap . pageX , tap . pageY , touch . pageX , touch . pageY ) ;
160
-
161
- if ( this . delayOver && this . distance >= this . options . distance ) {
155
+ const { delay, distance} = this . options ;
156
+ const { startEvent} = this ;
157
+ const start = touchCoords ( startEvent ) ;
158
+ const current = touchCoords ( event ) ;
159
+ const timeElapsed = Date . now ( ) - this . onTouchStartAt ;
160
+ const distanceTravelled = euclideanDistance ( start . pageX , start . pageY , current . pageX , current . pageY ) ;
161
+
162
+ Object . assign ( this , current ) ;
163
+ if ( timeElapsed >= delay && distanceTravelled >= distance ) {
164
+ window . clearTimeout ( this . tapTimeout ) ;
165
+ document . removeEventListener ( 'touchmove' , this [ onDistanceChange ] ) ;
162
166
this [ startDrag ] ( ) ;
163
167
}
164
168
}
165
169
166
170
/**
167
- * Touch move handler
171
+ * Mouse move handler while dragging
168
172
* @private
169
173
* @param {Event } event - Touch move event
170
174
*/
171
175
[ onTouchMove ] ( event ) {
172
- this . touchMoved = true ;
173
-
174
176
if ( ! this . dragging ) {
175
177
return ;
176
178
}
177
-
178
- const touch = event . touches [ 0 ] || event . changedTouches [ 0 ] ;
179
- const target = document . elementFromPoint ( touch . pageX - window . scrollX , touch . pageY - window . scrollY ) ;
179
+ const { pageX, pageY} = touchCoords ( event ) ;
180
+ const target = document . elementFromPoint ( pageX - window . scrollX , pageY - window . scrollY ) ;
180
181
181
182
const dragMoveEvent = new DragMoveSensorEvent ( {
182
- clientX : touch . pageX ,
183
- clientY : touch . pageY ,
183
+ clientX : pageX ,
184
+ clientY : pageY ,
184
185
target,
185
186
container : this . currentContainer ,
186
187
originalEvent : event ,
@@ -195,32 +196,31 @@ export default class TouchSensor extends Sensor {
195
196
* @param {Event } event - Touch end event
196
197
*/
197
198
[ onTouchEnd ] ( event ) {
198
- this . touchMoved = false ;
199
+ clearTimeout ( this . tapTimeout ) ;
199
200
preventScrolling = false ;
200
201
201
202
document . removeEventListener ( 'touchend' , this [ onTouchEnd ] ) ;
202
203
document . removeEventListener ( 'touchcancel' , this [ onTouchEnd ] ) ;
203
- document . removeEventListener ( 'touchmove' , this [ onTouchMove ] ) ;
204
204
document . removeEventListener ( 'touchmove' , this [ onDistanceChange ] ) ;
205
205
206
206
if ( this . currentContainer ) {
207
207
this . currentContainer . removeEventListener ( 'contextmenu' , onContextMenu ) ;
208
208
}
209
209
210
- clearTimeout ( this . tapTimeout ) ;
211
-
212
210
if ( ! this . dragging ) {
213
211
return ;
214
212
}
215
213
216
- const touch = event . touches [ 0 ] || event . changedTouches [ 0 ] ;
217
- const target = document . elementFromPoint ( touch . pageX - window . scrollX , touch . pageY - window . scrollY ) ;
214
+ document . removeEventListener ( 'touchmove' , this [ onTouchMove ] ) ;
215
+
216
+ const { pageX, pageY} = touchCoords ( event ) ;
217
+ const target = document . elementFromPoint ( pageX - window . scrollX , pageY - window . scrollY ) ;
218
218
219
219
event . preventDefault ( ) ;
220
220
221
221
const dragStopEvent = new DragStopSensorEvent ( {
222
- clientX : touch . pageX ,
223
- clientY : touch . pageY ,
222
+ clientX : pageX ,
223
+ clientY : pageY ,
224
224
target,
225
225
container : this . currentContainer ,
226
226
originalEvent : event ,
@@ -230,8 +230,6 @@ export default class TouchSensor extends Sensor {
230
230
231
231
this . currentContainer = null ;
232
232
this . dragging = false ;
233
- this . distance = 0 ;
234
- this . delayOver = false ;
235
233
this . startEvent = null ;
236
234
}
237
235
}
0 commit comments