Detect swipe gesture with leap motion - javascript

I knowed how to detect gesture left and right from
this
I want to know how to detect gesture up , down and circle.
My English is poor. I dont think you can understand, but help me plz.

For swipe directions, you can compare the x and y coordinates of the direction property of the Gesture object. In the Leap Motion JavaScript API, vectors are represented by 3-element arrays. So:
gesture.direction[0] is the x coordinate (left to right)
gesture.direction[1] is the y coordinate ( up, down)
gesture.direction[2] is the z coordinate (front to back)
The example you cite only looks at the sign of the x-coordinate -- so all swipes are classified as either right or left. To also classify swipes as up or down, you will have to compare the magnitude of the x and y coordinates to determine if the swipe is more horizontal or more vertical and then compare the sign of the coordinate to determine if a horizontal swipe is left or right or a vertical swipe is up or down.
Circle gestures are reported as a different type of gesture, so you can look at the gesture.type property.
Here is some JavaScript that illustrates this (adapted from the Sample.html file included with the Leap Motion SDK):
// Store frame for motion functions
var previousFrame = null;
// Setup Leap loop with frame callback function
var controllerOptions = {enableGestures: true};
Leap.loop(controllerOptions, function(frame) {
// Display Gesture object data
var gestureOutput = document.getElementById("gestureData");
var gestureString = "";
if (frame.gestures.length > 0) {
for (var i = 0; i < frame.gestures.length; i++) {
var gesture = frame.gestures[i];
switch (gesture.type) {
case "circle":
gestureString += "<br>ID: " + gesture.id + "<br>type: " + gesture.type + ", "
+ "<br>center: " + vectorToString(gesture.center) + " mm, "
+ "<br>normal: " + vectorToString(gesture.normal, 2) + ", "
+ "<br>radius: " + gesture.radius.toFixed(1) + " mm, "
+ "<br>progress: " + gesture.progress.toFixed(2) + " rotations"
+ "<br>";
break;
case "swipe":
//Classify swipe as either horizontal or vertical
var isHorizontal = Math.abs(gesture.direction[0]) > Math.abs(gesture.direction[1]);
//Classify as right-left or up-down
if(isHorizontal){
if(gesture.direction[0] > 0){
swipeDirection = "right";
} else {
swipeDirection = "left";
}
} else { //vertical
if(gesture.direction[1] > 0){
swipeDirection = "up";
} else {
swipeDirection = "down";
}
}
gestureString += "<br>ID: " + gesture.id + "<br>type: " + gesture.type + ", "
+ "<br>direction " + swipeDirection
+ "<br>gesture.direction vector: " + vectorToString(gesture.direction, 2) + ", "
+ "<br>";
break;
}
}
}
gestureOutput.innerHTML = gestureString + gestureOutput.innerHTML;
})
function vectorToString(vector, digits) {
if (typeof digits === "undefined") {
digits = 1;
}
return "(" + vector[0].toFixed(digits) + ", "
+ vector[1].toFixed(digits) + ", "
+ vector[2].toFixed(digits) + ")";
}
To use this, put it somewhere it will be executed and include a element with the id gestureData in the HTML document body:
<div id="gestureData"></div>

A friend of mine made a library for exactly this purpose. It checks for swipes in 6 different directions and can tell which direction a circle gesture is going.
https://github.com/L1fescape/curtsy
His code should be easily readable too so if you want to see how he did things you can.

Related

Why is this javascript function executing more times per second than it's supposed to

