ゲームパッド

W3C作業草案

この文書についての詳細
このバージョン:
https://www.w3.org/TR/2025/WD-gamepad-20250710/
最新公開バージョン:
https://www.w3.org/TR/gamepad/
最新編集者草案:
https://w3c.github.io/gamepad/
履歴:
https://www.w3.org/standards/history/gamepad/
コミット履歴
テストスイート:
https://wpt.live/gamepad/
実装レポート:
https://wpt.fyi/results/gamepad
編集者:
Steve Agoston (Sony)
Matt Reynolds (Google)
以前の編集者:
James Hollyer (Google)
Brandon Jones (Google)
Scott Graham (Google)
Ted Mielczarek (Mozilla)
フィードバック:
GitHub w3c/gamepad (プルリクエスト, 新しい課題, 未解決の課題)
ブラウザーサポート:
caniuse.com

概要

Gamepad仕様は、ゲームパッドデバイスを表す 低水準インターフェイスを定義します。

この文書のステータス

この節は、この 文書の公開時点におけるステータスを説明します。現在のW3C 公開物の一覧およびこの技術報告書の最新版は、 W3C標準および草案 索引にあります。

これは進行中の作業です。

この文書は、Web Applications Working Groupにより、 勧告トラックを使用した 作業草案として公開されました。

作業草案としての公開は、 W3Cおよびそのメンバーによる承認を意味しません。

これは草案文書であり、いつでも他の文書によって更新、置換、または廃止される 可能性があります。この文書を、進行中の作業以外のものとして引用することは 不適切です。

この文書は、 W3C 特許 ポリシーの下で運営される グループによって作成されました。 W3Cは、 グループの成果物に関連して行われた 特許開示の公開一覧を 管理しています。そのページには、 特許を開示するための手順も含まれています。個人が、 必須クレームを含むと その個人が信じる特許について実際の知識を持つ場合、 W3C特許ポリシー第6節に従って その情報を開示しなければなりません。

この文書は、 2023年11月3日 W3Cプロセス文書により管理されます。

1. 導入

この節は非規範的です。

一部のユーザーエージェントには、 ゲームパッドデバイスが接続されています。これらのデバイスは、 ゲームアプリケーションへの入力、および「10 フィート」ユーザーインターフェイス(プレゼンテーション、メディアビューアー)に望ましく適しています。

現在、ゲームパッドを入力として使用する唯一の方法は、 マウスまたはキーボードイベントをエミュレートすることですが、これは情報を失わせ、 エミュレーションを実現するためにユーザーエージェントの外部にある 追加ソフトウェアを必要とします。

一方、ネイティブアプリケーションは、システムAPIを介して これらのデバイスにアクセスできます。

Gamepad APIは、Webアプリケーションがゲームパッドデータを直接扱えるようにする インターフェイスを指定することで、この問題に対する解決策を提供します。

2. 範囲

ゲームを制御するために設計された外部デバイスとのインターフェイスは、 完全に一般的な方法で取り組むと、 大規模で扱いにくいものになる可能性があります。この仕様では、 広く実装でき、幅広く有用な機能の有用なサブセットを提供するために、 範囲を狭めることを明示的に選択します。

具体的には、ゲームパッドをサポートするために必要な機能のみを サポートすることを選択します。ゲームパッドのサポートには、 ボタンと軸という2種類の入力が必要です。ボタンと軸はいずれもアナログ値として報告され、 ボタンは[0 .. 1]の範囲、軸は[-1 .. 1]の範囲です。

主な目的はゲームパッドデバイスのサポートですが、これら 2種類のアナログ入力をサポートすることで、現在のゲームシステムで一般的な他の類似デバイス、 すなわちジョイスティック、ステアリングホイール、 ペダル、加速度計などもサポートできます。そのため、「gamepad」という名称は、 この仕様が扱うデバイス全体の総称になろうとするものではなく、 例示的なものです。

この仕様では、モーションセンシング、深度センシング、映像解析、 ジェスチャー認識などを行う、ゲームの文脈で使用されることもある より複雑なデバイスのサポートを明示的に除外します。

3. モデル

gamepadは、入力コントロールおよび出力 コントロールの集合です。入力コントロールは、時間とともに更新され得る入力 値の集合を持ちます。入力コントロールには、 gamepadのボタン、トリガー、ジョイスティック、サムスティック、およびタッチ面が含まれます。 出力コントロールは、 gamepadの挙動を変更し、 gamepadを操作するユーザーへフィードバックを提供する機能です。 出力コントロールには、gamepadの触覚アクチュエーターが含まれます。 gamepadは、ユーザーエージェントがその入力コントロールの現在の状態を読み取れる場合、 利用可能です。 gamepad利用可能でない場合、 それは利用不能です。 入力コントロールおよび出力コントロールは、 gamepad利用可能である間は 変更できません。

ユーザーエージェントは、次の責任を負います:

gamepadは、gamepad 識別子文字列を持ちます。これは、 gamepadのブランドまたはスタイルを識別する、 人間が読める文字列です。内容はユーザーエージェントによって決定されます。

3.1 入力コントロールレイアウト

gamepadは、gamepad上の各入力コントロールの 位置、向き、および種類を説明する入力コントロールレイアウトを持つことがあります。 ユーザーエージェントは、 gamepad標準レイアウトに対応する時を認識する責任を負います。 これは、gamepadが、同じ標準レイアウトに対応する他のgamepadsと交換可能に使用できるようにする 入力 コントロールレイアウトを持つことを意味します。ユーザー エージェントは、その入力コントロールが、 標準レイアウトで説明される入力コントロールと おおよそ同じ相対位置および向きを持つ場合、そのレイアウトが標準レイアウトに 対応すると考えるべきです

ユーザーエージェントは通常、 gamepad入力コントロールレイアウトを 直接検査することはできず、レイアウトを決定するためにヒューリスティックを使用してもよいです。 ユーザーエージェントは、 gamepad標準レイアウトに 対応するかどうかを決定する際に、 デバイス識別子を考慮するべきです。システムが各入力コントロールにラベルを割り当て、 そのラベルが特定のレイアウトを示唆する場合、ユーザーエージェントは、 そのgamepadがそのレイアウトを持つと考えるべきです。 同じ入力コントロールを持つ 標準モデルとアクセシブルモデルが存在する場合、ユーザーエージェントは、 アクセシブルモデルが標準モデルと同じ入力コントロールレイアウトを持つと 考えるべきです

アクセシブルなゲームパッドモデルとは、製造元が 標準レイアウトを持つゲームパッドの差し替え用代替として提供することを意図した ゲームパッドです。たとえば、Xbox Adaptive Controllerおよび PlayStation Access Controllerはアクセシブルなゲームパッドモデルです。Xbox Wireless ControllerおよびDualSenseは、対応する標準 モデルです。

3.2 入力値

各入力コントロールは、関連付けられた1つ以上の入力値を持ちます。 これはコントロールの現在の状態を表す数値です。 入力値はいつでも更新され得ます。ユーザーエージェントは、 入力値が更新された時を検出する責任を負い、 更新と、更新された値が読み取られる時との間の遅延を最小化するよう努めるべきです

入力値を読み取ると、その論理値、 すなわち現在の状態のスケーリングされていない数値表現が返されます。入力値はまた、 範囲内の最小および最大の 論理値を定義する論理 最小値および論理 最大値も持ちます。

入力値は、表されるデータの種類を識別する32ビット値である HID usage 識別子を関連付けて持つことがあります。HID usageは 入力コントロールレイアウトを正確に 説明するものではありませんが、慣例上、類似したレイアウトを持つ多くの gamepadsは類似したusageを使用します。ユーザーエージェントは、 入力コントロールレイアウトを決定する際に、 HID usage識別子に関する慣例に依拠するべきです

