Просмотр исходного кода

break touch interaction into own module

Hakim El Hattab 5 лет назад
Родитель
Сommit
5a5a5c9a6c
6 измененных файлов с 278 добавлено и 235 удалено
  1. 1 1
      dist/reveal.min.js
  2. 1 0
      gulpfile.js
  3. 1 3
      js/controllers/location.js
  4. 1 3
      js/controllers/slidenumber.js
  5. 255 0
      js/controllers/touch.js
  6. 19 228
      js/reveal.js

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/reveal.min.js


+ 1 - 0
gulpfile.js

@@ -87,6 +87,7 @@ gulp.task('serve', () => {
     connect.server({
     connect.server({
         root: root,
         root: root,
         port: port,
         port: port,
+        host: '0.0.0.0',
         livereload: true
         livereload: true
     })
     })
 
 

+ 1 - 3
js/controllers/location.js

@@ -1,7 +1,5 @@
-import { enterFullscreen } from '../utils/util.js'
-
 /**
 /**
- * Handles all reveal.js keyboard interactions.
+ * Reads and writes the URL based on reveal.js' current state.
  */
  */
 export default class Location {
 export default class Location {
 
 

+ 1 - 3
js/controllers/slidenumber.js

@@ -1,7 +1,5 @@
-import { enterFullscreen } from '../utils/util.js'
-
 /**
 /**
- * Handles all reveal.js keyboard interactions.
+ * Handles the display of reveal.js' optional slide number.
  */
  */
 export default class SlideNumber {
 export default class SlideNumber {
 
 

+ 255 - 0
js/controllers/touch.js

@@ -0,0 +1,255 @@
+const SWIPE_THRESHOLD = 40;
+
+/**
+ * Controls all touch interactions and navigations for
+ * a presentation.
+ */
+export default class Touch {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// Holds information about the currently ongoing touch interaction
+		this.touchStartX = 0;
+		this.touchStartY = 0;
+		this.touchStartCount = 0;
+		this.touchCaptured = false;
+
+		this.onPointerDown = this.onPointerDown.bind( this );
+		this.onPointerMove = this.onPointerMove.bind( this );
+		this.onPointerUp = this.onPointerUp.bind( this );
+		this.onTouchStart = this.onTouchStart.bind( this );
+		this.onTouchMove = this.onTouchMove.bind( this );
+		this.onTouchEnd = this.onTouchEnd.bind( this );
+
+	}
+
+	/**
+	 *
+	 */
+	bind() {
+
+		var revealElement = this.Reveal.getRevealElement();
+
+		if( 'onpointerdown' in window ) {
+			// Use W3C pointer events
+			revealElement.addEventListener( 'pointerdown', this.onPointerDown, false );
+			revealElement.addEventListener( 'pointermove', this.onPointerMove, false );
+			revealElement.addEventListener( 'pointerup', this.onPointerUp, false );
+		}
+		else if( window.navigator.msPointerEnabled ) {
+			// IE 10 uses prefixed version of pointer events
+			revealElement.addEventListener( 'MSPointerDown', this.onPointerDown, false );
+			revealElement.addEventListener( 'MSPointerMove', this.onPointerMove, false );
+			revealElement.addEventListener( 'MSPointerUp', this.onPointerUp, false );
+		}
+		else {
+			// Fall back to touch events
+			revealElement.addEventListener( 'touchstart', this.onTouchStart, false );
+			revealElement.addEventListener( 'touchmove', this.onTouchMove, false );
+			revealElement.addEventListener( 'touchend', this.onTouchEnd, false );
+		}
+
+	}
+
+	/**
+	 *
+	 */
+	unbind() {
+
+		var revealElement = this.Reveal.getRevealElement();
+
+		revealElement.removeEventListener( 'pointerdown', this.onPointerDown, false );
+		revealElement.removeEventListener( 'pointermove', this.onPointerMove, false );
+		revealElement.removeEventListener( 'pointerup', this.onPointerUp, false );
+
+		revealElement.removeEventListener( 'MSPointerDown', this.onPointerDown, false );
+		revealElement.removeEventListener( 'MSPointerMove', this.onPointerMove, false );
+		revealElement.removeEventListener( 'MSPointerUp', this.onPointerUp, false );
+
+		revealElement.removeEventListener( 'touchstart', this.onTouchStart, false );
+		revealElement.removeEventListener( 'touchmove', this.onTouchMove, false );
+		revealElement.removeEventListener( 'touchend', this.onTouchEnd, false );
+
+	}
+
+	/**
+	 * Checks if the target element prevents the triggering of
+	 * swipe navigation.
+	 */
+	isSwipePrevented( target ) {
+
+		while( target && typeof target.hasAttribute === 'function' ) {
+			if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
+			target = target.parentNode;
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Handler for the 'touchstart' event, enables support for
+	 * swipe and pinch gestures.
+	 *
+	 * @param {object} event
+	 */
+	onTouchStart( event ) {
+
+		if( this.isSwipePrevented( event.target ) ) return true;
+
+		this.touchStartX = event.touches[0].clientX;
+		this.touchStartY = event.touches[0].clientY;
+		this.touchStartCount = event.touches.length;
+
+	}
+
+	/**
+	 * Handler for the 'touchmove' event.
+	 *
+	 * @param {object} event
+	 */
+	onTouchMove( event ) {
+
+		if( this.isSwipePrevented( event.target ) ) return true;
+
+		let config = this.Reveal.getConfig();
+
+		// Each touch should only trigger one action
+		if( !this.touchCaptured ) {
+			this.Reveal.onUserInput( event );
+
+			let currentX = event.touches[0].clientX;
+			let currentY = event.touches[0].clientY;
+
+			// There was only one touch point, look for a swipe
+			if( event.touches.length === 1 && this.touchStartCount !== 2 ) {
+
+				let deltaX = currentX - this.touchStartX,
+					deltaY = currentY - this.touchStartY;
+
+				if( deltaX > SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						if( config.rtl ) {
+							this.Reveal.next();
+						}
+						else {
+							this.Reveal.prev()();
+						}
+					}
+					else {
+						this.Reveal.left();
+					}
+				}
+				else if( deltaX < -SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						if( config.rtl ) {
+							this.Reveal.prev()();
+						}
+						else {
+							this.Reveal.next();
+						}
+					}
+					else {
+						this.Reveal.right();
+					}
+				}
+				else if( deltaY > SWIPE_THRESHOLD ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						this.Reveal.prev()();
+					}
+					else {
+						this.Reveal.up();
+					}
+				}
+				else if( deltaY < -SWIPE_THRESHOLD ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						this.Reveal.next();
+					}
+					else {
+						this.Reveal.down();
+					}
+				}
+
+				// If we're embedded, only block touch events if they have
+				// triggered an action
+				if( config.embedded ) {
+					if( this.touchCaptured || this.Reveal.isVerticalSlide( currentSlide ) ) {
+						event.preventDefault();
+					}
+				}
+				// Not embedded? Block them all to avoid needless tossing
+				// around of the viewport in iOS
+				else {
+					event.preventDefault();
+				}
+
+			}
+		}
+		// There's a bug with swiping on some Android devices unless
+		// the default action is always prevented
+		else if( isAndroid ) {
+			event.preventDefault();
+		}
+
+	}
+
+	/**
+	 * Handler for the 'touchend' event.
+	 *
+	 * @param {object} event
+	 */
+	onTouchEnd( event ) {
+
+		this.touchCaptured = false;
+
+	}
+
+	/**
+	 * Convert pointer down to touch start.
+	 *
+	 * @param {object} event
+	 */
+	onPointerDown( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchStart( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer move to touch move.
+	 *
+	 * @param {object} event
+	 */
+	onPointerMove( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchMove( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer up to touch end.
+	 *
+	 * @param {object} event
+	 */
+	onPointerUp( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchEnd( event );
+		}
+
+	}
+
+}

+ 19 - 228
js/reveal.js

@@ -6,8 +6,11 @@ import Overview from './controllers/overview.js'
 import Keyboard from './controllers/keyboard.js'
 import Keyboard from './controllers/keyboard.js'
 import Location from './controllers/location.js'
 import Location from './controllers/location.js'
 import Plugins from './controllers/plugins.js'
 import Plugins from './controllers/plugins.js'
+import Touch from './controllers/touch.js'
 import Playback from './components/playback.js'
 import Playback from './components/playback.js'
 import defaultConfig from './config.js'
 import defaultConfig from './config.js'
+import { isMobile, isChrome, isAndroid, supportsZoom } from './utils/device.js'
+import { colorToRgb, colorBrightness } from './utils/color.js'
 import {
 import {
 	SLIDES_SELECTOR,
 	SLIDES_SELECTOR,
 	HORIZONTAL_SLIDES_SELECTOR,
 	HORIZONTAL_SLIDES_SELECTOR,
@@ -26,8 +29,6 @@ import {
 	enterFullscreen,
 	enterFullscreen,
 	getQueryHash
 	getQueryHash
 } from './utils/util.js'
 } from './utils/util.js'
-import { isMobile, isChrome, isAndroid, supportsZoom } from './utils/device.js'
-import { colorToRgb, colorBrightness } from './utils/color.js'
 
 
 /**
 /**
  * reveal.js
  * reveal.js
@@ -71,16 +72,6 @@ export default function( revealElement, options ) {
 		// The current scale of the presentation (see width/height config)
 		// The current scale of the presentation (see width/height config)
 		scale = 1,
 		scale = 1,
 
 
-		// CSS transform that is currently applied to the slides container,
-		// split into two groups
-		slidesTransform = { layout: '', overview: '' },
-
-		// Cached references to DOM elements
-		dom = {},
-
-		// Controller for plugin loading
-		plugins = new Plugins(),
-
 		// Controls loading and playback of slide content
 		// Controls loading and playback of slide content
 		slideContent = new SlideContent( Reveal ),
 		slideContent = new SlideContent( Reveal ),
 
 
@@ -102,6 +93,19 @@ export default function( revealElement, options ) {
 		// Controls the current location/URL
 		// Controls the current location/URL
 		location = new Location( Reveal ),
 		location = new Location( Reveal ),
 
 
+		// Controller for plugin loading
+		plugins = new Plugins(),
+
+		// Controls touch/swipe navigation for our deck
+		touch = new Touch( Reveal ),
+
+		// CSS transform that is currently applied to the slides container,
+		// split into two groups
+		slidesTransform = { layout: '', overview: '' },
+
+		// Cached references to DOM elements
+		dom = {},
+
 		// List of asynchronously loaded reveal.js dependencies
 		// List of asynchronously loaded reveal.js dependencies
 		asyncDependencies = [],
 		asyncDependencies = [],
 
 
@@ -124,16 +128,7 @@ export default function( revealElement, options ) {
 		autoSlidePlayer,
 		autoSlidePlayer,
 		autoSlideTimeout = 0,
 		autoSlideTimeout = 0,
 		autoSlideStartTime = -1,
 		autoSlideStartTime = -1,
-		autoSlidePaused = false,
-
-		// Holds information about the currently ongoing touch input
-		touch = {
-			startX: 0,
-			startY: 0,
-			startCount: 0,
-			captured: false,
-			threshold: 40
-		};
+		autoSlidePaused = false;
 
 
 	/**
 	/**
 	 * Starts up the presentation if the client is capable.
 	 * Starts up the presentation if the client is capable.
@@ -922,24 +917,7 @@ export default function( revealElement, options ) {
 		window.addEventListener( 'resize', onWindowResize, false );
 		window.addEventListener( 'resize', onWindowResize, false );
 
 
 		if( config.touch ) {
 		if( config.touch ) {
-			if( 'onpointerdown' in window ) {
-				// Use W3C pointer events
-				dom.wrapper.addEventListener( 'pointerdown', onPointerDown, false );
-				dom.wrapper.addEventListener( 'pointermove', onPointerMove, false );
-				dom.wrapper.addEventListener( 'pointerup', onPointerUp, false );
-			}
-			else if( window.navigator.msPointerEnabled ) {
-				// IE 10 uses prefixed version of pointer events
-				dom.wrapper.addEventListener( 'MSPointerDown', onPointerDown, false );
-				dom.wrapper.addEventListener( 'MSPointerMove', onPointerMove, false );
-				dom.wrapper.addEventListener( 'MSPointerUp', onPointerUp, false );
-			}
-			else {
-				// Fall back to touch events
-				dom.wrapper.addEventListener( 'touchstart', onTouchStart, false );
-				dom.wrapper.addEventListener( 'touchmove', onTouchMove, false );
-				dom.wrapper.addEventListener( 'touchend', onTouchEnd, false );
-			}
+			touch.bind();
 		}
 		}
 
 
 		if( config.keyboard ) {
 		if( config.keyboard ) {
@@ -984,23 +962,12 @@ export default function( revealElement, options ) {
 
 
 		eventsAreBound = false;
 		eventsAreBound = false;
 
 
+		touch.unbind();
 		keyboard.unbind();
 		keyboard.unbind();
 
 
 		window.removeEventListener( 'hashchange', onWindowHashChange, false );
 		window.removeEventListener( 'hashchange', onWindowHashChange, false );
 		window.removeEventListener( 'resize', onWindowResize, false );
 		window.removeEventListener( 'resize', onWindowResize, false );
 
 
-		dom.wrapper.removeEventListener( 'pointerdown', onPointerDown, false );
-		dom.wrapper.removeEventListener( 'pointermove', onPointerMove, false );
-		dom.wrapper.removeEventListener( 'pointerup', onPointerUp, false );
-
-		dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false );
-		dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false );
-		dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false );
-
-		dom.wrapper.removeEventListener( 'touchstart', onTouchStart, false );
-		dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false );
-		dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false );
-
 		dom.pauseOverlay.removeEventListener( 'click', resume, false );
 		dom.pauseOverlay.removeEventListener( 'click', resume, false );
 
 
 		if ( config.progress && dom.progress ) {
 		if ( config.progress && dom.progress ) {
@@ -3121,21 +3088,6 @@ export default function( revealElement, options ) {
 
 
 	}
 	}
 
 
-	/**
-	 * Checks if the target element prevents the triggering of
-	 * swipe navigation.
-	 */
-	function isSwipePrevented( target ) {
-
-		while( target && typeof target.hasAttribute === 'function' ) {
-			if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
-			target = target.parentNode;
-		}
-
-		return false;
-
-	}
-
 
 
 	// --------------------------------------------------------------------//
 	// --------------------------------------------------------------------//
 	// ----------------------------- EVENTS -------------------------------//
 	// ----------------------------- EVENTS -------------------------------//
@@ -3171,167 +3123,6 @@ export default function( revealElement, options ) {
 
 
 	}
 	}
 
 
-	/**
-	 * Handler for the 'touchstart' event, enables support for
-	 * swipe and pinch gestures.
-	 *
-	 * @param {object} event
-	 */
-	function onTouchStart( event ) {
-
-		if( isSwipePrevented( event.target ) ) return true;
-
-		touch.startX = event.touches[0].clientX;
-		touch.startY = event.touches[0].clientY;
-		touch.startCount = event.touches.length;
-
-	}
-
-	/**
-	 * Handler for the 'touchmove' event.
-	 *
-	 * @param {object} event
-	 */
-	function onTouchMove( event ) {
-
-		if( isSwipePrevented( event.target ) ) return true;
-
-		// Each touch should only trigger one action
-		if( !touch.captured ) {
-			onUserInput( event );
-
-			let currentX = event.touches[0].clientX;
-			let currentY = event.touches[0].clientY;
-
-			// There was only one touch point, look for a swipe
-			if( event.touches.length === 1 && touch.startCount !== 2 ) {
-
-				let deltaX = currentX - touch.startX,
-					deltaY = currentY - touch.startY;
-
-				if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
-					touch.captured = true;
-					if( config.navigationMode === 'linear' ) {
-						if( config.rtl ) {
-							navigateNext();
-						}
-						else {
-							navigatePrev();
-						}
-					}
-					else {
-						navigateLeft();
-					}
-				}
-				else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
-					touch.captured = true;
-					if( config.navigationMode === 'linear' ) {
-						if( config.rtl ) {
-							navigatePrev();
-						}
-						else {
-							navigateNext();
-						}
-					}
-					else {
-						navigateRight();
-					}
-				}
-				else if( deltaY > touch.threshold ) {
-					touch.captured = true;
-					if( config.navigationMode === 'linear' ) {
-						navigatePrev();
-					}
-					else {
-						navigateUp();
-					}
-				}
-				else if( deltaY < -touch.threshold ) {
-					touch.captured = true;
-					if( config.navigationMode === 'linear' ) {
-						navigateNext();
-					}
-					else {
-						navigateDown();
-					}
-				}
-
-				// If we're embedded, only block touch events if they have
-				// triggered an action
-				if( config.embedded ) {
-					if( touch.captured || isVerticalSlide( currentSlide ) ) {
-						event.preventDefault();
-					}
-				}
-				// Not embedded? Block them all to avoid needless tossing
-				// around of the viewport in iOS
-				else {
-					event.preventDefault();
-				}
-
-			}
-		}
-		// There's a bug with swiping on some Android devices unless
-		// the default action is always prevented
-		else if( isAndroid ) {
-			event.preventDefault();
-		}
-
-	}
-
-	/**
-	 * Handler for the 'touchend' event.
-	 *
-	 * @param {object} event
-	 */
-	function onTouchEnd( event ) {
-
-		touch.captured = false;
-
-	}
-
-	/**
-	 * Convert pointer down to touch start.
-	 *
-	 * @param {object} event
-	 */
-	function onPointerDown( event ) {
-
-		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
-			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
-			onTouchStart( event );
-		}
-
-	}
-
-	/**
-	 * Convert pointer move to touch move.
-	 *
-	 * @param {object} event
-	 */
-	function onPointerMove( event ) {
-
-		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
-			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
-			onTouchMove( event );
-		}
-
-	}
-
-	/**
-	 * Convert pointer up to touch end.
-	 *
-	 * @param {object} event
-	 */
-	function onPointerUp( event ) {
-
-		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
-			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
-			onTouchEnd( event );
-		}
-
-	}
-
 	/**
 	/**
 	 * Handles mouse wheel scrolling, throttled to avoid skipping
 	 * Handles mouse wheel scrolling, throttled to avoid skipping
 	 * multiple slides.
 	 * multiple slides.

Некоторые файлы не были показаны из-за большого количества измененных файлов