@@ -62,6 +62,7 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
62
62
this . contextMenuOpen = false ;
63
63
this . mouseScrollTimeStamp = 0 ;
64
64
this . mouseScrollDelta = 0 ;
65
+ this . touchSwipeState = null ;
65
66
66
67
if ( contextMenuItems ) {
67
68
contextMenuItems . contextFirstPage . addEventListener ( 'click' ,
@@ -135,10 +136,6 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
135
136
136
137
var MOUSE_SCROLL_COOLDOWN_TIME = 50 ;
137
138
var PAGE_SWITCH_THRESHOLD = 0.1 ;
138
- var PageSwitchDirection = {
139
- UP : - 1 ,
140
- DOWN : 1
141
- } ;
142
139
143
140
var currentTime = ( new Date ( ) ) . getTime ( ) ;
144
141
var storedTime = this . mouseScrollTimeStamp ;
@@ -156,19 +153,13 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
156
153
this . mouseScrollDelta += delta ;
157
154
158
155
if ( Math . abs ( this . mouseScrollDelta ) >= PAGE_SWITCH_THRESHOLD ) {
159
- var pageSwitchDirection = ( this . mouseScrollDelta > 0 ) ?
160
- PageSwitchDirection . UP : PageSwitchDirection . DOWN ;
161
- var page = this . pdfViewer . currentPageNumber ;
156
+ var totalDelta = this . mouseScrollDelta ;
162
157
this . _resetMouseScrollState ( ) ;
163
-
164
- // If we're at the first/last page, we don't need to do anything.
165
- if ( ( page === 1 && pageSwitchDirection === PageSwitchDirection . UP ) ||
166
- ( page === this . pdfViewer . pagesCount &&
167
- pageSwitchDirection === PageSwitchDirection . DOWN ) ) {
168
- return ;
158
+ var success = totalDelta > 0 ? this . _goToPreviousPage ( )
159
+ : this . _goToNextPage ( ) ;
160
+ if ( success ) {
161
+ this . mouseScrollTimeStamp = currentTime ;
169
162
}
170
- this . pdfViewer . currentPageNumber = ( page + pageSwitchDirection ) ;
171
- this . mouseScrollTimeStamp = currentTime ;
172
163
}
173
164
} ,
174
165
@@ -179,6 +170,32 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
179
170
document . msFullscreenElement ) ;
180
171
} ,
181
172
173
+ /**
174
+ * @private
175
+ */
176
+ _goToPreviousPage : function PDFPresentationMode_goToPreviousPage ( ) {
177
+ var page = this . pdfViewer . currentPageNumber ;
178
+ // If we're at the first page, we don't need to do anything.
179
+ if ( page <= 1 ) {
180
+ return false ;
181
+ }
182
+ this . pdfViewer . currentPageNumber = ( page - 1 ) ;
183
+ return true ;
184
+ } ,
185
+
186
+ /**
187
+ * @private
188
+ */
189
+ _goToNextPage : function PDFPresentationMode_goToNextPage ( ) {
190
+ var page = this . pdfViewer . currentPageNumber ;
191
+ // If we're at the last page, we don't need to do anything.
192
+ if ( page >= this . pdfViewer . pagesCount ) {
193
+ return false ;
194
+ }
195
+ this . pdfViewer . currentPageNumber = ( page + 1 ) ;
196
+ return true ;
197
+ } ,
198
+
182
199
/**
183
200
* @private
184
201
*/
@@ -339,6 +356,72 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
339
356
this . mouseScrollDelta = 0 ;
340
357
} ,
341
358
359
+ /**
360
+ * @private
361
+ */
362
+ _touchSwipe : function PDFPresentationMode_touchSwipe ( evt ) {
363
+ if ( ! this . active ) {
364
+ return ;
365
+ }
366
+
367
+ // Must move at least these many CSS pixels for it to count as a swipe
368
+ var SWIPE_MIN_DISTANCE_THRESHOLD = 50 ;
369
+ // The swipe angle is allowed to deviate from the x or y axis by this much
370
+ // before it is not considered a swipe in that direction any more.
371
+ var SWIPE_ANGLE_THRESHOLD = Math . PI / 6 ;
372
+
373
+ if ( evt . touches . length > 1 ) {
374
+ // Multiple touch points detected, cancel the swipe.
375
+ this . touchSwipeState = null ;
376
+ return ;
377
+ }
378
+ switch ( evt . type ) {
379
+ case 'touchstart' :
380
+ this . touchSwipeState = {
381
+ startX : evt . touches [ 0 ] . pageX ,
382
+ startY : evt . touches [ 0 ] . pageY ,
383
+ endX : evt . touches [ 0 ] . pageX ,
384
+ endY : evt . touches [ 0 ] . pageY
385
+ } ;
386
+ break ;
387
+ case 'touchmove' :
388
+ if ( this . touchSwipeState === null ) {
389
+ return ;
390
+ }
391
+ this . touchSwipeState . endX = evt . touches [ 0 ] . pageX ;
392
+ this . touchSwipeState . endY = evt . touches [ 0 ] . pageY ;
393
+ // Do a preventDefault to avoid the swipe from triggering browser
394
+ // gestures (Chrome in particular has some sort of swipe gesture in
395
+ // fullscreen mode).
396
+ evt . preventDefault ( ) ;
397
+ break ;
398
+ case 'touchend' :
399
+ if ( this . touchSwipeState === null ) {
400
+ return ;
401
+ }
402
+ var delta = 0 ;
403
+ var dx = this . touchSwipeState . endX - this . touchSwipeState . startX ;
404
+ var dy = this . touchSwipeState . endY - this . touchSwipeState . startY ;
405
+ var absAngle = Math . abs ( Math . atan2 ( dy , dx ) ) ;
406
+ if ( Math . abs ( dx ) > SWIPE_MIN_DISTANCE_THRESHOLD &&
407
+ ( absAngle <= SWIPE_ANGLE_THRESHOLD ||
408
+ absAngle >= ( Math . PI - SWIPE_ANGLE_THRESHOLD ) ) ) {
409
+ // horizontal swipe
410
+ delta = dx ;
411
+ } else if ( Math . abs ( dy ) > SWIPE_MIN_DISTANCE_THRESHOLD &&
412
+ Math . abs ( absAngle - ( Math . PI / 2 ) ) <= SWIPE_ANGLE_THRESHOLD ) {
413
+ // vertical swipe
414
+ delta = dy ;
415
+ }
416
+ if ( delta > 0 ) {
417
+ this . _goToPreviousPage ( ) ;
418
+ } else if ( delta < 0 ) {
419
+ this . _goToNextPage ( ) ;
420
+ }
421
+ break ;
422
+ }
423
+ } ,
424
+
342
425
/**
343
426
* @private
344
427
*/
@@ -348,12 +431,16 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
348
431
this . mouseWheelBind = this . _mouseWheel . bind ( this ) ;
349
432
this . resetMouseScrollStateBind = this . _resetMouseScrollState . bind ( this ) ;
350
433
this . contextMenuBind = this . _contextMenu . bind ( this ) ;
434
+ this . touchSwipeBind = this . _touchSwipe . bind ( this ) ;
351
435
352
436
window . addEventListener ( 'mousemove' , this . showControlsBind ) ;
353
437
window . addEventListener ( 'mousedown' , this . mouseDownBind ) ;
354
438
window . addEventListener ( 'wheel' , this . mouseWheelBind ) ;
355
439
window . addEventListener ( 'keydown' , this . resetMouseScrollStateBind ) ;
356
440
window . addEventListener ( 'contextmenu' , this . contextMenuBind ) ;
441
+ window . addEventListener ( 'touchstart' , this . touchSwipeBind ) ;
442
+ window . addEventListener ( 'touchmove' , this . touchSwipeBind ) ;
443
+ window . addEventListener ( 'touchend' , this . touchSwipeBind ) ;
357
444
} ,
358
445
359
446
/**
@@ -366,12 +453,16 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() {
366
453
window . removeEventListener ( 'wheel' , this . mouseWheelBind ) ;
367
454
window . removeEventListener ( 'keydown' , this . resetMouseScrollStateBind ) ;
368
455
window . removeEventListener ( 'contextmenu' , this . contextMenuBind ) ;
456
+ window . removeEventListener ( 'touchstart' , this . touchSwipeBind ) ;
457
+ window . removeEventListener ( 'touchmove' , this . touchSwipeBind ) ;
458
+ window . removeEventListener ( 'touchend' , this . touchSwipeBind ) ;
369
459
370
460
delete this . showControlsBind ;
371
461
delete this . mouseDownBind ;
372
462
delete this . mouseWheelBind ;
373
463
delete this . resetMouseScrollStateBind ;
374
464
delete this . contextMenuBind ;
465
+ delete this . touchSwipeBind ;
375
466
} ,
376
467
377
468
/**
0 commit comments