3.3

gamepadaxis入力を持つことがあります。 は、 基準位置からのコントロールの現在の変位を表す 入力値です。

gamepadは、リストである axis listを持ちます。これは、 gamepadのすべての axis入力を、ユーザー エージェントによって決定される何らかの順序で含みます。

入力コントロールは、ユーザーが 入力コントロールとの相互作用を停止した時に、 axisを中心位置へ自動的に戻すよう設計されていることがあります。 その場合、axis優先軸 状態を持ちます。axis優先軸状態を持つ場合、 追加の入力値である中心 位置 値も持つことがあります。これはaxisが中心にある時の 論理値です。

3.4 ボタン

gamepadbutton入力を持つことがあります。 ボタンは、 押して有効化できる入力コントロールです。 gamepadは、 リストである button listを持ちます。これは、 gamepadのすべての button入力を、ユーザーエージェントによって決定される何らかの順序で 含みます。

入力コントロールは、ユーザーが 入力コントロールとの相互作用を停止した時に、 buttonを未押下状態へ自動的に戻すよう設計されていることがあります。 その場合、button優先 ボタン状態を持ちます。

buttonは、その buttonが有効化されている時を示すデジタルスイッチを持つことがあります。 その場合、buttonは、追加の 入力値であるデジタル ボタン値を持ちます。これは、buttonが有効化されている時はtrueであり、 そうでない場合はfalseです。

buttonは、そのbuttonが どの程度有効化されているかを報告できるアナログセンサーを持つことがあります。そうである場合、 そのbuttonは:

buttonはタッチを検出できることがあります。その場合、そのbuttonは、 追加の入力値であるボタン タッチ値を持ちます。 これは、buttonがタッチされている時はtrueであり、 そうでない場合はfalseです。

3.5 タッチ面

gamepadタッチ面を持つことがあります。 タッチ面 は、接触点を表す2D位置データを提供する入力コントロールです。 gamepadは、touch surface listを持ちます。 これは、リストであり、 gamepadタッチ面を含みます。このリストは、 gamepadの左側により近いタッチ面ほど、 リストの先頭に近く現れるように順序付けられます。

タッチ面は、 センサーによって現在検出されている接触点を表す、0個以上のタッチ点リストである アクティブ タッチ点リスト入力値を持ちます。 タッチ 点は、単一時点における単一の接触点を表します。 タッチ点は、 タッチ面の座標系内の位置を表す touch x座標および touch y 座標を持ちます。タッチ面gamepadの上面、下面、前面、または背面にある場合、 touch x座標は左右軸に沿って測定され、 それ以外の場合は上下軸に沿って測定されます。touch y 座標は直交軸に沿って測定されます。

タッチ面gamepadの左側または右側にある場合、 その寸法はいずれも水平軸とは揃いません。

タッチ面は、面の寸法入力値を持つことがあります。 面の 幅および面の 高さ入力値は、タッチ面の寸法であり、 touch x座標およびtouch y 座標と同じ単位です。タッチ面は、両方の寸法値を持つか、どちらも持たないかのいずれかです。

タッチ点は、新しい接触点である場合も、 以前の接触の継続である場合もあります。タッチ点は、ユーザーエージェントが、 それが以前のタッチ点の継続であり、以前の GamepadTouchによって表されたものだと識別する場合、 既存のアクティブ タッチ点の一部です。既存の アクティブタッチ点の一部であるタッチ点アクティブ タッチ点IDは、以前のGamepadTouchtouchIdです。

3.6 出力コントロール

gamepad触覚 アクチュエーターを持つことがあります。触覚 アクチュエーターは、ユーザーが感じられる方法でgamepadを 動かすことができる出力コントロールです。触覚アクチュエーターは、 ユーザーへフィードバックを提供する触覚効果を生成するために 使用できます。複数のアクチュエーターからの振動は、より複雑な効果を生成するために 組み合わされます。ユーザー エージェントは、 利用可能gamepads上で、 触覚アクチュエーター触覚効果の再生および停止を命令する責任を負います。

gamepadは、 振動 アクチュエーターを持つことがあります。これは、 触覚アクチュエーターであり、 gamepad全体を振動させる 触覚効果を再生できます。

触覚アクチュエーターは、 1つ以上のGamepadHapticEffectType 値を含むサポートされる 効果 種類リストを持ちます。これは、 gamepad利用可能である間は 変更できません。

4. Gamepadインターフェイス

このインターフェイスは、個々のゲームパッドデバイスを定義します。

WebIDL[Exposed=Window]
interface Gamepad {
  readonly attribute DOMString id;
  readonly attribute long index;
  readonly attribute boolean connected;
  readonly attribute DOMHighResTimeStamp timestamp;
  readonly attribute GamepadMappingType mapping;
  readonly attribute FrozenArray<double> axes;
  readonly attribute FrozenArray<GamepadButton> buttons;
  readonly attribute FrozenArray<GamepadTouch> touches;
  [SameObject] readonly attribute GamepadHapticActuator vibrationActuator;
};

システムと通信するために使用されるアルゴリズムは通常、 非同期に完了し、ゲームパッドタスクソースに作業をキューに入れます。

Gamepadのインスタンスは、次の表で説明される 内部スロットを用いて作成されます:

内部スロット 初期値 説明(非規範的)
[[connected]] false デバイスがシステムに接続されていることを示すフラグ
[[timestamp]] undefined このGamepadのデータが最後に更新された時刻
[[axes]] 空のsequence このデバイスによって公開される軸の現在の状態を表す sequencedouble
[[buttons]] 空のsequence このデバイスによって公開されるボタンの現在の状態を表す GamepadButtonオブジェクトの sequence
[[exposed]] false Gamepadオブジェクトが スクリプトに公開されたことを示すフラグ
[[axisMapping]] 空のordered map 未マップ軸インデックスから axes配列内のインデックスへのマッピング
[[axisMinimums]] 空のlist 各軸の最小論理値を含むlist
[[axisMaximums]] 空のlist 各軸の最大論理値を含むlist
[[buttonMapping]] 空のordered map 未マップボタンインデックスから buttons配列内のインデックスへのマッピング
[[buttonMinimums]] 空のlist 各ボタンの最小論理値を含むlist
[[buttonMaximums]] 空のlist 各ボタンの最大論理値を含むlist
[[touches]] 空のlist ユーザー生成のタッチがあれば、そのリストを保持します。ゲームパッドが タッチ面をサポートしていない場合、このリストは空のままです。
[[nextTouchId]] 0 次に入ってくるタッチに使用する touchId値。
[[vibrationActuator]] undefined ゲームパッド全体を振動させる触覚効果を生成できる GamepadHapticActuatorオブジェクト
id属性

ゲームパッドの識別文字列です。この文字列は、接続された ゲームパッドデバイスのブランドまたはスタイルを識別します。

id文字列の正確な形式は未指定のままです。 ユーザーエージェントは、 デバイスを一意に識別することなく製品を識別する文字列を選択することが 推奨されます。たとえば、USBゲームパッドは idVendorおよびidProduct値によって識別されることがあります。 シリアル番号やBluetoothデバイスアドレスのような一意の識別子は、 id文字列に含めてはなりません

index属性
Navigator内のゲームパッドのインデックスです。 複数のゲームパッドがユーザー エージェントに接続されている場合、インデックスはゼロから始まり、 先着順で割り当てられなければなりません。ゲームパッドが 切断された場合、以前に割り当てられたインデックスを、接続され続けている ゲームパッドに再割り当てしてはなりません。ただし、ゲームパッドが 切断され、その後、同じまたは異なるゲームパッドが接続された場合、 以前に使用された最小のインデックスが再利用されなければなりません
connected 属性

