Skip to content

Commit b5b37a5

Browse files
committed
fix multitouch detection for pointer events, prevents an issue where zoom gestures incorrectly triggered a slide change
1 parent 52c6c8b commit b5b37a5

1 file changed

Lines changed: 43 additions & 18 deletions

File tree

js/controllers/touch.js

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ export default class Touch {
1818
this.touchStartY = 0;
1919
this.touchStartCount = 0;
2020
this.touchCaptured = false;
21+
this.activePointers = new Map();
2122

2223
this.onPointerDown = this.onPointerDown.bind( this );
2324
this.onPointerMove = this.onPointerMove.bind( this );
2425
this.onPointerUp = this.onPointerUp.bind( this );
26+
this.onPointerCancel = this.onPointerCancel.bind( this );
2527
this.onTouchStart = this.onTouchStart.bind( this );
2628
this.onTouchMove = this.onTouchMove.bind( this );
2729
this.onTouchEnd = this.onTouchEnd.bind( this );
@@ -36,19 +38,13 @@ export default class Touch {
3638
let revealElement = this.Reveal.getRevealElement();
3739

3840
if( 'onpointerdown' in window ) {
39-
// Use W3C pointer events
4041
revealElement.addEventListener( 'pointerdown', this.onPointerDown, false );
4142
revealElement.addEventListener( 'pointermove', this.onPointerMove, false );
4243
revealElement.addEventListener( 'pointerup', this.onPointerUp, false );
44+
revealElement.addEventListener( 'pointercancel', this.onPointerCancel, false );
4345
}
44-
else if( window.navigator.msPointerEnabled ) {
45-
// IE 10 uses prefixed version of pointer events
46-
revealElement.addEventListener( 'MSPointerDown', this.onPointerDown, false );
47-
revealElement.addEventListener( 'MSPointerMove', this.onPointerMove, false );
48-
revealElement.addEventListener( 'MSPointerUp', this.onPointerUp, false );
49-
}
46+
// Fall back to touch events
5047
else {
51-
// Fall back to touch events
5248
revealElement.addEventListener( 'touchstart', this.onTouchStart, false );
5349
revealElement.addEventListener( 'touchmove', this.onTouchMove, false );
5450
revealElement.addEventListener( 'touchend', this.onTouchEnd, false );
@@ -66,10 +62,7 @@ export default class Touch {
6662
revealElement.removeEventListener( 'pointerdown', this.onPointerDown, false );
6763
revealElement.removeEventListener( 'pointermove', this.onPointerMove, false );
6864
revealElement.removeEventListener( 'pointerup', this.onPointerUp, false );
69-
70-
revealElement.removeEventListener( 'MSPointerDown', this.onPointerDown, false );
71-
revealElement.removeEventListener( 'MSPointerMove', this.onPointerMove, false );
72-
revealElement.removeEventListener( 'MSPointerUp', this.onPointerUp, false );
65+
revealElement.removeEventListener( 'pointercancel', this.onPointerCancel, false );
7366

7467
revealElement.removeEventListener( 'touchstart', this.onTouchStart, false );
7568
revealElement.removeEventListener( 'touchmove', this.onTouchMove, false );
@@ -228,15 +221,30 @@ export default class Touch {
228221

229222
}
230223

224+
/**
225+
* Returns all active touch pointers in touch-like format.
226+
*
227+
* @return {Array}
228+
*/
229+
getActiveTouches() {
230+
231+
return Array.from( this.activePointers.values(), pointer => ({
232+
clientX: pointer.clientX,
233+
clientY: pointer.clientY
234+
}) );
235+
236+
}
237+
231238
/**
232239
* Convert pointer down to touch start.
233240
*
234241
* @param {object} event
235242
*/
236243
onPointerDown( event ) {
237244

238-
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
239-
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
245+
if( event.pointerType === "touch" ) {
246+
this.activePointers.set( event.pointerId, event );
247+
event.touches = this.getActiveTouches();
240248
this.onTouchStart( event );
241249
}
242250

@@ -249,8 +257,9 @@ export default class Touch {
249257
*/
250258
onPointerMove( event ) {
251259

252-
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
253-
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
260+
if( event.pointerType === "touch" ) {
261+
this.activePointers.set( event.pointerId, event );
262+
event.touches = this.getActiveTouches();
254263
this.onTouchMove( event );
255264
}
256265

@@ -263,8 +272,24 @@ export default class Touch {
263272
*/
264273
onPointerUp( event ) {
265274

266-
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
267-
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
275+
if( event.pointerType === "touch" ) {
276+
this.activePointers.delete( event.pointerId );
277+
event.touches = this.getActiveTouches();
278+
this.onTouchEnd( event );
279+
}
280+
281+
}
282+
283+
/**
284+
* Convert pointer cancel to touch end.
285+
*
286+
* @param {object} event
287+
*/
288+
onPointerCancel( event ) {
289+
290+
if( event.pointerType === "touch" ) {
291+
this.activePointers.delete( event.pointerId );
292+
event.touches = this.getActiveTouches();
268293
this.onTouchEnd( event );
269294
}
270295

0 commit comments

Comments
 (0)