p5.js を用いた JavaScript のプログラムで Leap Motion の情報を取得する（leap.js ではなく WebSocket を利用）

以下の記事の続きです。

●バニラな JavaScript や p5.js で Leap Motion の情報を取得する（leap.js ではなく WebSocket を利用） - Qiita
　https://qiita.com/youtoy/items/efc4da1feee26186f565

上記の記事では、単純に「 `ws://localhost:6437/` 」に接続して、WebSocket で情報を取得できたことだけ確認していました。
今回は、手を認識した情報を取得するところへ進んでいきます。

## 検証方法
今回、前回の 2パターンの検証方法のうちの「p5.js を用いたほう（さらに、p5.js Web Editor上でプログラムを実行する形）」で進めていきます。
leap.js は用いず、ブラウザが外部ライブラリなしに扱える WebSocket を使っているので、HTML に関して p5.js Web Editor のデフォルト状態から何も変更は加えていません（デフォルトで読み込み設定がされているライブラリ以外に、別途、ライブラリの読み込みを追加するようなことは必要ありません）。

## 最小限のプログラムで手の情報を取得してみる
以下のドキュメントを見つつ、プログラムを削ったりしつつで、最小限のプログラムでの情報取得を行ってみます。

●WebSocket Communication — Leap Motion JavaScript SDK v3.2 Beta documentation
　https://developer-archive.leapmotion.com/documentation/javascript/supplements/Leap_JSON.html

プログラムをいろいろ組み替えてみつつ、前回の記事の最後に出ていたログ出力を見つつ、以下のプログラムで各種情報が含まれていそうな部分をログに出してみました。

```javascript
const WSURL = "ws://localhost:6437";
let ws, eventLeapMotion;

function setup() {
  createCanvas(500, 500);

  let ws = new WebSocket(WSURL);
  ws.onopen = function (event) {
    console.log("open!");
  };
  ws.onmessage = function (event) {
    eventLeapMotion = event;
  };
}

function draw() {
  background(220);

  if (eventLeapMotion) {
    console.log(eventLeapMotion.data);
  }
}
```

`eventLeapMotion.data` の部分のログ出力はオブジェクトになっているのを期待していたのですが、どうやら以下のように文字列になったもののようでした。
![eventLeapMotion.data の出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b17e8ef5-2b00-6063-873d-4a4dafb4db66.jpeg)
また、オブジェクトに変換していれば eventLeapMotion.data.hands で手の情報がとれそうです（上記のログ出力時は、Leap Motion の上に手をかざしていなかったため、hands の中身は空の配列ですが...）。

`JSON.parse()` で文字列をオブジェクトに変換しつつ、hands の中身のデータを取得するようにしてみます。
この時、hands の中が空ではない時だけ、hands の中を出力するようにしてみました。

```javascript
const WSURL = "ws://localhost:6437";
let ws, eventLeapMotion;

function setup() {
  createCanvas(500, 500);

  let ws = new WebSocket(WSURL);
  ws.onopen = function (event) {
    console.log("open!");
  };
  ws.onmessage = function (event) {
    eventLeapMotion = event;
  };
}

function draw() {
  background(220);

  if (eventLeapMotion) {
    const hands = JSON.parse(eventLeapMotion.data).hands;
    if (hands?.length) {
      console.log("手の情報を出力");
      for (hand of hands) {
        console.log(hand);
      }
    }
  }
}
```

そして、上記のログ出力を確認してみます。
両手をかざしたり、片手のみをかざしたりしてみたのですが、以下のように両手の情報が出たり（赤矢印で示した部分）、片手のみの情報が出たり（緑矢印で示した部分）という結果が得られているのが分かります。
![手の情報を出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/dd2aff2c-2557-e68e-09f2-2373bcbe692e.jpeg)

そして、オブジェクトの1階層下の部分を展開してみると、以下のようにいろいろとデータがとれていそうなことが確認できました。
![オブジェクトの1階層下の部分を展開](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c2ada05d-7074-0fae-0622-d47988bea71d.jpeg)

### 一部、情報が見つからない？
この中もいろいろ見ていっていたのですが、ドキュメントの以下にある情報の一部（例えば「`type`」）が見つからなかったりました。
![手に関する情報（公式ドキュメントの記載）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f328a28e-dd6c-2e56-576c-7e6e96f5275b.jpeg)

ドキュメントを調べていくと、この部分に書かれた、WebSocket経由で取得する情報のバージョン指定が絡んでいそうでした。
![WebSocket経由で取得する情報のバージョン指定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ad8a415b-881e-4eda-1777-c8b624dba1b9.jpeg)
赤線の部分を見ると、URL の最後に「v1.json」〜「v6.json」の何れかを明示的につけることで、サブプロトコルを指定できるという記載があります。そして、緑の線の部分を見ると、その指定を行わなかった場合は「v1.json」が選ばれるという記載もあります。

ドキュメントの下の方を見ると、以下の記載もあったため、どうやら「v6.json」を指定しないと取得できない情報があったということらしいです。
![バージョンの違い](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6a54121a-f65c-306b-5337-2c691cdf113e.jpeg)
せっかくなら、色々と情報を取得できたほうが便利そうなので、「v6.json」を使った情報取得を別途試せたらと思っています。