JavaScriptでLeapMotionアプリを作る方法 このエントリをはてなブックマークに登録

2013年07月26日

takurutakuru

こんにちは。クレイの浅海です。
いま話題のLeapMotionとJavascriptを使って、空中でピアノを演奏できるアプリを作りました。

まだLeapMotionを初めて数日なので勘違いしている部分もあるかもしれませんが、JavaScriptでLeapMotion対応アプリをどのように作るのかについて、気づいたことを紹介します。

目次

デモ

まずは実際に動かしている動画を御覧ください。
空中に手をかざすだけで、ピアノを演奏することができます。
音の再生にはMIDI.jsを使用しています。

※ 手を3Dで表示している部分は、LeapMotion標準のビジュアライザです。自分が作った部分はピアノの方です。

指一本で弾くのがおすすめです。

頑張れば和音も弾けます。ドミソー♪

黒鍵も弾けます。指がツル・・。

LMC(LeapMotionController)を持っている方は以下のページで試すことができます。(Chrome推奨)
http://kray.jp/projects/leap-motion-piano/index.html

leap.jsの用意

ピアノアプリの作り方を紹介するのは音楽知識も多く必要になってくるので、本記事ではleap.jsの基本的な使い方を書いていきます。

JavaScriptを使ってブラウザで動かせるLeapMotionアプリの作成には、leap.jsというものが必要なので、下記のリポジトリから持ってきます。

https://github.com/leapmotion/leapjs

そして、HTMLファイルを用意しleap.jsを読み込むだけで、LMCへの入力をブラウザのJavaScriptで扱えるようになります。
これでLMCとブラウザのJavaScriptが連携できることが不思議でしたが、どうやらLeapMotionがWebSocketサーバを立てているらしく、leap.jsはそのサーバと通信をして情報を取っているようです。
故に、WebSocket未対応のブラウザでは動きません。

イベントループ

leap.js を読み込んでいれば、Leapオブジェクトを使うことができます。
Leap.loopメソッドにフレーム毎のコールバックを登録することにより、フレーム毎の処理を記述することができます。
当然、1秒間に何十回も呼ばれる部分なので、コールバック内部に記述する処理のパフォーマンスには注意したほうが良いです。

Leap.loop({enableGestures: true}, function(frame){
  // フレーム毎の処理
});

loopの第一引数はnullでも良いですが、タップやスワイプなどのジェスチャ操作を有効にするために {enableGestures: true}を渡しています。

Frameオブジェクト

loopのコールバック関数に出てくるframeはLeap.Frameのインスタンスです。手指の座標、動き、角度など、全ての情報が詰まっています。
ここから欲しい情報をひっぱてきて使うだけなので簡単です。

いくつか例を挙げて説明します。

frame.fingers

これには現在LMCが認識している指の情報が入っています。
fingers自体は配列になっており、その中の指情報を見てみると

frame.fingers: [
  {
    id: 53, // 固有ID
    handId: 99 // 属している手のID
    direction: [-0.11, 0.17, -0.97], // 方向 x,y,z
    tipPosition: [30.62, 223.425, -56.18], // 位置 x,y,z
    tipVelocity: [-327.78, 108.69, 446.51], // 速度 x,y,z
/*    ・
      ・
      ・    */

  }
]

などなど、使えそうな情報が入っています。

冒頭で紹介したピアノでは、ここで取得できるtipVelocityを利用して、早い速度の時は大きい音を出すという細工をしています。

frame.hands

LeapMotionが認識している手の情報です。
handsの中身を見てみると以下のようになっています。

frame.hands: [
  {
    id: 99,
    direction: [-0.77, 0.28, -0.57],
    fingers: [], // 指情報の配列
    palmPosition: [41.85, 153.08, 62.08],
    palmVelocity: [56.41, 11.67, 27.20],
    sphereCenter: [30.70, 128.83, 34.09],
    sphereRadius: 74.14,
/*    ・
      ・
      ・    */

  }
]

指情報には無い情報として、sphereCenter,shpereRadiusというものがあり、これは手のひらにフィットしている球があるとしたときの中心座標や半径になっています。
面白そうな情報なのですが、ピアノでは特に使っていません。

frame.gestures

Leap.loopメソッドに渡したenableGesturesオプションにtrueを指定すると、ジェスチャに対応した動作を行ったフレーム内でそのジェスチャの情報を取得することができるようになります。

ジェスチャオブジェクトによって、持っているプロパティがバラバラですが、オブジェクトがどのジェスチャに対応しているかどうかはtypeプロパティを参照すればわかります。
現在用意されているジェスチャとしては、

  • circle
  • swipe
  • keyTap
  • screenTap

の4つのtypeがあるようです。

また、stateプロパティというものもあり、これはジェスチャの開始、途中、終了に対応した文字列がはいっています。
それぞれ、

