A collection of plugins available built on top of the LeapJS plugin framework. The library is written in CoffeeScript, but CoffeeScript is not required to run applications.
GitHub Projectleapmotion/leapjs-plugins
Edit the markdown for these docs on github.
This project is maintained by leapmotion.
Hosted on GitHub Pages — Theme by orderedlist
Fires controller events when a hand enters or leaves the frame.
1 controller.use('handEntry')
Triggered from the controller. This passes in the Hand object.
Triggered from the controller. This passes in the Hand as it was seen in the last frame.
This event is also triggered for every hand present when the device is disconnected.
1 controller.use('handHolding')
The hand-holding plugin provides a simple way to store data about a hand object between frames.
Similar to jQuery.data, this method allows a value to be get or set. This is the main method, all else are convenience methods.
This will either hold the value passed in, or hold on to whatever the hand is currently hovering over (see below).
This will return the object currently being held.
1 hand.holding(); // returns someDiv
Sets a function which the hand will use to determine what it is hovering over.
Returns what the hand is currently hovering over, based upon the hoverFn. If no callback is set, will return undefined.
1 hand.hovering() // returns the results of hand.closestDiv();
# Calculates how much a hand has changed pitch in the last few seconds.
Leap.Controller.plugin 'sumPitch', (options = {})->
timeWindow = options.timeWindow || 1 # seconds
# delta of both hands are combined
pitchData = []
{
hand: (hand)->
# skip momentary hands
if hand.timeVisible < 1
return
# initial pass
# we namespace our keys under sumPitch
lastPitch = hand.data('sumPitch.lastPitch')
currentPitch = hand.pitch()
hand.data('sumPitch.lastPitch', currentPitch)
return unless lastPitch
# store values with timestamps
now = Date.now()
pitchData.push({
delta: currentPitch - lastPitch,
time: now
})
# manage rolling sum
while pitchData[0].time < (now - (timeWindow * 1000))
pitchData.shift()
hand.sumPitch = 0
for data in pitchData
hand.sumPitch += Math.abs(data.delta)
}
# The controller has already been initialized at the top of the page. Otherwise:
# controller = new Leap.Controller();
# controller.connect()
window.handHoldDemo = $('#hand-hold-demo')
controller.on 'frame', (frame)->
if frame.hands[0]
handHoldDemo.html("frame id: #{frame.id} <br/>hand sumPitch (in the last second): #{frame.hands[0].sumPitch.toPrecision(3)}")
else
handHoldDemo.html('frame id: ' + frame.id + ' <br/>no hand present.');
// Calculates how much a hand has changed pitch in the last few seconds.
Leap.Controller.plugin('sumPitch', function(options) {
options || (options = {})
var pitchData = [],
timeWindow = options.timeWindow || 1; // seconds
return {
hand: function(hand) {
var currentPitch, data, lastPitch, mostDistantTime, now, _i, _len;
hand.sumPitch = 0;
if (hand.timeVisible < 1) {
return;
}
lastPitch = hand.data('sumPitch.lastPitch');
currentPitch = hand.pitch();
hand.data('sumPitch.lastPitch', currentPitch);
if (!lastPitch) {
return;
}
// store values with timesstamps
now = Date.now();
pitchData.push({
delta: currentPitch - lastPitch,
time: now
});
// manage rolling sum
while (pitchData[0].time < (now - (timeWindow * 1000))) {
pitchData.shift();
}
for (_i = 0, _len = pitchData.length; _i < _len; _i++) {
data = pitchData[_i];
hand.sumPitch += Math.abs(data.delta);
}
}
};
});
window.handHoldDemo = $('#hand-hold-demo');
// The controller has already been initialized at the top of the page. Otherwise:
// var controller = new Leap.Controller();
// controller.connect()
controller
.use('handHold')
.use('sumPitch')
.on('frame', function(frame) {
if (frame.hands[0]) {
return handHoldDemo.html('frame id: ' + frame.id + ' <br/>hand sumPitch (in the last second): ' + frame.hands[0].sumPitch.toPrecision(3));
}else{
return handHoldDemo.html('frame id: ' + frame.id + ' <br/>no hand present.');
}
})
Adds the “screenPosition” method by default to hands and pointables. This returns a vec3 (an array of length 3) with [x,y,z] screen coordinates indicating where the hand is. This method can accept an optional vec3, allowing it to convert any arbitrary vec3 of coordinates.
Custom positioning methods can be passed in, allowing different scaling techniques,
e.g., Pointer Ballistics for Windows XP
Here we scale based upon the interaction box and screen size:
1 controller.use('screenPosition') 2 // or 3 controller.use('screenPosition', {positioning: 'absolute'}) // the default 4 // or 5 controller.use 'screenPosition', { 6 positioning: function(positionVec3){ 7 // Arguments for Leap.vec3 are (out, a, b) 8 [ 9 Leap.vec3.subtract(positionVec3, positionVec3, this.frame.interactionBox.center) 10 Leap.vec3.divide(positionVec3, positionVec3, this.frame.interactionBox.size) 11 Leap.vec3.multiply(positionVec3, positionVec3, [window.innerWidth, window.innerHeight, 0]) 12 ] 13 } 14 } 15 16 // later... 17 hand.screenPosition() // returns [156,204,0]
More info on vec3 can be found, In the gl-matrix docs
Returns the location of the hand in screen-space, or the passed in vector in screen-space.
Applies to hands and pointables.
window.handHoldDemoCursor = $('#screen-position-demo .cursor')
window.handHoldDemoOutput = $('#screen-position-demo .output')
controller
.use('screenPosition', {scale: 8})
.on('frame', (frame)->
if hand = frame.hands[0]
handHoldDemoOutput.html("[<br/> #{hand.screenPosition()[0]}
<br/> #{hand.screenPosition()[1]}
<br/> #{hand.screenPosition()[2]}<br/>]")
handHoldDemoCursor.css(
left: hand.screenPosition()[0],
bottom: hand.screenPosition()[1]
)
).on('deviceConnected', ->
$('#screen-position-demo .noleap').remove()
)
window.handHoldDemoCursor = $('#screen-position-demo .cursor');
window.handHoldDemoOutput = $('#screen-position-demo .output')
controller
.use('screenPosition', {
scale: 8
})
.on('frame', function(frame) {
var hand;
if (hand = frame.hands[0]) {
handHoldDemoOutput.html("[<br/> " + (hand.screenPosition()[0]) +
" <br/> " + (hand.screenPosition()[1]) +
" <br/> " + (hand.screenPosition()[2]) + "<br/>]");
return handHoldDemoCursor.css({
left: hand.screenPosition()[0] + 'px',
bottom: hand.screenPosition()[1] + 'px'
});
}
}).on('deviceConnected', function(){
$('#screen-position-demo .noleap').remove()
});
This plugin is used to confirm a minimum LeapJS protocol version. For an application or plugin which requires functionality specific to a minimum protocol, include and configure this plugin.
When a device is ready, it will check the protocol version and if outdated emit versionCheck.outdated
from the controller with data e.g., {current: 5, required: 6, disconnect: true}
.
disconnect
[boolean true]
If out of date, the controller will be disconnected, preventing any frames from being
received, unless the disconnect option is set to false.
requiredProtocolVersion
[integer 6]
The required protocol version.
alert
[boolean false]
If out of date, show an alert dialog with the following message: “Your Leap Software version is out of date. Visit http://www.leapmotion.com/setup to update”
This plugin is used to send pre-recorded Leap frame data in to any Leap App.
recording
[string {frames: [], metadata: {}}]
A blob of JSON data. This should include two keys:
frames
, an array of raw frames as emittedmetadata
, additional info about the file. Metadata may include:
formatVersion
- the spec version of JSON blog. This should aways be 1generatedBy
- A string explaining what software made the recordingframes
- The number of frames in blobframeRate
- The average frame rate of the recording. This can be understood as the level of compression.protocolVersion
- A number indicating protocolVersion was used when recording the frame dataserviceVersion
- A string indicating which version of the Leap Service was used when recording the frame data.autoPlay
[boolean true]
Begin playback immediately upon load.
overlay
[boolean true or an element]
Show “Connect Device” and “Move hands over device” indicator images. These images
will be automatically displayed at the top of the page based upon device state. The overlay element can be accessed
and customized at any time through the plugin scope. E.g., myController.plugins.playback.player.overlay
pauseOnHand
[boolean false]
Have playback stop when a hand is inserted over the Leap device, and start again when the hand is removed.
requiredProtocolVersion
[number]
When using pauseOnHand, set a minimum required protocol version for the user to take control
loop
[boolean true]
Automatically repeat playback when the recording has finished.
timeBetweenLoops
[number, ms]
When looping, how long to wait between plays.This plugin comes with an extensive API for usage in an application, including functions such as play, pause, record, stop, and export. When leapjs-playback
is released as a standalone repository, they will be documented there. These can be access as follows:
1 controller.plugins.playback.player.play()