I am working on a sort of clicker game where the user is able to buy upgrades. One such upgrade involves the user earning a certain amount of in-game currency per second, in this case 0.1. Unfortunately if the user decides to buy more than one of this upgrade it appears to rise exponentially. I feel like this might be because the setInterval() function is stacking each time, so that the first time it is 0.1 then the next its 0.1 + 0.2 so 0.3, then 0.3 + 0.2 + 0.1 so 0.6 and so on.
upgradePerSec1.onclick = function() {
if (presents >= cost1) {
presents -= cost1;
upgrade1Amount += 1;
totalPresentsSpent += cost1;
cost1 = Math.ceil(cost1Base *= 1.03 ** upgrade1Amount);
perSec += 0.1;
displayScore.innerHTML = format(presents) + " Presents delivered.";
cost1Disp.innerHTML = "<hr>Cost: " + format(cost1);
title.innerHTML = format(presents) + " Presents";
perSecDisp.innerHTML = formatPerSec(perSec) + " presents /s";
totalPresentsSpentDisp.innerHTML = format(totalPresentsSpent) + " Total presents spent";
setInterval(increment1, 1000);
} else {
alert("You don't have enough presents! Still need: " + format(cost1 - presents));
}
}
function increment1() {
presents += perSec;
totalPresents += perSec;
displayScore.innerHTML = format(presents) + " Presents delivered.";
totalPresentsDisp.innerHTML = format(totalPresents) + " Total presents delivered";
title.innerHTML = format(presents) + " Presents";
}
Here is some clarification for this code:
upgradePerSec1 = HTML button element
cost1 = the cost of this upgrade
perSec = variable to store the amount of "presents" per second
displayScore = an HTML label element
cost1Disp = an HTML label element
title = the browser tab title
format() = a function to format large numbers by adding in commas
totalPresents = the total presents without taking away costs (used for a statistics section)
I have tried replacing the perSec variable with just the number(obviously did not work) I have tried making the timing also rise but could not get the correct timing. Ive also searched many places on the web and could not find any helpful results. I saw one on stack overlfow but it did not apply to me.
You're right, the setInterval calls are stacking. To fix the issue, you should make sure you only call setInterval() once (e.g. by adding an if statement before that line checking if perSec === 0).
e.g.
upgradePerSec1.onclick = function() {
if (presents >= cost1) {
if (perSec === 0) {
setInterval(increment1, 1000);
}
presents -= cost1;
upgrade1Amount += 1;
totalPresentsSpent += cost1;
cost1 = Math.ceil(cost1Base *= 1.03 ** upgrade1Amount);
perSec += 0.1;
displayScore.innerHTML = format(presents) + " Presents delivered.";
cost1Disp.innerHTML = "<hr>Cost: " + format(cost1);
title.innerHTML = format(presents) + " Presents";
perSecDisp.innerHTML = formatPerSec(perSec) + " presents /s";
totalPresentsSpentDisp.innerHTML = format(totalPresentsSpent) + " Total presents spent";
} else {
alert("You don't have enough presents! Still need: " + format(cost1 - presents));
}
}
function increment1() {
presents += perSec;
totalPresents += perSec;
displayScore.innerHTML = format(presents) + " Presents delivered.";
totalPresentsDisp.innerHTML = format(totalPresents) + " Total presents delivered";
title.innerHTML = format(presents) + " Presents";
}

How to make clickable line in JQuery Flot?

I am using flot to make line charts. One of the functionality I am trying to implement is highting the line (including points on the line and its corresponding legend), if the user clicks on the line, cancel the highlighting if the user clicks anywhere else on the chart.
Tried 'plotclick' event, but it requires clicking on points. I need the ability to get the series when clicking on the line as well.
Hopefully, there is a way to do that.
You have to manually search for the nearest point on the line and then calculate the distance with something like this:
$('#placeholder').on('plotclick', function(event, pos, item) {
$('#output').empty();
if (item) { // clicked on point
$('#output').text('series: ' + item.series.label + ' - datapoint: ' + item.dataIndex);
return;
}
else { // search for line
for (var i = 1; i < data.length; i++) {
if (data[i-1][0] <= pos.x && pos.x < data[i][0]) {
var lineX = (pos.x - data[i-1][0]) / (data[i][0] - data[i-1][0]);
var lineY = data[i-1][1] + lineX * (data[i][1] - data[i-1][1]);
if (Math.abs(pos.y - lineY) < maxDistance) {
$('#output').html('between datapoints ' + (i-1) + ' and ' + i + '<br />'
+ 'distance from line: ' + Math.abs(pos.y - lineY).toFixed(3));
}
return;
}
}
}
});
See this fiddle for a full example. If you have multiple data series you can search for the nearest point on each line and then calculate the nearest line.

