diff options
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | index.html | 3 | ||||
-rw-r--r-- | plugin/leap/leap.js | 103 |
3 files changed, 73 insertions, 45 deletions
@@ -628,10 +628,10 @@ Reveal.initialize({ ## Leap Motion The Leap Motion plugin lets you utilize your [Leap Motion](https://www.leapmotion.com/) device to control basic navigation of your presentation. The gestures currently supported are: -##### 1 hand + 1 finger +##### 1 to 2 fingers * Pointer — Point to anything on screen. Move your finger past the device to expand the pointer. -##### 1 hand + 2 or more fingers +##### 1 hand + 3 or more fingers * Left * Right @@ -647,11 +647,13 @@ Toggle the overview mode. Do it a second time to exit the overview. #### Config Options You can edit the following options: +* autoCenter: Defaults to true. Center the pointer based on where you put your finger into the leap motions detection field. +* gestureDelay: Defaults to 500. How long to delay between gestures in milliseconds. * naturalSwipe: Defaults to true. Swipe as though you were touching a touch screen. Set to false to invert. -* pointerSize: Defaults to 15. The minimum height and width of the pointer. * pointerColor: Defaults to #00aaff. The color of the pointer. -* pointerOpacity: Defaults to 0.75. The opacity of the pointer. -* gestureDelay: Defaults to 500. How long to delay between gestures in milliseconds. +* pointerOpacity: Defaults to 0.7. The opacity of the pointer. +* pointerSize: Defaults to 15. The minimum height and width of the pointer. +* pointerTolerance: Defaults to 120. Bigger = slower pointer. Example configuration: ```js @@ -370,7 +370,8 @@ function linkify( selector ) { { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, { src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }, { src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } }, - { src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } } + { src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }, + { src: 'plugin/leap/leap.js', async: true } // { src: 'plugin/search/search.js', async: true, condition: function() { return !!document.body.classList; } } // { src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } } ] diff --git a/plugin/leap/leap.js b/plugin/leap/leap.js index a605153..8ec51ec 100644 --- a/plugin/leap/leap.js +++ b/plugin/leap/leap.js @@ -23,78 +23,103 @@ var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)re */ (function () { - var controller = new Leap.Controller({ enableGestures: true }), - leapConfig = Reveal.getConfig().leap, - pointer = document.createElement('div'), - body = document.body, + var body = document.body, + controller = new Leap.Controller({ enableGestures: true }), lastGesture = 0, + leapConfig = Reveal.getConfig().leap, + pointer = document.createElement( 'div' ), config = { - naturalSwipe : true, // Swipe as if it were a touch screen. - pointerSize : 15, // Default height/width of the pointer. - pointerColor : '#00aaff', // Default color of the pointer. - pointerOpacity : 0.75, // Default opacity of the pointer. - gestureDelay : 500 // How long to delay between gestures. + autoCenter : true, // Center pointer around detected position. + gestureDelay : 500, // How long to delay between gestures. + naturalSwipe : true, // Swipe as if it were a touch screen. + pointerColor : '#00aaff', // Default color of the pointer. + pointerOpacity : 0.7, // Default opacity of the pointer. + pointerSize : 15, // Default height/width of the pointer. + pointerTolerance : 120 // Bigger = slower pointer. }, - now; + now, + entered; // Merge user defined settings with defaults - if ( leapConfig ) { - for (key in leapConfig) { + if( leapConfig ) { + for( key in leapConfig ) { config[key] = leapConfig[key]; } } pointer.id = 'leap'; - pointer.style.filter = 'alpha(opacity="' + config.pointerOpacity * 100 + '")'; pointer.style.opacity = config.pointerOpacity; pointer.style.backgroundColor = config.pointerColor; - body.appendChild(pointer); + body.appendChild( pointer ); - controller.on('frame', function (frame) { + // Leap's loop + controller.on( 'frame', function ( frame ) { // Timing code to rate limit gesture execution now = new Date().getTime(); - // Pointer code - if ( frame.hands.length === 1 && frame.fingers.length === 1 ) { - var size = -2 * frame.hands[0].palmPosition[2]; + // Pointer: 1 to 2 fingers. Strictly one finger works but may cause innaccuracies. + // The innaccuracies were observed on a development model and may not be an issue with consumer models. + if( frame.fingers.length > 0 && frame.fingers.length < 3 ) { + // Invert direction and multiply by 3 for greater effect. + var size = -3 * frame.fingers[0].tipPosition[2]; - if ( size < config.pointerSize ) { - size = config.pointerSize + if( size < config.pointerSize ) { + size = config.pointerSize; } - pointer.style.bottom = - frame.hands[0].palmPosition[1] * (body.offsetHeight / 100) - body.offsetHeight + 'px'; - - pointer.style.left = - frame.hands[0].palmPosition[0] * (body.offsetWidth / 100) + (body.offsetWidth / 2) + 'px'; - - pointer.style.visibility = 'visible'; pointer.style.width = size + 'px'; pointer.style.height = size + 'px'; pointer.style.borderRadius = size - 5 + 'px'; - } + pointer.style.visibility = 'visible'; + + tipPosition = frame.fingers[0].tipPosition; + + if( config.autoCenter ) { + // Check whether the finger has entered the z range of the Leap Motion. Used for the autoCenter option. + if( !entered ) { + entered = true; + enteredPosition = frame.fingers[0].tipPosition; + } + + pointer.style.top = + (-1 * (( tipPosition[1] - enteredPosition[1] ) * body.offsetHeight / config.pointerTolerance )) + + ( body.offsetHeight / 2 ) + 'px'; + + pointer.style.left = + (( tipPosition[0] - enteredPosition[0] ) * body.offsetWidth / config.pointerTolerance ) + + ( body.offsetWidth / 2 ) + 'px'; + } + else { + pointer.style.top = ( 1 - (( tipPosition[1] - 50) / config.pointerTolerance )) * + body.offsetHeight + 'px'; + + pointer.style.left = ( tipPosition[0] * body.offsetWidth / config.pointerTolerance ) + + ( body.offsetWidth / 2 ) + 'px'; + } + } else { // Hide pointer on exit + entered = false; pointer.style.visibility = 'hidden'; } - + // Gestures - if ( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) { + if( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) { var gesture = frame.gestures[0]; // One hand gestures if( frame.hands.length === 1 ) { - // Swipe gestures. 2+ fingers. - if ( frame.fingers.length > 1 && gesture.type === 'swipe' ) { + // Swipe gestures. 3+ fingers. + if( frame.fingers.length > 2 && gesture.type === 'swipe' ) { // Define here since some gestures will throw undefined for these. var x = gesture.direction[0], y = gesture.direction[1]; // Left/right swipe gestures - if ( Math.abs(x) > Math.abs(y) ) { - if ( x > 0 ) { + if( Math.abs( x ) > Math.abs( y )) { + if( x > 0 ) { config.naturalSwipe ? Reveal.left() : Reveal.right(); } else { @@ -105,7 +130,7 @@ var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)re // Up/down swipe gestures } else { - if ( y > 0 ) { + if( y > 0 ) { config.naturalSwipe ? Reveal.down() : Reveal.up(); } else { @@ -115,11 +140,11 @@ var b=right.criteria;if(a!==b){if(a>b||a===void 0)return 1;if(a<b||b===void 0)re lastGesture = now; } } - // Two hand gestures } - else if ( frame.hands.length == 2 ) { - // All upwards 2 hand gestures = toggle overview - if ( gesture.direction[1] > 0 ) { + // Two hand gestures + else if( frame.hands.length === 2 ) { + // Upward two hand swipe gesture + if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) { Reveal.toggleOverview(); } |