このオブジェクトによって表される物理デバイスが まだシステムに接続されているかどうかを示します。ゲームパッドが、 物理的に切断された、電源が切られた、またはその他の理由で 使用不能になったことにより利用不能になると、 connected属性は falseに設定されなければなりません

connected取得子の手順は次のとおりです:

  1. this.[[connected]]を返す。
timestamp 属性

timestampにより、作成者は、この ゲームパッドのaxesまたはbuttons属性が最後に更新された時刻を 判断できます。この値は、システムがデバイスから新しいボタンまたは軸入力 値を受信するたびに、現在の高分解能 時刻へ設定されなければなりません。ハードウェアからデータを受信していない場合、 timestampは、 Gamepadが最初にスクリプトへ 利用可能にされた時点の現在の高分解能 時刻なければなりません

警告

ユーザーエージェントは、 [HR-TIME]のクロック分解能の推奨に従い、 timestamp属性の最小分解能を 5マイクロ秒に設定するべきです

timestamp取得子の手順は次のとおりです:

  1. this.[[timestamp]]を返す。
mapping 属性

このデバイスで使用されているマッピングです。ユーザーエージェントが デバイスのレイアウトについて知識を持つ場合、対応するGamepadMappingType 値へmappingを設定することで、 マッピングが使用中であることを示すべきです

ゲームパッドデバイスのマッピングを選択するには、次の手順を実行します:

  1. ゲームパッドデバイスのボタンおよび軸レイアウトが Standard Gamepadレイアウトに対応する場合、 "standard"を返す。
  2. ""を返す。
axes属性

ゲームパッドのすべての軸の値の配列です。すべての軸値は、 [-1 .. 1]の範囲に線形正規化されなければなりません。 コントローラーが地面に垂直で、方向スティックが上を指している場合、 -1は「前方」または「左」に対応するべきであり、1は 「後方」または「右」に対応するべきです。2D 入力デバイスから得られる軸は、axes配列内で互いに隣接して現れ、X、 次にYの順になるべきです。要素0および1が通常、方向スティックの X軸およびY軸を表すように、軸は重要度の降順に現れることが 推奨されますユーザーエージェントが 異なる値(または異なる順序の値)を返す必要があるまで、 同じオブジェクトが返されなければなりません

axes取得子の手順は次のとおりです:

  1. this.[[axes]]を返す。
buttons 属性

ゲームパッドのすべてのボタンのボタン状態の配列です。 主ボタン、副ボタン、第3ボタンなどが buttons配列内の要素0、1、2、...として現れるように、 ボタンは重要度の降順に現れることが 推奨されますユーザーエージェントが 異なる値(または異なる順序の値)を返す必要があるまで、 同じオブジェクトが返されなければなりません

buttons取得子の手順は次のとおりです:

  1. this.[[buttons]]を返す。
touches 属性

すべてのタッチ面から生成されるGamepadTouchオブジェクトの listです。

touches取得子の手順は次のとおりです:

  1. this.[[touches]]を返す。
vibrationActuator属性

デバイスの主たる振動アクチュエーターを表す GamepadHapticActuatorオブジェクトです。

vibrationActuator取得子の手順は 次のとおりです:

  1. this.[[vibrationActuator]]を返す。

4.1 入力の受信

システムが新しいボタンまたは軸入力値を受信する時、 次の手順を実行します:

  1. gamepadを、新しいボタンまたは軸入力値を受信した デバイスを表すGamepad オブジェクトとする。
  2. gamepad関連する グローバルオブジェクトを用いて、gamepadについてゲームパッド状態を更新するため、 グローバルタスクをキューに入れる。 これはゲームパッドタスクソース上で行う。

gamepadについてゲームパッド状態を更新するには、 次の手順を実行します:

  1. nowを、gamepad関連する グローバルオブジェクトが与えられた現在の高分解能 時刻とする。
  2. gamepad.[[timestamp]]nowに設定する。
  3. gamepadについて軸をマップして正規化する手順を 実行する。
  4. gamepadについてボタンをマップして正規化する手順を 実行する。
  5. gamepadについてタッチを記録する手順を実行する。
  6. navigatorを、gamepad関連する グローバルオブジェクトNavigator オブジェクトとする。
  7. navigator.[[hasGamepadGesture]]falseであり、かつ gamepadゲームパッドユーザージェスチャーを含む場合:
    1. navigator.[[hasGamepadGesture]]trueに設定する。
    2. navigator.[[gamepads]]の各 connectedGamepadについて反復する:
      1. connectedGamepadnullでない場合:
        1. connectedGamepad.[[exposed]]trueに設定する。
        2. connectedGamepad.[[timestamp]]nowに設定する。
        3. documentを、gamepad関連する グローバルオブジェクト関連付けられた Documentとし、それ以外の場合は nullとする。
        4. documentnullではなく、かつ 完全に アクティブである場合、グローバルタスクをキューに入れる。 これはゲームパッドタスクソース上で行い、gamepad関連する グローバルオブジェクトに対して gamepadconnectedという名前のイベントを発火する。 その際、GamepadEventを用い、その gamepad 属性を connectedGamepadで初期化する。

gamepadについて軸を マップして正規化するには、次の手順を実行します:

  1. axisValuesを、gamepadによって表される デバイスの各軸入力について、最新の論理軸入力値を表すunsigned long値の listとする。
  2. maxRawAxisIndexを、axisValuesサイズ − 1とする。
  3. 0からmaxRawAxisIndexまでの範囲の各 rawAxisIndexについて反復する:
    1. mappedIndexgamepad.[[axisMapping]][rawAxisIndex]とする。
    2. logicalValueaxisValues[rawAxisIndex]とする。
    3. logicalMinimumgamepad.[[axisMinimums]][rawAxisIndex]とする。
    4. logicalMaximumgamepad.[[axisMaximums]][rawAxisIndex]とする。
    5. normalizedValueを、2 (logicalValuelogicalMinimum) / (logicalMaximumlogicalMinimum) − 1とする。
    6. gamepad.[[axes]][axisIndex]を normalizedValueに設定する。

gamepadについてボタンを マップして正規化するには、次の手順を実行します:

  1. buttonValuesを、gamepadによって表される デバイスの各ボタン入力について、最新の論理ボタン入力値を表す unsigned long値の listとする。
  2. maxRawButtonIndexを、 buttonValuesサイズ − 1とする。
  3. 0からmaxRawButtonIndexまでの範囲の各 rawButtonIndexについて反復する:
    1. mappedIndexgamepad.[[buttonMapping]][rawButtonIndex]とする。
    2. logicalValuebuttonValues[rawButtonIndex]とする。
    3. logicalMinimumgamepad.[[buttonMinimums]][rawButtonIndex]とする。
    4. logicalMaximumgamepad.[[buttonMaximums]][rawButtonIndex]とする。
    5. normalizedValueを、(logicalValuelogicalMinimum) / (logicalMaximumlogicalMinimum)とする。
    6. buttongamepad.[[buttons]][mappedIndex]とする。
    7. button.[[value]]normalizedValueに設定する。
    8. ボタンが純粋な押下状態または解放状態を示すデジタルスイッチを持つ場合、 ボタンが押されていればbutton.[[pressed]]trueに、押されていなければfalseに設定する。

      それ以外の場合、値がボタン押下しきい値を上回る場合は button.[[pressed]]trueに設定し、しきい値を上回らない場合はfalseに設定する。

    9. ボタンがタッチを検出できる場合、ボタンが現在タッチされていれば button.[[touched]]trueに設定する。

      それ以外の場合、button.[[touched]]button.[[pressed]]に設定する。

