Leap Motion Controllerが届いたので、手っ取り早く作れるJavaScriptで作ってみました(SAOの旬は過ぎてるかもだけど)。Exampleがcanvasをいじるものばかりだったので、DOMを操作するとどうなるもんかと思い、試してみました。
※ SAOを知らないかたはこちら
IMG 0700 from hiroki_yo on Vimeo.
DEMOサイトはこちら(※Chromeのみです)
「Touchless」という、マウスポインタをLMCで動かすアプリがあるのですが、leap.jsを読み込んだサイトでは何故かポインタが動きません。マウスポインタはTouchlessにまかせて、ジェスチャだけをleap.jsで取得してみよう、という目論見だったのですが頓挫しました。
しょうがないので、DOMを操作してポインタ代わりにし、当たり判定でイベントをつけることにしてみました。
Leap.loopの中で、取得したいジェスチャの分岐を書くだけです。
var motionObj = {}; Leap.loop({enableGestures: true}, function(frame){ // 指座標取得、当たり判定の処理 motionObj.setPointer(frame); // ジェスチャ判定 if(frame.gestures.length) { for(var i=0, len=frame.gestures.length; i<len; i++){ switch (frame.gestures[i].type) { case "swipe": motionObj.swipeAction(i,frame); break; case "circle": motionObj.circleAction(i,frame); break; case "keyTap": break; case "screenTap": motionObj.screenTapAction(i,frame); break; default: break; } } } });
上記の処理に加えて、指の座標を取得て当たり判定を行う処理を書いています。また今回のDEMOは、指1本で使うことを前提に作っています。
スワイプのジェスチャはこんな感じにしています。
// Gestures : swipe motionObj.swipeAction = function(i,frame){ if(frame.pointables.length < 1) return false; if(frame.gestures[i].state == "start") { // スワイプ開始 } else if (frame.gestures[i].state == "update") { // スワイプ中 if(!frame.pointables[0]) return false; if(frame.fingers[i].tipVelocity[1] < 500) { // 上から下にスワイプで、メニューボタン表示の処理 } else if(frame.fingers[i].tipVelocity[1] > 500) { // 下から上にスワイプで、メニューボタン非表示の処理 } } else if (frame.gestures[i].state == "stop"){ // スワイプ停止 } };
frame.fingers[i].tipVelocity[1] で、Y軸方向に一定以上の速さで動かした時のみイベントが起こるようになっている、はず(たぶん)。
範囲の決まっているオブジェクトに対して、ピンポイントにタップするのは難しいです。訓練してどうにかなるものではないと感じました。
なので今回はキータップ/スクリーンタップは使用せず、一定時間のタップ(150ms以上同じオブジェクトで当たり判定)で、イベントが起こるようにしています。
マウスポインタを動かせれば当たり判定処理なんか書かなくても済むのに・・・何か方法が無いか探し中です。
canvasをいじるのではなく、デザイナーさんがもっと気軽に実装できるようにならないと、WEBでは広まらないんじゃないかなぁと。今回はポインタの座標でイベントが起こるものになっているので、もっとジェスチャを使ってWEBサイトを見れるようなると楽しくなるだろうなぁ。
こちらからダウンロードできます。
http://darkblackswords.deviantart.com/art/Sword-Art-Online-Font-342305125
下記のツイートのリンク先にあるブロック崩しゲームでは、Touchlessでポインタを動かしつつ、webサイト上でもジェスチャを取得できています。WebSocketから取得した生のデータを処理すれば目論見通りに動くのかも?
[Leap] leap.js を使わず直接 WebSocket から受け取る ブロック崩し のサンプルなど。git http://t.co/6EMelOJiME 実際に置いてみた http://t.co/xfktmrHXOu
— 高橋登史朗 ( ToshiroT ) (@toshirot) August 3, 2013