I'd like to make my program re-run the beginning, kind of like a loop javascript

I'm making a chopsticks game, and this is my first app I'm making (really new to javascript) and I want it to restart whenever it reaches a certain point until either both the enemy's or your hands have 5 chopsticks. Here's my code:
var nocLeft = 1;
var nocRight = 1;
var handChoice = prompt("You now have " + nocLeft + " chopstick(s) on your left hand, and " + nocRight+ " chopstick(s) on your right hand, which hand do you want to use?").toLowerCase();
if (handChoice === right){
var ehc = prompt("Which hand are you attacking? The enemy's left hand has " + noceLeft + ", and their right hand has " + noceRight + " chopsticks.").toLowerCase();
switch(ehc) {
case 'right':
console.log("You chose the right hand!");
break;
case 'left':
console.log("You chose the right hand!");
break;
default:
console.log("please answer with 'left' or 'right', thanks!");
}
}
else if (handChoice === left){
var ehc = prompt("Which hand are you attacking? The enemy's left hand has " + noceLeft + ", and their right hand has " + noceRight + " chopsticks.").toLowerCase;
}
else {
}
Here's one way to do it:
var exit = false;
while (exit != true) {
// Your code
// Use the next line to get out of the loop
// exit = true;
}
The above method will exit the loop after it reaches the end. If you'd like to exit immediately you can use break.

On the server, player movement is not rendered

This code renders the motion of the player, changing the picture. Locally it works fine on the server change picture is not visible. But if you uncomment the alert ("right1"); and alert ("right2"); will be seen as an image change. How do I make the server was also seen pictures change?
var timer;
function GoRight(toPosition, level, mines) {
clearInterval(timer);
var left = $("#man").position().left;
var top = $("#man").position().top;
$("#man").attr('style', 'position:absolute;display:block;left:' + left + 'px;top:' + top + 'px;')
$("#man").attr("class", "");
var tempi = 0;
timer = setInterval(
function () {
if (left >= toPosition) {
left = toPosition;
$("#man").attr('style', 'position:absolute;display:block;left:' + left + 'px;top:' + top + 'px;')
clearInterval(timer);
$("#man").attr('src', '/content/games/kamikaze2/right0.gif');
return;
}
tempi += 8;
left += 8;
$("#man").attr('style', 'position:absolute;display:block;left:' + left + 'px;top:' + top + 'px;')
if (tempi % 16 == 0) {
// alert("right1");
$("#man").attr('src', '/content/games/kamikaze2/right1.gif');
}
else {
// alert("right2");
$("#man").attr('src', '/content/games/kamikaze2/right2.gif');
}
}, 70);
}
It's like a surprise, but it helped me a line after the if else
$("#man").attr('src');
but it works

cursor JAVASCRIPT needs to be adapted to wordpress DOCTYPE