gamepadについてタッチを 記録するには、次の手順を実行します:

  1. Assert: Gamepad.[[touches]]空である
  2. gamepad上の各タッチ面について、タッチ面の列挙順に 次の手順を繰り返す:
    1. surfaceIdを現在の面の 列挙インデックスとする。
    2. タッチ面がデバイス単位で最大面寸法を公開する場合、 touch.surfaceDimensions を、width および height がデバイス単位でのタッチ面上の最大XおよびY 寸法に初期化されたDOMRectReadOnly に設定する。
    3. 現在のタッチ面について、gamepadによって報告される各アクティブタッチ点に対して、 次の手順を繰り返す。
      1. touchを、新しく作成された GamepadTouchオブジェクトとする。
      2. touch.surfaceIdsurfaceIdに設定する。
      3. タッチデータが、ユーザーエージェントによって追跡される 既存のアクティブタッチ点の一部である場合:
        1. touch.touchIdを、 そのアクティブタッチ点の touchIdに設定する。
        2. それ以外の場合、touch.touchIdgamepad.[[nextTouchId]]に設定し、 gamepad.[[nextTouchId]]を インクリメントする。
          : タッチ idはGamepadに相対的です

          Gamepadが複数のタッチ面を持つ場合、touch idは面をまたいで一意になります。

      4. touch.positionを、新しい DOMPointReadOnly に設定する。そのx は、デバイスタッチ面に相対的なデバイスX座標に初期化され、 左端の座標が-1、右端の座標が1となるよう[-1 .. 1]へ正規化される。 また、 y は、デバイスタッチ面に対して、上端の座標が-1、下端の座標が1となるよう [-1 .. 1]へ正規化されて初期化される。
        : 可能な実装( surfaceDimensionsが利用可能な場合)

        x = (2.0 * touchData.x / surfaceDimensions.width) - 1
        y = (2.0 * touchData.y / surfaceDimensions.height) - 1

      5. touchgamepad.[[touches]]追加する

4.2 Gamepadの構築

接続されたゲームパッドデバイスを表す新しい Gamepadは、 次の手順を実行することで構築されます:

  1. gamepadを、新しく作成されたGamepadインスタンスとする:
    1. gamepadid属性を、ゲームパッドの 識別文字列に初期化する。
    2. gamepadindex属性を、 gamepadについて未使用の ゲームパッドインデックスを選択する結果に初期化する。
    3. gamepadmapping属性を、 ゲームパッドデバイスについてマッピングを選択する結果に 初期化する。
    4. gamepad.[[connected]]trueに設定する。
    5. gamepad.[[timestamp]]を、gamepad関連する グローバルオブジェクトが与えられた現在の高分解能 時刻に設定する。
    6. gamepad.[[axes]] を、gamepadについて 軸を初期化する結果に設定する。
    7. gamepad.[[buttons]]を、gamepadについて ボタンを初期化する結果に設定する。
    8. gamepad.[[vibrationActuator]]を、 gamepadについてGamepadHapticActuatorを 構築する結果に設定する。
  2. gamepadを返す。

gamepadについて未使用の ゲームパッドインデックスを選択するには、次の手順を実行します:

  1. navigatorを、gamepad関連する グローバルオブジェクトNavigator オブジェクトとする。
  2. maxGamepadIndexを、 navigator.[[gamepads]]サイズ − 1とする。
  3. 0からmaxGamepadIndexまでの範囲の各 gamepadIndexについて反復する:
    1. navigator.[[gamepads]][gamepadIndex]が nullなら、gamepadIndexを返す。
  4. navigator.[[gamepads]]null追加する
  5. navigator.[[gamepads]]サイズ − 1を返す。

gamepadについて軸を初期化するには、 次の手順を実行します:

  1. inputCountを、 gamepadによって表されるデバイスが公開する軸入力の数とする。
  2. gamepad.[[axisMinimums]]を、 inputCountに等しいサイズを持ち、 各軸入力の最小論理値を含む unsigned long値の listに設定する。
  3. gamepad.[[axisMaximums]]を、 inputCountに等しいサイズを持ち、 各軸入力の最大論理値を含む unsigned long値の listに設定する。
  4. unmappedInputListを空のlistとする。
  5. mappedIndexListを空のlistとする。
  6. axesSizeを0とする。
  7. 0からinputCount − 1までの範囲の各 rawInputIndexについて反復する:
    1. インデックスrawInputIndexのゲームパッド軸が Standard Gamepadの軸を表す場合:
      1. canonicalIndexを、その軸の標準インデックスとする。
      2. mappedIndexListcanonicalIndex含む場合、 rawInputIndexunmappedInputListに追加する。

        それ以外の場合:

        1. gamepad.[[axisMapping]][rawInputIndex]を canonicalIndexに設定する。
        2. canonicalIndexmappedIndexList追加する
        3. canonicalIndex + 1がaxesSizeより大きい場合、 axesSizecanonicalIndex + 1に設定する。

      それ以外の場合、rawInputIndexunmappedInputList追加する

  8. axisIndexを0とする。
  9. unmappedInputListの各rawInputIndexについて反復する:
    1. mappedIndexListaxisIndex含む間:
      1. axisIndexをインクリメントする。
    2. gamepad.[[axisMapping]][rawInputIndex]を axisIndexに設定する。
    3. axisIndexmappedIndexList追加する
    4. axisIndex + 1がaxesSizeより大きい場合、 axesSizeaxisIndex + 1に設定する。
  10. axesを空のlistとする。
  11. 0からaxesSize − 1までの範囲の各 axisIndexについて反復し、0をaxes追加する
  12. axesを返す。

gamepadについてボタンを初期化するには、 次の手順を実行します:

  1. inputCountを、 gamepadによって表されるデバイスが公開するボタン入力の数とする。
  2. gamepad.[[buttonMinimums]]を、inputCountに等しいサイズを持ち、 各ボタン入力の最小論理値を含む unsigned long値の listに設定する。
  3. gamepad.[[buttonMaximums]]を、inputCountに等しいサイズを持ち、 各ボタン入力の最大論理値を含む unsigned long値の listに設定する。
  4. unmappedInputListを空のlistとする。
  5. mappedIndexListを空のlistとする。
  6. buttonsSizeを0とする。
  7. 0からinputCount − 1までの範囲の各 rawInputIndexについて反復する:
    1. インデックスrawInputIndexのゲームパッドボタンが Standard Gamepadのボタンを表す場合:
      1. canonicalIndexを、そのボタンの標準インデックスとする。
      2. mappedIndexListcanonicalIndex含む場合、 rawInputIndexunmappedInputListに追加する。

        それ以外の場合:

        1. gamepad.[[buttonMapping]][rawInputIndex] をcanonicalIndexに設定する。
        2. canonicalIndexmappedIndexList追加する
        3. canonicalIndex + 1が buttonsSizeより大きい場合、buttonsSizecanonicalIndex + 1に設定する。

      それ以外の場合、rawInputIndexunmappedInputList追加する

    2. rawInputIndexをインクリメントする。
  8. buttonIndexを0とする。
  9. unmappedInputListの各rawInputIndexについて反復する:
    1. mappedIndexListbuttonIndex含む間:
      1. buttonIndexをインクリメントする。
    2. gamepad.[[buttonMapping]][rawInputIndex] をbuttonIndexに設定する。
    3. buttonIndexmappedIndexList追加する
    4. buttonIndex + 1がbuttonsSizeより大きい場合、 buttonsSizebuttonIndex + 1に設定する。
  10. buttonsを空のlistとする。
  11. 0からbuttonsSize − 1までの範囲の各 buttonIndexについて反復し新しいGamepadButtonbuttons追加する
  12. buttonsを返す。

