diff options
Diffstat (limited to 'js/reveal.js')
-rw-r--r-- | js/reveal.js | 199 |
1 files changed, 148 insertions, 51 deletions
diff --git a/js/reveal.js b/js/reveal.js index d6c5b5b..33b58cf 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -53,7 +53,18 @@ var Reveal = (function(){ mouseWheelTimeout = 0, // Delays updates to the URL due to a Chrome thumbnailer bug - writeURLTimeout = 0; + writeURLTimeout = 0, + + // Holds information about the currently ongoing touch input + touch = { + startX: 0, + startY: 0, + startSpan: 0, + startCount: 0, + handled: false, + threshold: 40 + }; + /** * Starts up the slideshow by applying configuration @@ -79,14 +90,7 @@ var Reveal = (function(){ dom.controlsUp = document.querySelector( '#reveal .controls .up' ); dom.controlsDown = document.querySelector( '#reveal .controls .down' ); - // Bind all view events - document.addEventListener( 'keydown', onDocumentKeyDown, false ); - document.addEventListener( 'touchstart', onDocumentTouchStart, false ); - window.addEventListener( 'hashchange', onWindowHashChange, false ); - dom.controlsLeft.addEventListener( 'click', preventAndForward( navigateLeft ), false ); - dom.controlsRight.addEventListener( 'click', preventAndForward( navigateRight ), false ); - dom.controlsUp.addEventListener( 'click', preventAndForward( navigateUp ), false ); - dom.controlsDown.addEventListener( 'click', preventAndForward( navigateDown ), false ); + addEventListeners(); // Copy options over to our config object extend( config, options ); @@ -135,6 +139,33 @@ var Reveal = (function(){ window.addEventListener( 'load', removeAddressBar, false ); window.addEventListener( 'orientationchange', removeAddressBar, false ); } + + } + + function addEventListeners() { + document.addEventListener( 'keydown', onDocumentKeyDown, false ); + document.addEventListener( 'touchstart', onDocumentTouchStart, false ); + document.addEventListener( 'touchmove', onDocumentTouchMove, false ); + document.addEventListener( 'touchend', onDocumentTouchEnd, false ); + window.addEventListener( 'hashchange', onWindowHashChange, false ); + + dom.controlsLeft.addEventListener( 'click', preventAndForward( navigateLeft ), false ); + dom.controlsRight.addEventListener( 'click', preventAndForward( navigateRight ), false ); + dom.controlsUp.addEventListener( 'click', preventAndForward( navigateUp ), false ); + dom.controlsDown.addEventListener( 'click', preventAndForward( navigateDown ), false ); + } + + function removeEventListeners() { + document.removeEventListener( 'keydown', onDocumentKeyDown, false ); + document.removeEventListener( 'touchstart', onDocumentTouchStart, false ); + document.removeEventListener( 'touchmove', onDocumentTouchMove, false ); + document.removeEventListener( 'touchend', onDocumentTouchEnd, false ); + window.removeEventListener( 'hashchange', onWindowHashChange, false ); + + dom.controlsLeft.removeEventListener( 'click', preventAndForward( navigateLeft ), false ); + dom.controlsRight.removeEventListener( 'click', preventAndForward( navigateRight ), false ); + dom.controlsUp.removeEventListener( 'click', preventAndForward( navigateUp ), false ); + dom.controlsDown.removeEventListener( 'click', preventAndForward( navigateDown ), false ); } /** @@ -147,6 +178,13 @@ var Reveal = (function(){ } } + function distanceBetween( a, b ) { + var dx = a.x - b.x, + dy = a.y - b.y; + + return Math.sqrt( dx*dx + dy*dy ); + } + /** * Prevents an events defaults behavior calls the * specified delegate. @@ -224,54 +262,98 @@ var Reveal = (function(){ } } - + /** - * Handler for the document level 'touchstart' event. - * - * This enables very basic tap interaction for touch - * devices. Added mainly for performance testing of 3D - * transforms on iOS but was so happily surprised with - * how smoothly it runs so I left it in here. Apple +1 - * - * @param {Object} event + * Handler for the document level 'touchstart' event, + * enables support for swipe and pinch gestures. */ function onDocumentTouchStart( event ) { - // We're only interested in one point taps - if (event.touches.length === 1) { - // Never prevent taps on anchors and images - if( event.target.tagName.toLowerCase() === 'a' || event.target.tagName.toLowerCase() === 'img' ) { - return; - } - - event.preventDefault(); - - var point = { - x: event.touches[0].clientX, - y: event.touches[0].clientY - }; - - // Define the extent of the areas that may be tapped - // to navigate - var wt = window.innerWidth * 0.3; - var ht = window.innerHeight * 0.3; - - if( point.x < wt ) { - navigateLeft(); - } - else if( point.x > window.innerWidth - wt ) { - navigateRight(); - } - else if( point.y < ht ) { - navigateUp(); + touch.startX = event.touches[0].clientX; + touch.startY = event.touches[0].clientY; + touch.startCount = event.touches.length; + + // If there's two touches we need to memorize the distance + // between those two points to detect pinching + if( event.touches.length === 2 ) { + touch.startSpan = distanceBetween( { + x: event.touches[1].clientX, + y: event.touches[1].clientY + }, { + x: touch.startX, + y: touch.startY + } ); + } + } + + /** + * Handler for the document level 'touchmove' event. + */ + function onDocumentTouchMove( event ) { + // Each touch should only trigger one action + if( !touch.handled ) { + var currentX = event.touches[0].clientX; + var currentY = event.touches[0].clientY; + + // If the touch started off with two points and still has + // two active touches; test for the pinch gesture + if( event.touches.length === 2 && touch.startCount === 2 ) { + + // The current distance in pixels between the two touch points + var currentSpan = distanceBetween( { + x: event.touches[1].clientX, + y: event.touches[1].clientY + }, { + x: touch.startX, + y: touch.startY + } ); + + // If the span is larger than the desire amount we've got + // ourselves a pinch + if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) { + touch.handled = true; + + if( currentSpan < touch.startSpan ) { + activateOverview(); + } + else { + deactivateOverview(); + } + } + } - else if( point.y > window.innerHeight - ht ) { - navigateDown(); + // There was only one touch point, look for a swipe + else if( event.touches.length === 1 ) { + var deltaX = currentX - touch.startX, + deltaY = currentY - touch.startY; + + if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) { + touch.handled = true; + navigateLeft(); + } + else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) { + touch.handled = true; + navigateRight(); + } + else if( deltaY > touch.threshold ) { + touch.handled = true; + navigateUp(); + } + else if( deltaY < -touch.threshold ) { + touch.handled = true; + navigateDown(); + } } - - slide(); + + event.preventDefault(); } } + /** + * Handler for the document level 'touchend' event. + */ + function onDocumentTouchEnd( event ) { + touch.handled = false; + } /** * Handles mouse wheel scrolling, throttled to avoid @@ -326,6 +408,7 @@ var Reveal = (function(){ * can't be improved. */ function activateOverview() { + dom.wrapper.classList.add( 'overview' ); var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); @@ -341,12 +424,12 @@ var Reveal = (function(){ hslide.style.msTransform = htransform; hslide.style.OTransform = htransform; hslide.style.transform = htransform; - + if( !hslide.classList.contains( 'stack' ) ) { // Navigate to this slide on click hslide.addEventListener( 'click', onOverviewSlideClicked, true ); } - + var verticalSlides = Array.prototype.slice.call( hslide.querySelectorAll( 'section' ) ); for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) { @@ -365,6 +448,7 @@ var Reveal = (function(){ // Navigate to this slide on click vslide.addEventListener( 'click', onOverviewSlideClicked, true ); } + } } @@ -786,6 +870,18 @@ var Reveal = (function(){ availableRoutes().down ? navigateDown() : navigateRight(); } } + + /** + * Toggles the slide overview mode on and off. + */ + function toggleOverview() { + if( overviewIsActive() ) { + deactivateOverview(); + } + else { + activateOverview(); + } + } // Expose some methods publicly return { @@ -795,6 +891,7 @@ var Reveal = (function(){ navigateRight: navigateRight, navigateUp: navigateUp, navigateDown: navigateDown, + toggleOverview: toggleOverview, // Forward event binding to the reveal DOM element addEventListener: function( type, listener, useCapture ) { |