if you are experienced with relations between javascript and doctype declaration , any help would be appreciated. i use wordpress and i am trying to include cursor script into a page. the script works without default wordpress doctype, with it - it does not. any suggestions how to make the cursor script work, please?
HTML doctype declaration for my WordPress:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Code for cursor:
<STYLE type="text/css">
<!--
.kisser {
position:absolute;
top:0;
left:0;
visibility:hidden;
}
-->
</STYLE>
<SCRIPT language="JavaScript1.2" type="text/JavaScript">
<!-- cloak
//Kissing trail
//Visit http://www.rainbow.arch.scriptmania.com for this script
kisserCount = 15 //maximum number of images on screen at one time
curKisser = 0 //the last image DIV to be displayed (used for timer)
kissDelay = 1200 //duration images stay on screen (in milliseconds)
kissSpacer = 30 //distance to move mouse b4 next heart appears
theimage = "cur.png" //the 1st image to be displayed
theimage2 = "small_heart.gif" //the 2nd image to be displayed
//Browser checking and syntax variables
var docLayers = (document.layers) ? true:false;
var docId = (document.getElementById) ? true:false;
var docAll = (document.all) ? true:false;
var docbitK = (docLayers) ? "document.layers['":(docId) ? "document.getElementById('":(docAll) ? "document.all['":"document."
var docbitendK = (docLayers) ? "']":(docId) ? "')":(docAll) ? "']":""
var stylebitK = (docLayers) ? "":".style"
var showbitK = (docLayers) ? "show":"visible"
var hidebitK = (docLayers) ? "hide":"hidden"
var ns6=document.getElementById&&!document.all
//Variables used in script
var posX, posY, lastX, lastY, kisserCount, curKisser, kissDelay, kissSpacer, theimage
lastX = 0
lastY = 0
//Collection of functions to get mouse position and place the images
function doKisser(e) {
posX = getMouseXPos(e)
posY = getMouseYPos(e)
if (posX>(lastX+kissSpacer)||posX<(lastX-kissSpacer)||posY>(lastY+kissSpacer)||posY<(lastY-kissSpacer)) {
showKisser(posX,posY)
lastX = posX
lastY = posY
}
}
// Get the horizontal position of the mouse
function getMouseXPos(e) {
if (document.layers||ns6) {
return parseInt(e.pageX+10)
} else {
return (parseInt(event.clientX+10) + parseInt(document.body.scrollLeft))
}
}
// Get the vartical position of the mouse
function getMouseYPos(e) {
if (document.layers||ns6) {
return parseInt(e.pageY)
} else {
return (parseInt(event.clientY) + parseInt(document.body.scrollTop))
}
}
//Place the image and start timer so that it disappears after a period of time
function showKisser(x,y) {
var processedx=ns6? Math.min(x,window.innerWidth-75) : docAll? Math.min(x,document.body.clientWidth-55) : x
if (curKisser >= kisserCount) {curKisser = 0}
eval(docbitK + "kisser" + curKisser + docbitendK + stylebitK + ".left = " + processedx)
eval(docbitK + "kisser" + curKisser + docbitendK + stylebitK + ".top = " + y)
eval(docbitK + "kisser" + curKisser + docbitendK + stylebitK + ".visibility = '" + showbitK + "'")
if (eval("typeof(kissDelay" + curKisser + ")")=="number") {
eval("clearTimeout(kissDelay" + curKisser + ")")
}
eval("kissDelay" + curKisser + " = setTimeout('hideKisser(" + curKisser + ")',kissDelay)")
curKisser += 1
}
//Make the image disappear
function hideKisser(knum) {
eval(docbitK + "kisser" + knum + docbitendK + stylebitK + ".visibility = '" + hidebitK + "'")
}
function kissbegin(){
//Let the browser know when the mouse moves
if (docLayers) {
document.captureEvents(Event.MOUSEMOVE)
document.onMouseMove = doKisser
} else {
document.onmousemove = doKisser
}
}
window.onload=kissbegin
// decloak -->
</SCRIPT>
<!--Simply copy and paste just before </BODY> section of your page.-->
<SCRIPT language="JavaScript" type="text/JavaScript">
<!-- cloak
// Add all DIV's of hearts
if (document.all||document.getElementById||document.layers){
for (k=0;k<kisserCount;k=k+2) {
document.write('<div id="kisser' + k + '" class="kisser"><img src="' + theimage + '" alt="" border="0"></div>\n')
document.write('<div id="kisser' + (k+1) + '" class="kisser"><img src="' + theimage2 + '" alt="" border="0"></div>\n')
}
}
// decloak -->
</SCRIPT>
The script is riddled with very old browser detection code, this could cause it to break in 'newer' browsers with a stricter DOCTYPE.
Try to remove the 'language="JavaScript1.2"' in the script tag. If that doesn't work you'd have to rewrite the browser detection.
The actual script isn't very complicated though so perhaps you could find parts elsewhere and combine them.
You need to do two things:
Hide the cursor (which is done with CSS)
Fetch the mouse position and place your own cursor there (typically an image). For this you will need a script that fetch the mouse position.
Shouldn't be too hard :)

Categories