5. GamepadButtonインターフェイス

このインターフェイスは、ゲームパッドデバイス上の個々のボタンの状態を定義します。

WebIDL[Exposed=Window]
interface GamepadButton {
  readonly attribute boolean pressed;
  readonly attribute boolean touched;
  readonly attribute double value;
};

GamepadButtonのインスタンスは、次の表で説明される内部スロットを用いて作成されます:

内部スロット 初期値 説明(非規範的)
[[pressed]] false ボタンが押されていることを示すフラグ
[[touched]] false ボタンがタッチされていることを示すフラグ
[[value]] 0.0 [0 .. 1]の範囲にスケーリングされたボタン値を表す double
pressed 属性

ボタンの押下状態です。このプロパティは、 ボタンが現在押されている場合はtrueなければならず、押されていない場合はfalseなければなりません。 純粋な押下状態または解放状態を示すデジタルスイッチを持たないボタンについては、 ユーザーエージェントは、 値が一定量を超えた時にボタンが押されたことを示すため、 ボタン 押下しきい値を選択しなければなりません。 プラットフォームAPIが推奨値を与える場合、ユーザーエージェントはそれを使用するべきです。 その他の場合、ユーザーエージェントは、 他の何らかの妥当な値を選択するべきです

pressed取得子の手順は次のとおりです:

  1. this.[[pressed]]を返す。
touched 属性

ボタンのタッチ状態です。ボタンがタッチを検出できる場合、 ボタンが現在タッチされていれば、このプロパティはtrueなければならず、 それ以外の場合はfalseなければなりません。ボタンが タッチを検出できず、アナログ値を報告できる場合、このプロパティは、valueプロパティが 0より大きい場合はtrueなければならず、 valueが0の場合はfalseなければなりません。ボタンがタッチを検出できず、 デジタル値のみを報告できる場合、このプロパティはpressed属性を反映しなければなりません

touched取得子の手順は次のとおりです:

  1. this.[[touched]]を返す。
value 属性

アナログセンサーを持つボタンについて、このプロパティは、ボタンが押された量を 表さなければなりません。すべてのボタン値は、[0 .. 1]の範囲に 線形正規化されなければなりません。0は完全に押されていないことを意味しなければならず、 1は完全に押されていることを意味しなければなりません。アナログセンサーを持たないボタンについては、 完全に押されていない状態と完全に押されている状態に対応する値0および1のみが それぞれ提供されなければなりません

value取得子の手順は次のとおりです:

  1. this.[[value]]を返す。

6. GamepadTouchインターフェイス

このインターフェイスは、そのような入力をサポートするゲームパッドのタッチ面上の タッチを定義します。このオブジェクトは、入力媒体(例: 指、スタイラスなど)が タッチデバイスに接触した時から、入力媒体がタッチデバイスに接触しなくなる時まで、 タッチ点を一意に識別するタッチ touchIdで構成されます。

WebIDLdictionary GamepadTouch {
  unsigned long touchId;
  octet surfaceId;
  DOMPointReadOnly position;
  DOMRectReadOnly? surfaceDimensions;
};
touchId属性
タッチの一意なidです。範囲は[0 .. 4294967295]です。
surfaceId属性
タッチを生成した面の一意なidです。
position属性
タッチのxy座標を保持する DOMPointReadOnlyです。 z値およびw値は現在使用されません。各座標の範囲は[-1 .. 1]に正規化されます。 x軸に沿って、-1は最左端の座標を参照し、1は最右端の座標を参照します。 y軸に沿って、-1は最上端の座標を参照し、1は最下端の座標を参照します。
surfaceDimensions属性
整数単位でのタッチ面のwidth およびheightで 初期化されたDOMRectReadOnlyです。 利用できない場合はnullです。

7. GamepadMappingType列挙型

この列挙型は、Gamepadの既知のマッピングの集合を定義します。

WebIDLenum GamepadMappingType {
  "",
  "standard",
  "xr-standard",
};
""
空文字列は、このgamepadに対してマッピングが使用されていないことを示します。
"standard"
GamepadのコントロールがStandard Gamepad レイアウトにマッピングされています。
"xr-standard"
Gamepadのコントロールが"xr-standard" gamepad mappingにマッピングされています。このマッピングは、 WebXR Gamepads Module - Level 1による使用のために予約されています。 Gamepadオブジェクトが getGamepads()によって返される場合、 "xr-standard"の mappingを報告してはなりません

8. GamepadHapticActuatorインターフェイス

GamepadHapticActuatorは、 触覚フィードバックの目的で力を加えることができる、モーターまたは他のアクチュエーターの 構成に対応します。

WebIDL[Exposed=Window]
interface GamepadHapticActuator {
  [SameObject] readonly attribute FrozenArray<GamepadHapticEffectType> effects;
  Promise<GamepadHapticsResult> playEffect(
      GamepadHapticEffectType type,
      optional GamepadEffectParameters params = {}
  );
  Promise<GamepadHapticsResult> reset();
};

GamepadHapticActuatorのインスタンスは、 次の表で説明される内部スロットを用いて作成されます:

内部スロット 初期値 説明
[[effects]] GamepadHapticEffectTypeの空のlist アクチュエーターがサポートする効果を表します。
[[playingEffectPromise]] null 何らかの効果を再生するためのPromise、または効果が 再生されていない場合はnull
effects属性

アクチュエーターがサポートするすべての触覚効果の種類を表す GamepadHapticEffectType値の配列です。 このプロパティは、ユーザーエージェントがその種類の効果の 再生をサポートしない場合を除き、アクチュエーターがサポートする GamepadHapticEffectType値を列挙します。

effects取得子の手順は次のとおりです:

  1. this.[[effects]]を返す。
playEffect()メソッド

GamepadHapticEffectType typeおよび GamepadEffectParameters paramsを伴って呼び出される playEffect() メソッドの手順は次のとおりです:

  1. paramsが、type妥当な効果を記述しない場合、 TypeError拒否されたpromiseを返す。
  2. documentを、現在の 設定オブジェクト関連する グローバルオブジェクト関連付けられた Documentとする。
  3. documentnullである、またはdocument完全に アクティブでない、またはdocument可視性 状態"hidden"である場合、 "InvalidStateError" DOMException拒否されたpromiseを返す。
  4. this.[[playingEffectPromise]]nullでない場合:
    1. effectPromisethis.[[playingEffectPromise]]とする。
    2. this.[[playingEffectPromise]]nullに設定する。
    3. グローバルタスクをキューに入れる。 これはゲームパッドタスクソース上で、 this関連する グローバルオブジェクトを用いて行い、 effectPromiseを"preempted"で解決する。
  5. this GamepadHapticActuatorが、type効果を再生できない場合、 NotSupportedErrorを理由として 拒否されたpromiseを返す。
  6. [[playingEffectPromise]]新しいpromiseとする。
  7. playEffectTimestampを、document関連する グローバルオブジェクトが与えられた現在の高分解能 時刻とする。
  8. 次の手順を並列に行う:
    1. typeparams、およびplayEffectTimestampを用いて、 アクチュエーターに触覚効果を発行する
    2. 効果が完了した時、もし this.[[playingEffectPromise]]nullでない場合、グローバルタスクをキューに入れる。 これはゲームパッドタスクソース上で、this関連する グローバルオブジェクトを用いて行い、 次の手順を実行する:
      1. this.[[playingEffectPromise]]nullである場合、これらの手順を中止する。
      2. this.[[playingEffectPromise]] を"complete"で 解決する。
      3. this.[[playingEffectPromise]]nullに設定する。
  9. [[playingEffectPromise]]を返す。
reset()メソッド

