Various updates
Enhanced the pointer. Cleaned up the code. Added additional optional parameters. Updated documentation. modified: README.md modified: index.html modified: plugin/leap/leap.js
This commit is contained in:
parent
1d895bad61
commit
bd543e5cee
3 changed files with 74 additions and 46 deletions
14
README.md
14
README.md
|
@ -628,10 +628,10 @@ Reveal.initialize({
|
||||||
## Leap Motion
|
## 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:
|
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.
|
* 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
|
* Left
|
||||||
* Right
|
* Right
|
||||||
|
@ -647,11 +647,13 @@ Toggle the overview mode. Do it a second time to exit the overview.
|
||||||
|
|
||||||
#### Config Options
|
#### Config Options
|
||||||
You can edit the following options:
|
You can edit the following options:
|
||||||
* naturalSwipe: Defaults to true. Swipe as though you were touching a touch screen. Set to false to invert.
|
* autoCenter: Defaults to true. Center the pointer based on where you put your finger into the leap motions detection field.
|
||||||
* 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.
|
* 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.
|
||||||
|
* pointerColor: Defaults to #00aaff. The color of the pointer.
|
||||||
|
* 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:
|
Example configuration:
|
||||||
```js
|
```js
|
||||||
|
|
|
@ -370,7 +370,8 @@ function linkify( selector ) {
|
||||||
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
|
{ 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/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/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/search/search.js', async: true, condition: function() { return !!document.body.classList; } }
|
||||||
// { src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }
|
// { src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }
|
||||||
]
|
]
|
||||||
|
|
|
@ -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 () {
|
(function () {
|
||||||
var controller = new Leap.Controller({ enableGestures: true }),
|
var body = document.body,
|
||||||
leapConfig = Reveal.getConfig().leap,
|
controller = new Leap.Controller({ enableGestures: true }),
|
||||||
pointer = document.createElement('div'),
|
|
||||||
body = document.body,
|
|
||||||
lastGesture = 0,
|
lastGesture = 0,
|
||||||
|
leapConfig = Reveal.getConfig().leap,
|
||||||
|
pointer = document.createElement( 'div' ),
|
||||||
config = {
|
config = {
|
||||||
|
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.
|
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.
|
pointerColor : '#00aaff', // Default color of the pointer.
|
||||||
pointerOpacity : 0.75, // Default opacity of the pointer.
|
pointerOpacity : 0.7, // Default opacity of the pointer.
|
||||||
gestureDelay : 500 // How long to delay between gestures.
|
pointerSize : 15, // Default height/width of the pointer.
|
||||||
|
pointerTolerance : 120 // Bigger = slower pointer.
|
||||||
},
|
},
|
||||||
now;
|
now,
|
||||||
|
entered;
|
||||||
|
|
||||||
// Merge user defined settings with defaults
|
// Merge user defined settings with defaults
|
||||||
if ( leapConfig ) {
|
if( leapConfig ) {
|
||||||
for (key in leapConfig) {
|
for( key in leapConfig ) {
|
||||||
config[key] = leapConfig[key];
|
config[key] = leapConfig[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer.id = 'leap';
|
pointer.id = 'leap';
|
||||||
|
|
||||||
pointer.style.filter = 'alpha(opacity="' + config.pointerOpacity * 100 + '")';
|
|
||||||
pointer.style.opacity = config.pointerOpacity;
|
pointer.style.opacity = config.pointerOpacity;
|
||||||
pointer.style.backgroundColor = config.pointerColor;
|
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
|
// Timing code to rate limit gesture execution
|
||||||
now = new Date().getTime();
|
now = new Date().getTime();
|
||||||
|
|
||||||
// Pointer code
|
// Pointer: 1 to 2 fingers. Strictly one finger works but may cause innaccuracies.
|
||||||
if ( frame.hands.length === 1 && frame.fingers.length === 1 ) {
|
// The innaccuracies were observed on a development model and may not be an issue with consumer models.
|
||||||
var size = -2 * frame.hands[0].palmPosition[2];
|
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 ) {
|
if( size < config.pointerSize ) {
|
||||||
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.width = size + 'px';
|
||||||
pointer.style.height = size + 'px';
|
pointer.style.height = size + 'px';
|
||||||
pointer.style.borderRadius = size - 5 + '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 {
|
else {
|
||||||
// Hide pointer on exit
|
// Hide pointer on exit
|
||||||
|
entered = false;
|
||||||
pointer.style.visibility = 'hidden';
|
pointer.style.visibility = 'hidden';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestures
|
// Gestures
|
||||||
if ( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) {
|
if( frame.gestures.length > 0 && (now - lastGesture) > config.gestureDelay ) {
|
||||||
var gesture = frame.gestures[0];
|
var gesture = frame.gestures[0];
|
||||||
|
|
||||||
// One hand gestures
|
// One hand gestures
|
||||||
if( frame.hands.length === 1 ) {
|
if( frame.hands.length === 1 ) {
|
||||||
// Swipe gestures. 2+ fingers.
|
// Swipe gestures. 3+ fingers.
|
||||||
if ( frame.fingers.length > 1 && gesture.type === 'swipe' ) {
|
if( frame.fingers.length > 2 && gesture.type === 'swipe' ) {
|
||||||
// Define here since some gestures will throw undefined for these.
|
// Define here since some gestures will throw undefined for these.
|
||||||
var x = gesture.direction[0],
|
var x = gesture.direction[0],
|
||||||
y = gesture.direction[1];
|
y = gesture.direction[1];
|
||||||
|
|
||||||
// Left/right swipe gestures
|
// Left/right swipe gestures
|
||||||
if ( Math.abs(x) > Math.abs(y) ) {
|
if( Math.abs( x ) > Math.abs( y )) {
|
||||||
if ( x > 0 ) {
|
if( x > 0 ) {
|
||||||
config.naturalSwipe ? Reveal.left() : Reveal.right();
|
config.naturalSwipe ? Reveal.left() : Reveal.right();
|
||||||
}
|
}
|
||||||
else {
|
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
|
// Up/down swipe gestures
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( y > 0 ) {
|
if( y > 0 ) {
|
||||||
config.naturalSwipe ? Reveal.down() : Reveal.up();
|
config.naturalSwipe ? Reveal.down() : Reveal.up();
|
||||||
}
|
}
|
||||||
else {
|
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;
|
lastGesture = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Two hand gestures
|
|
||||||
}
|
}
|
||||||
else if ( frame.hands.length == 2 ) {
|
// Two hand gestures
|
||||||
// All upwards 2 hand gestures = toggle overview
|
else if( frame.hands.length === 2 ) {
|
||||||
if ( gesture.direction[1] > 0 ) {
|
// Upward two hand swipe gesture
|
||||||
|
if( gesture.direction[1] > 0 && gesture.type === 'swipe' ) {
|
||||||
Reveal.toggleOverview();
|
Reveal.toggleOverview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue