Keyboard Lock API でキーをキャプチャする

インタラクティブなウェブサイト、ゲーム、リモート デスクトップやアプリケーション ストリーミングなど、さまざまなユースケースで没入型の全画面エクスペリエンスを提供します。

ブラウザを長時間使用するユーザーが増える中、高機能でインタラクティブなウェブサイト、ゲーム、リモート デスクトップ ストリーミング、アプリケーション ストリーミングは、没入感のある全画面表示のエクスペリエンスの提供を目指しています。そのためには、サイトが全画面表示モードのときに特別なキーとキーボード ショートカットにアクセスし、ナビゲーション、メニュー、ゲームで使用できるようにする必要があります。たとえば、EscAlt+TabCmd+`Ctrl+N などのキーが必要になります。

デフォルトでは、これらのキーはブラウザまたは基盤となるオペレーティング システムによって取得されるため、ウェブ アプリケーションでは利用できません。Keyboard Lock API を使用すると、ホスト OS で許可されているすべてのキーをウェブサイトで使用できるようになります(ブラウザの互換性をご覧ください)。

<ph type="x-smartling-placeholder">
</ph> macOS Chrome のブラウザタブにストリーミングされた Ubuntu Linux(全画面モードではまだ実行されていません)。 <ph type="x-smartling-placeholder">
</ph> 問題: ストリーミングされた Ubuntu Linux リモート デスクトップが全画面表示モードで実行されておらず、キーボード ロックがアクティブでない システムキーは macOS ホスト オペレーティング システムでキャプチャされるため、エクスペリエンスはまだ臨場感がありません

Keyboard Lock API を使用する

Keyboard API の Keyboard インターフェースは、物理キーボードからのキー入力のキャプチャを切り替える関数や、ユーザーのキーボード レイアウトに関する情報を取得する機能を提供します。

前提条件

最新のブラウザで利用できる全画面モードは 2 種類あります。Fullscreen API を使用して JavaScript で開始する場合と、ユーザーがキーボード ショートカットで開始する場合です。Keyboard Lock API は、JavaScript で開始された全画面がアクティブな場合にのみ使用できます。 JavaScript によって開始される全画面表示の例を次に示します。

await document.documentElement.requestFullscreen();

機能検出

次のパターンを使用して、Keyboard Lock API がサポートされているかどうかを確認できます。

if ('keyboard' in navigator && 'lock' in navigator.keyboard) {
  // Supported!
}

キーボードのロック

Keyboard インターフェースの lock() メソッドは、物理キーボードの一部またはすべてのキーのキー入力のキャプチャを有効にすると、Promise を返します。この方法で取得できるのは、基盤となるオペレーティング システムによってアクセス権が付与されているキーのみです。lock() メソッドは、ロックする 1 つ以上のキーコードの配列を受け取ります。キーコードを指定しない場合、すべてのキーがロックされます。有効なキーコード値のリストは、UI イベント KeyboardEvent コードの値の仕様をご覧ください。

すべての鍵のキャプチャ

次の例では、すべてのキーの押下をキャプチャします。

navigator.keyboard.lock();

特定のキーのキャプチャ

次の例では、WASD キーをキャプチャします。キーの押下でどの修飾子が使用されているかにかかわらず、これらのキーをキャプチャします。US QWERTY レイアウトの場合、"KeyW" を登録すると、WShift+WCtrl +WCtrl +Shift +W など、W とその他のすべての修飾キーの組み合わせがアプリに送信されます。"KeyA""KeyS""KeyD" についても同様です。

await navigator.keyboard.lock([
  "KeyW",
  "KeyA",
  "KeyS",
  "KeyD",
]);

キャプチャしたキーの押下には、キーボード イベントを使用して応答できます。 たとえば、次のコードは onkeydown イベントを使用しています。

document.addEventListener('keydown', (event) => {
  if ((event.code === 'KeyA') && !(event.ctrlKey || event.metaKey)) {
    // Do something when the 'A' key was pressed, but only
    // when not in combination with the command or control key.
  }
});

キーボードのロック解除

unlock() メソッドは、lock() メソッドによってキャプチャされたすべてのキーをロック解除し、同期的に返します。

navigator.keyboard.unlock();

ドキュメントが閉じられると、ブラウザは常に unlock() を暗黙的に呼び出します。

デモ

Keyboard Lock API をテストするには、Glitch でデモを実行します。必ずソースコードを確認してください。下の [全画面表示に変更] ボタンをクリックすると、新しいウィンドウでデモが起動し、全画面モードになります。

セキュリティ上の考慮事項

この API では、すべてのキーを取得するのに使用され、(Fullscreen APIPointerLock API と組み合わせて使用すると)ユーザーがウェブページを終了できなくなる可能性があります。これを防ぐために、API によってすべてのキーがリクエストされても、ユーザーがキーボードのロックを終了できるようにする必要があります。Chrome では、長い(2 秒間)Esc キーを押すと、キーボードのロックが解除されます。

謝辞

この記事は、Joe MedleyKayce Basques によってレビューされました。キーボード ロックの仕様は、Gary KacmarcikJamie Walch によって作成されています。 Ken Suarez 氏による Unsplash のヒーロー画像