reset()メソッドの手順は次のとおりです:

  1. documentを、現在の 設定オブジェクト関連する グローバルオブジェクト関連付けられた Documentとする。
  2. documentnullである、またはdocument完全に アクティブでない、またはdocument可視性 状態"hidden"である場合、 "InvalidStateError" DOMException拒否されたpromiseを返す。
  3. resetResultPromise新しいpromiseとする。
  4. this.[[playingEffectPromise]]nullでない場合、次の手順を並列に行う:
    1. effectPromisethis.[[playingEffectPromise]]とする。
    2. 触覚効果を停止する。これはthisの gamepadのアクチュエーター上で行う。
    3. 効果が正常に停止された場合、次を行う:
      1. effectPromisethis.[[playingEffectPromise]] がまだ同じである場合、 this.[[playingEffectPromise]]nullに設定する。
      2. グローバルタスクをキューに入れる。 これはゲームパッドタスクソース上で、 this関連する グローバルオブジェクトを用いて行い、 effectPromiseを "preempted"で 解決する。
    4. resetResultPromiseを "complete"で 解決する
  5. resetResultPromiseを返す。

GamepadHapticActuatorは、 type[[effects]] list内に見つかる場合、type効果を再生できます

GamepadHapticEffectType typeおよびGamepadEffectParameters paramsを持つ効果が、妥当な効果を記述するかどうかを確認するには、 次の手順を実行します:

  1. GamepadHapticEffectType typeの値が与えられたとして、次で分岐する:
    "dual-rumble"
    params妥当なdual-rumble効果を記述しない場合、 falseを返す。
    "trigger-rumble"
    params妥当なtrigger-rumble効果を記述しない場合、 falseを返す。
  2. trueを返す

アクチュエーター上で触覚効果を 発行するには、ユーザーエージェントは、 typeの効果をレンダリングするためのコマンドを デバイスへ送信し、提供されたparamsを使用させようとしなければなりませんユーザーエージェントは、 params.startDelay0.0でない場合、より正確な再生タイミングのために、提供されたplayEffectTimestampを 使用するべきですユーザー エージェントは、互換性を高めるために効果を変更してもよいです。 たとえば、ランブルモーター向けの効果は、波形触覚をサポートするが ランブルモーターを欠くデバイスのために、波形ベースの効果に変換されることがあります。

アクチュエーター上で触覚 効果を停止するには、ユーザーエージェントは、 現在再生中の効果を中止するためのコマンドをデバイスへ送信しなければなりません。 触覚効果が中断された場合、アクチュエーターは可能な限り速やかに静止状態へ戻るべきです

8.1 可視性変更の処理

document可視性状態"hidden"になった時、各GamepadHapticActuator actuatorについて、次の手順を実行します:

  1. actuator.[[playingEffectPromise]]nullである場合、これらの手順を中止する。
  2. グローバルタスクをキューに入れる。 これはゲームパッドタスクソース上で、 actuator関連する グローバルオブジェクトを用いて行い、次の手順を実行する:
    1. actuator.[[playingEffectPromise]]nullである場合、これらの手順を中止する。
    2. actuator.[[playingEffectPromise]] を"preempted"で 解決する。
    3. actuator.[[playingEffectPromise]]nullに設定する。
  3. actuator上の触覚効果を停止する

8.2 GamepadHapticActuatorの構築

Gamepadの主たる振動アクチュエーターを表す 新しい gamepadHapticActuatorは、 次の手順を実行することで構築されます:

  1. gamepadHapticActuatorを、新しく 作成されたGamepadHapticActuatorインスタンスとする。
  2. supportedEffectsListを空のlistとする。
  3. GamepadHapticEffectTypeの各列挙値 typeについて、ユーザーエージェントが、 そのアクチュエーター上でその種類の効果を開始するコマンドを送信できる場合、 typesupportedEffectsListに追加する。
  4. gamepadHapticActuator.[[effects]]supportedEffectsListに設定する。

9. GamepadHapticsResult列挙型

WebIDLenum GamepadHapticsResult {
  "complete",
  "preempted"
};
complete

触覚効果は再生を完了しました。

preempted

現在の効果は、別の効果によって停止または置換されました(すなわち「preempted」)。

10. GamepadHapticEffectType列挙型

効果の種類は、効果パラメーターがアクチュエーターによってどのように解釈されるかを 定義します。

WebIDLenum GamepadHapticEffectType {
  "dual-rumble",
  "trigger-rumble"
};
"dual-rumble"効果タイプ

"dual-rumble"は、標準ゲームパッドの 各ハンドルに偏心回転質量(ERM)振動モーターを持つ触覚 構成を記述します。この構成では、どちらの モーターもゲームパッド全体を振動させることができます。各モーターによって 作成される振動効果は等しくないため、それぞれの効果を組み合わせて より複雑な触覚効果を作成できます。

"dual-rumble"効果は、この種類の アクチュエーターを対象とした、固定時間で一定強度の振動効果です。 "dual-rumble" 効果は、startDelaydurationstrongMagnitude、および weakMagnitudeによって定義されますが、 いずれも既定値が0であるため必須ではありません。

strongMagnitudeおよび weakMagnitudeは、 低周波振動および高周波振動の強度レベルを設定し、 [0 .. 1]の範囲に正規化され、既定値は0です。

GamepadEffectParameters paramsが与えられた場合、 妥当なdual-rumble効果は、妥当なduration妥当なstartDelayを持ち、かつ strongMagnitudeおよび weakMagnitudeの両方が [0 .. 1]の範囲内になければなりません。

"trigger-rumble"効果タイプ

"trigger-rumble"は、 "dual-rumble"に使用される2つの ハンドルモーターに加えて、Standard Gamepadの下部前面ボタン (標準インデックス6および7のボタン)のそれぞれに 振動モーターを持つ触覚構成を記述します。これらのボタンは 最も一般的にはばね付きトリガーの形を取ります。この 構成では、どちらのモーターもボタン表面に局所的な 触覚フィードバックを提供できます。

"trigger-rumble"効果は、 この種類のアクチュエーターを対象とした、固定時間で一定強度の 振動効果です。"trigger-rumble" 効果は、startDelaydurationstrongMagnitudeweakMagnitudeleftTrigger、および rightTriggerによって 定義されますが、いずれも既定値が0であるため必須ではありません。

startDelaydurationstrongMagnitudeweakMagnitudeは、 "dual-rumble"と同じ定義を共有します。 leftTriggerおよび rightTriggerは、それぞれ 左右の下部前面ボタン振動の強度レベルを設定し、 [0 .. 1]の範囲に正規化され、既定値は0です。

GamepadEffectParameters paramsが与えられた場合、 妥当なtrigger-rumble効果は、妥当なduration妥当なstartDelayを持ち、かつ strongMagnitudeweakMagnitudeleftTrigger、および rightTriggerが [0 .. 1]の範囲内になければなりません。

11. GamepadEffectParameters辞書

GamepadEffectParameters辞書は、触覚効果によって使用される パラメーター用のキーを含みます。各キーの意味は触覚効果によって定義され、 一部のキーは使用されないことがあります。

望ましくない長時間実行効果を緩和するため、ユーザーエージェントは、妥当な効果について、 合計効果時間を何らかの最大時間までに制限してもよいです。 ユーザーエージェントが最大5秒を使用することが 推奨されます

WebIDLdictionary GamepadEffectParameters {
    unsigned long long duration = 0;
    unsigned long long startDelay = 0;
    double strongMagnitude = 0.0;
    double weakMagnitude = 0.0;
    double leftTrigger = 0.0;
    double rightTrigger = 0.0;
};
duration メンバー
durationは、 振動効果の継続時間をミリ秒で設定します。
startDelay メンバー
startDelayは、 playEffect()が 呼び出されてから振動が開始されるまでの遅延時間をミリ秒で設定します。 遅延間隔の間、アクチュエーターは振動するべきではありません
strongMagnitudeメンバー
"dual-rumble"または "trigger-rumble"効果における 低周波ランブルの振動強度です。
weakMagnitudeメンバー
"dual-rumble"または "trigger-rumble"効果における 高周波ランブルの振動強度です。
leftTriggerメンバー
"trigger-rumble" 効果における、左下前面ボタン(標準 インデックス6)のランブルの振動強度です。
rightTriggerメンバー
"trigger-rumble"効果における、 右下前面ボタン(標準インデックス7)のランブルの振動強度です。

12. Navigatorインターフェイスへの拡張

WebIDL[Exposed=Window]
partial interface Navigator {
  sequence<Gamepad?> getGamepads();
};

Navigatorのインスタンスは、 次の表で説明される内部スロットを用いて作成されます:

内部スロット 初期値 説明(非規範的)
[[hasGamepadGesture]] false ゲームパッドユーザージェスチャーが 観測されたことを示すフラグ
[[gamepads]] Gamepad?オブジェクトの空のsequence そのindex属性で指定されるインデックスに存在する各 Gamepad、または未割り当てインデックスの null

12.1 getGamepads()メソッド

getGamepads()から返されるゲームパッド状態は、 gamepaddisconnected またはgamepadconnectedイベントが 発火した後まで、切断または接続を反映しません。

フィンガープリンティングを緩和するため、 getGamepads()は、 ゲームパッドユーザージェスチャーが見られる前は、 空のlistを返します。 [FINGERPRINTING-GUIDANCE]

getGamepads()メソッドの手順は 次のとおりです:

  1. docを、現在の グローバルオブジェクト関連付けられた Documentとする。
  2. docnullである、またはdoc完全に アクティブでない場合、 空のlistを返す。
  3. doc"gamepad"権限の使用を 許可されていない場合、 "SecurityError" DOMException投げ、これらの手順を中止する。
  4. this.[[hasGamepadGesture]]falseである場合、 空のlistを返す。
  5. nowを、現在の グローバルオブジェクトが与えられた現在の高分解能 時刻とする。
  6. gamepadsを空のlistとする。
  7. this.[[gamepads]]gamepadについて:
    1. gamepadnullでなく、かつ gamepad.[[exposed]]falseである場合:
      1. gamepad.[[exposed]]trueに設定する。
      2. gamepad.[[timestamp]]nowに設定する。
    2. gamepadgamepads追加する
  8. gamepadsを返す。

gamepadは、現在の入力状態が、ユーザーが現在ゲームパッドと 相互作用していることを示す場合、 ゲームパッドユーザージェスチャーを含みますユーザーエージェントは、 入力状態がゲームパッドユーザージェスチャーを含むかどうかを確認するためのアルゴリズムを 提供しなければなりません。中立の既定値をサポートし、 falsepressed値を 少なくとも一度報告したボタンについては、truepressed値は 相互作用とみなされるべきです。ボタンが中立の既定値を サポートしない場合(たとえば、トグルスイッチ)、 truepressed値は 相互作用とみなされるべきではありません。ボタンが falsepressed値を一度も報告していない場合、 それは相互作用とみなされるべきではありません。 軸の動きは、その軸が中立の既定値をサポートし、中立からの現在の 変位がユーザーエージェントによって 選択されたしきい値を超えており、かつその軸が少なくとも一度 しきい値未満の値を報告している場合、相互作用とみなされるべきです。 軸が中立の既定値をサポートしない場合(たとえば、自己中心復帰しないジョイスティックの軸)、 または軸が軸ジェスチャーしきい値未満の値を一度も報告していない場合、 その軸は相互作用の確認時に考慮されるべきではありません。 軸ジェスチャーしきい値は、ランダムなジッターが相互作用とみなされないよう十分に大きくするべきです

13. GamepadEventインターフェイス

WebIDL[Exposed=Window]

interface GamepadEvent: Event {
  constructor(DOMString type, GamepadEventInit eventInitDict);
  [SameObject] readonly attribute Gamepad gamepad;
};
gamepad属性
gamepad属性は、このイベントに関連付けられた ゲームパッドデータへのアクセスを提供します。

13.1 GamepadEventInit辞書

WebIDLdictionary GamepadEventInit : EventInit {
  required Gamepad gamepad;
};
gamepadメンバー
このイベントに関連付けられたGamepad

14. 再マッピング

各デバイス製造元は多くの異なる製品を作成しており、それぞれが 固有のボタンおよび軸のスタイルとレイアウトを持ちます。 ユーザーエージェントは、 これらを可能な限り多くサポートすることが意図されています。

さらに、ゲームコンソールによって普及したデファクト標準レイアウトが 存在します。ユーザーエージェントが 接続されたデバイスを認識する場合、可能であれば標準順序に再マッピングすることが 推奨されます。認識されないデバイスも、 それらの生の形式で公開されるべきです。

現在、標準レイアウトは1つあり、それがStandard Gamepadです。再マッピング時、axesおよび buttons内のインデックスは、 できるだけ下図の物理的位置に対応するべきです。さらに、 mappingは "standard"に設定されるべきです

Standard Gamepadのボタンは、4つのボタンからなる左クラスター、 4つのボタンからなる右クラスター、3つのボタンからなる中央 クラスター、およびゲームパッドの左右両側にある前面向きボタンのペアとして 配置されます。"Standard Gamepad"の4つの軸は、 左右に1つずつあるアナログスティックのペアに関連付けられています。次の 表は、ボタン/軸とそれらの物理的位置を説明します。

軸入力は、サムスティック軸の入力値を報告し、そのサムスティックが 対応するStandard Gamepadサムスティックとほぼ同じ位置にあり、 軸の向き(上下または左右)がStandard Gamepad軸の向きと一致する場合、Standard Gamepad軸を表すものとします。同じ Standard Gamepad軸を表す軸が複数ある場合、ユーザーエージェントは、そのうち1つを Standard Gamepad軸として選択し、他の軸には別の インデックスを割り当てるべきです

ボタン入力は、ボタンまたはトリガーの入力値を報告し、そのボタンまたは トリガーが対応するStandard Gamepadボタンとほぼ同じ位置にある場合、 Standard Gamepadボタンを表すものとします。

軸またはボタン入力がStandard Gamepadの軸または ボタンを表す場合、その標準インデックスは、 対応するStandard Gamepadの軸またはボタンのインデックスです。

種類 インデックス 位置
ボタン 0 右クラスターの下ボタン
1 右クラスターの右ボタン
2 右クラスターの左ボタン
3 右クラスターの上ボタン
4 左上前面ボタン
5 右上前面ボタン
6 左下前面ボタン
7 右下前面ボタン
8 中央クラスターの左ボタン
9 中央クラスターの右ボタン
10 左スティック押下ボタン
11 右スティック押下ボタン
12 左クラスターの上ボタン
13 左クラスターの下ボタン
14 左クラスターの左ボタン
15 左クラスターの右ボタン
16 中央クラスターの中央ボタン
axes 0 左スティックの水平軸(負が左/正が右)
1 左スティックの垂直軸(負が上/正が下)
2 右スティックの水平軸(負が左/正が右)
3 右スティックの垂直軸(負が上/正が下)
1 Standard Gamepadレイアウトの視覚的表現。

14.1 フィンガープリンティングの緩和

