【小ネタ】ブラウザで PS4用コントローラー「DUALSHOCK 4」を扱う下準備： WebHID API と WebHID-DS4

## はじめに
今まで、ブラウザで PS4用コントローラー「DUALSHOCK 4」を扱える API を試したり、記事を書いたりしたことがありました。

以下は 1年以上前の話になってはしまいますが、「DUALSHOCK 4」をブラウザで扱うというのを「Gamepad API」「WebHID API」でやってみていた話の記事です。

●【完走賞ゲット-10】gamecontroller.js を使って DualShock 4 を JavaScript で扱う - Qiita
　https://qiita.com/youtoy/items/87c1c37b51ae9ef4ab4d

●【完走賞ゲット-6】「WebHID DualShock 4 Demo」というサイトを軽く試してみる - Qiita
　https://qiita.com/youtoy/items/468454fe968ff3632511

### 久しぶりに「Gamepad API」「WebHID API」を扱う
最近、Nintendo Switch の Joy-Con と「WebHID API」を組み合わせた話に手をつけたのがあり、ふと「DUALSHOCK 4」との組み合わせもやろうと思ったのが、今回の記事を書いたきっかけです。

●Joy-Con などをブラウザで使える API 2つの情報をまとめて見てみる： Gamepad API と WebHID API - Qiita
　https://qiita.com/youtoy/items/109d1564ee2ff4bd463f

記事を書いた後には、以下のようなお試しをしてみたりも。

https://twitter.com/youtoy/status/1766882918868337070

https://twitter.com/youtoy/status/1766487478176030897

## 「DUALSHOCK 4」＋「WebHID API」
今回、「DUALSHOCK 4」＋「WebHID API」を試すにあたり、既存のライブラリを使ったやり方で進めようと思いました。

そのための情報を少しピックアップしてみます。

### WebHID-DS4
おそらく有名どころの 1つは、以下の「WebHID-DS4」です。

●TheBITLINK/WebHID-DS4: High Level API for DualShock 4 controllers powered by WebHID
　https://github.com/TheBITLINK/WebHID-DS4?tab=readme-ov-file

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ac2cb898-e843-55c7-f83c-6b62e0001adb.png)

最終更新が 3年前くらいなのが少し気になりますが、以下の機能を扱えるとのことで、「DUALSHOCK 4」＋「WebHID API」のお試しが楽になりそうです。

- Supported Features
   - USB and Bluetooth connectivity
   - Gyro & Accelerometer data
   - Touchpad Input
   - Buttons & Analogs
   - Lightbar RGB values
   - Rumble motors

公式サンプルを見ると、以下の内容が書かれており、上記の機能の中で「USB and Bluetooth connectivity」「Buttons & Analogs（一部のみ）」「Lightbar RGB values」あたりの使い方が分かりそうでした。

```javascript
import { DualShock4 } from 'webhid-ds4'

// The WebHID device can only be requested upon user interaction
document.getElementById('connectButton').addEventListener('click', async () => {
  const DS4 = new DualShock4()
  // This will request the WebHID device and initialize the controller
  await DS4.init()
  // Define a custom lightbar color
  await DS4.lightbar.setColorRGB(170, 255, 0)
  // The state object is updated periodically with the current controller state
  function logInputs () {
    requestAnimationFrame(logInputs)
    document.getElementById('triangle').innerText = `Triangle Button: ${DS4.state.buttons.triangle}`
    document.getElementById('circle').innerText = `Circle Button: ${DS4.state.buttons.circle}`
    document.getElementById('cross').innerText = `Cross Button: ${DS4.state.buttons.cross}`
    document.getElementById('square').innerText = `Square Button: ${DS4.state.buttons.square}`

    document.getElementById('leftStick').innerText = `Left Stick: ${DS4.state.axes.leftStickX}, ${DS4.state.axes.leftStickY}`
    document.getElementById('rightStick').innerText = `Right Stick: ${DS4.state.axes.rightStickX}, ${DS4.state.axes.rightStickY}`
  }
  logInputs()
})
```

それ以外に、以下の使い方も情報を見ておきたいところです。

- Gyro & Accelerometer data
- Touchpad Input
- Buttons & Analogs
- Rumble motors

それについて、関連するページを見ていくと、以下のドキュメントに情報がありそうでした。

●webhid-ds4
　https://thebitlink.github.io/WebHID-DS4/api/#usage-example

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6802e3c1-b1cf-fae2-1862-69b75073ee86.png)

別途、以下のページを見つつ、実際の実装をやっていこうと思います。

●DualShock4AnalogState | webhid-ds4
　https://thebitlink.github.io/WebHID-DS4/api/interfaces/dualshock4analogstate.html

●DualShock4Touchpad | webhid-ds4
　https://thebitlink.github.io/WebHID-DS4/api/interfaces/dualshock4touchpad.html
●DualShock4TouchpadTouch | webhid-ds4
　https://thebitlink.github.io/WebHID-DS4/api/interfaces/dualshock4touchpadtouch.html

●DualShock4ButtonState | webhid-ds4
　https://thebitlink.github.io/WebHID-DS4/api/interfaces/dualshock4buttonstate.html

●DualShock4Rumble | webhid-ds4
　https://thebitlink.github.io/WebHID-DS4/api/classes/dualshock4rumble.html


●DualShock4State | webhid-ds4
　https://thebitlink.github.io/WebHID-DS4/api/interfaces/dualshock4state.html

## 【追記】 簡単なお試しをやった時の様子

<iframe width="560" height="315" src="https://www.youtube.com/embed/RurUw4GiHiE?si=GYNypDUFVCkJItIz" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>