start
ジェスチャ開始
update
ジェスチャの途中
stop
ジェスチャ終了

となっています。

circle

指でぐるぐるぐるぐる円を描いているとcircleジェスチャと認識されます。

取得できる情報には以下のようなものがあります。

{
  center: [-3.62, 277,22, 70.53],
  radius: 45.13,
  progress: 0.82,
/*  ・
    ・
    ・   */

}

そのままですが、centerは円の中心座標、radiusは半径です。
冒頭のピアノでcircleジェスチャを行うと、「きらきら星変奏曲」の一部が自動で演奏されます。

swipe

スマホやタブレット端末でスクロールをする時のように、手をサッと動かすとSwipeになります。

{
  direction: [-0.94, -0.02, 0.34],
  position: [-115.39, 172.57, 88.63],
  speed: 1703.21,
  startPosition: [29.63, 176.35, 39.95],
/*  ・
    ・
    ・   */

}

swipeとして重要なのはやはりdirectionだと思います。スワイプしている方向がわからなければしょうがないので。。
ほかにも、speedや、startPositionなど、便利そうな情報が入っています。

ピアノでは、グリッサンドの実装にswipeを使ったりもしていましたが、とっても弾き難いのでやめました。

keyTap

スマホやタブレット端末での画面タップに似ていますが、正しく認識されるためにはコツが必要ようで、すこし難しいです。
コツとしては、これぐらい大げさにやることだと思います。

以下のような情報取れます。

{
  direction: [-0.07, -0.91, -0.40],
  position: [27.82, 173.36, 72.59],
/*  ・
    ・
    ・   */

}

ピアノを作り始めた時の打鍵の実装にはkeyTapを使っていましたが、あまりにも弾き難くなるのでやめました。
今はfingerのtipPositionを見て、ある領域に入った時に音を鳴らしています。

screenTap

keyTapの奥方向バージョンです。
まったくコツがつかめず、個人的にはかなり難しかったです。
ペンなどを使うとやりやすいかもしれません。

これもとくに目新しい情報はありません。

{
  direction: [0.26, -0.02, -0.96],
  position: [-32.77, 293.252, -9.72],
/*  ・
    ・
    ・   */

}

以上のようにLeapMotionのプログラミングはframeに入っている情報をどう扱うかに限ります。
LMCは入力装置なので当然ですね。

感想

メインのコードも短く、イベントループ内でFrameオブジェクトから必要な情報を選んで使用するだけなので、非常に簡単です。
エンターテインメント分野だけでなく、普通のwebサイトに組み込むことも現実的なのではないかと思いました。
具体的には、「既存のwebサイトにLeapMotionのスワイプでページ送りする機能を組み込む」なんてことをしたいときには、JavaScriptを数行書くだけで出来てしまいます。

実際の利用やデバッグで、LMCの操作は腕がかなり疲れるのではないかと思っていましたが、人間慣れるもんですね。
たしかに初日はかなり疲れましたが、2日目からはまったく疲れは感じませんでした。

最後に、今回作ったピアノを弾きこなす人の出現を待っています! よろしくお願いします。

デモのコード

Githubにピアノのコードを公開しました。
leap.jsやMIDI.jsを参考URLから取得して、適切なディレクトリに配置すると動きます。

https://github.com/ttakuru88/leap-motion-piano

関連記事

クレイについてもっと知りたい方は…

  1. クレイの3つの強みを見てみる。
  2. WEBシステムのことなら何でもご相談ください。

「いいね!」で応援よろしくお願いします!

このエントリーに対するコメント

  1. 買ってみたものの、使い方がよくわからず挫折しそうになっていたところでした。サンプルのページでピアノが弾けることができて、やる気を取り戻せました。
    まだ内容確認していませんがコードが置いてあるのも大変助かります。ありがとうございました。

    2013年09月08日, 3:55 PM

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


トラックバック
  1. ハードウェア・スタートアップが避けるべき12の「○○ウェア」 | TechCrunch Japan2014/04/10, 8:01 AM

    […] 例えば、Google Glassはフューチャーウェアぽくあり、ボアウェアでもあるかもしれない。先日10%の従業員をレイオフしたLeap Motionも、ボアウェアとフューチャーウェアの要素が少しあるとぼくは思う。いや、ぼくがLeap Motionでピアノを弾くハックを楽しめないだけなのかもしれないけど、開発しないなら30分で飽きるよね、Leap Motionって。ボアウェアは、多かれ少なかれ現在ウェアラブル・デバイス全般に当てはまる面がありそうだ。最初は嬉しくて身に着けるけど結局実用的価値が低くて飽きたら着けないという。 […]

we use!!Ruby on RailsAmazon Web Services

このページの先頭へ