Gamepadオブジェクトの機能を検査することは、 能動的フィンガープリンティングの手段として使用できます。ユーザーエージェントは、フィンガープリンティング 面を減らすために、APIを通じて公開されるデバイス情報を変更してもよいです。 例として、実装は、接続されたデバイスにより多いまたは少ない 入力が存在する場合でも、Gamepadオブジェクトが Standard Gamepadレイアウトで定義された数とちょうど同じボタンおよび軸を 持つことを要求できます。 [FINGERPRINTING-GUIDANCE]

15. 使用例

この節は非規範的です。

以下の例は、ゲームパッドへの典型的なアクセスを示します。 requestAnimationFrame() メソッドとの関係に注意してください。

function runAnimation() {
    window.requestAnimationFrame(runAnimation);
    for (const pad of navigator.getGamepads()) {
      // todo; pad.axesとpad.buttonsを表示する簡単なデモ
      console.log(pad);
    }
}

window.requestAnimationFrame(runAnimation);
Best Practice 1: requestAnimationFrame()との 調整

インタラクティブなアプリケーションは通常、 requestAnimationFrame() メソッドを用いてアニメーションを駆動し、アニメーションをユーザーのゲームパッド入力と 調整したいと考えます。そのため、ゲームパッドデータは、アニメーションコールバックが 実行される直前にできるだけ近いタイミングで、かつアニメーションと一致する頻度で ポーリングされるべきです。すなわち、アニメーションコールバックが60Hzで実行されている場合、 ゲームパッド入力もそのレートでサンプリングされるべきです。

16. gamepadconnectedイベント

ゲームパッドがシステム上で利用可能になった時、次の手順を実行します:

  1. documentを、現在のグローバル オブジェクト関連付けられた Documentとし、それ以外の場合はnullとする。
  2. documentnullでなく、かつ "gamepad"権限の使用を許可されていない場合、 これらの手順を中止する。
  3. グローバルタスクを キューに入れる。これは、ゲームパッドタスクソース上で、 現在のグローバル オブジェクトを用いて行い、次の手順を実行する:
    1. gamepadを、ゲームパッドを表す新しい Gamepadとする。
    2. navigatorを、gamepad関連する グローバルオブジェクトNavigator オブジェクトとする。
    3. navigator.[[gamepads]][gamepad.index]を gamepadに設定する。
    4. navigator.[[hasGamepadGesture]]trueである場合:
      1. gamepad.[[exposed]]trueに設定する。
      2. documentnullでなく、かつ 完全に アクティブである場合、gamepad関連する グローバルオブジェクトに対して、 gamepadconnectedという名前のイベントを発火する。 その際、GamepadEventを使用し、その gamepad属性を gamepadで初期化する。

この仕様を実装するユーザーエージェントは、 gamepadconnectedという名前の 新しいDOMイベントを提供しなければなりません。対応するイベントは GamepadEvent型でなければならずWindow オブジェクト上で発火しなければなりません

ユーザーエージェントは、 ユーザーがゲームパッドを接続したことを示すため、このイベント型をディスパッチしなければなりません。ページが読み込まれた時点でゲームパッドが すでに接続されていた場合、ユーザーがボタンを押すか軸を動かした時に gamepadconnectedイベントが ディスパッチされるべきです

17. gamepaddisconnectedイベント

ゲームパッドがシステム上で利用不能になった時、次の手順を実行します:

  1. gamepadを、利用不能なデバイスを表す Gamepad とする。
  2. グローバルタスクを キューに入れる。これは、ゲームパッドタスクソース上で、 gamepad関連する グローバルオブジェクトを用いて行い、次の手順を実行する:
    1. gamepad.[[connected]]falseに設定する。
    2. documentを、gamepad関連する グローバルオブジェクト関連付けられた Documentとし、それ以外の場合はnullとする。
    3. gamepad.[[exposed]]trueであり、かつ documentnullでなく、かつ 完全に アクティブである場合、gamepad関連する グローバルオブジェクトに対して、 gamepaddisconnectedという名前のイベントを発火する。これは GamepadEventを用い、その gamepad属性を gamepadで初期化する。
    4. navigatorを、gamepad関連する グローバルオブジェクトNavigator オブジェクトとする。
    5. navigator.[[gamepads]][gamepad.index]を nullに設定する。
    6. navigator.[[gamepads]]空でなく、かつ navigator.[[gamepads]]の最後の項目nullである間、 navigator.[[gamepads]]の最後の項目削除する

この仕様を実装するユーザーエージェントは、 gamepaddisconnectedという名前の 新しいDOMイベントを提供しなければなりません。対応するイベントは GamepadEvent型でなければならずWindow オブジェクト上で発火しなければなりません

ゲームパッドがユーザーエージェントから切断された時、 ユーザーエージェントが以前にその ゲームパッドについてgamepadconnectedイベントを Windowへ ディスパッチしていた場合、gamepaddisconnectedイベントは その同じWindowへ ディスパッチされなければなりません

18. その他のイベント

軸およびボタン変更イベントを含めるか除外するか、またそれらを よりまとめる("gamepadchanged"?)、多少分離する("gamepadaxischanged"?)、 あるいは個々の軸およびボタンごとに分離するかについて、さらなる議論が必要です。

19. WindowEventHandlersインターフェイスミックスインへの拡張

この仕様は、HTMLのWindowEventHandlers インターフェイスミックスインを拡張し、 イベントハンドラー登録を容易にするためにイベントハンドラー IDL属性を追加します。

WebIDLpartial interface mixin WindowEventHandlers {
  attribute EventHandler ongamepadconnected;
  attribute EventHandler ongamepaddisconnected;
};

20. Permissions Policyとの統合

この仕様は、 文字列"gamepad"で識別されるポリシー制御機能を定義します。その 既定の 許可リスト*です。

文書権限 ポリシーは、 その文書内の任意のコンテンツが getGamepads()へアクセスすることを許可されるかどうかを 決定します。いずれかの文書で無効にされた場合、その文書内のどのコンテンツも getGamepads()使用することを許可されず、 またgamepadconnectedおよび gamepaddisconnected イベントも発火しません。

21. 適合性

非規範的と明示された節に加え、この仕様内のすべての著作ガイドライン、図、例、および注は 非規範的です。この仕様内のその他すべては規範的です。

この文書におけるキーワードMAYMUSTMUST NOTRECOMMENDEDSHOULD、およびSHOULD NOTは、 ここに示すようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174] に記述されているように解釈されます。

A. 謝辞

この節は非規範的です。

以下の人々が、この文書の開発に貢献しました。

B. 参考文献

B.1 規範参考文献

[dom]
DOM標準. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[FINGERPRINTING-GUIDANCE]
Web仕様におけるブラウザー フィンガープリンティングの緩和. Nick Doty; Tom Ritter. W3C. 2025年3月21日. W3C Working Group Note. URL: https://www.w3.org/TR/fingerprinting-guidance/
[geometry-1]
Geometry Interfaces Module Level 1. Simon Pieters; Chris Harrelson. W3C. 2018年12月4日. W3C Candidate Recommendation. URL: https://www.w3.org/TR/geometry-1/
[HR-TIME]
High Resolution Time. Yoav Weiss. W3C. 2024年 11月7日. W3C Working Draft. URL: https://www.w3.org/TR/hr-time-3/
[html]
HTML標準. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra標準. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[permissions-policy]
Permissions Policy. Ian Clelland. W3C. 2025年5月6日. W3C Working Draft. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
RFCで要求レベルを示すために使用する キーワード. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119キーワードにおける大文字と小文字の曖昧性. B. Leiba. IETF. 2017年5月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[WEBIDL]
Web IDL標準. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/
[webxr-gamepads-module-1]
WebXR Gamepads Module - Level 1. Brandon Jones; Manish Goregaokar; Rik Cabanier. W3C. 2024年4月9日. W3C Working Draft. URL: https://www.w3.org/TR/webxr-gamepads-module-1/