ウェブアプリで、ポインタ イベントをキャプチャする際にマウス アクセラレーションを無効にできるようになりました。
高速移動は、マウスまたはトラックパッドを使用して画面上のポインタを移動する場合の、人間工学に基づく機能です。ゆっくりと動くことで正確に動き、短い動作でポインタが画面全体を横切ることができます。具体的には、マウスを動かしたのと同じ物理的な距離で、移動距離が速くなると、画面上のポインタが移動します。
オペレーティング システムでは、デフォルトでマウス アクセラレーションが有効になっています。一部のファーストパーティの視点ゲーム(一般にファースト パーソン シューティング(FPS))では、生のマウス入力データを使用して、加速度を調整せずにカメラの回転を制御します。遅いか速いかに関係なく、同じ物理運動でも同じ回転になります。その結果、プロのゲーマーは、より優れたゲーム体験と高い精度を実現しています。
Chrome 88 以降では、最新の Pointer Lock API により、ウェブアプリでマウスの移動データを高速化と非高速化を切り替えることができます。
Google Stadia や Nvidia GeForce Now などのウェブベースのゲーム プラットフォームでは、すでにこれらの新機能を使用して FPS ゲーマーの満足度を高めています。
API の使用
ポインタのロックをリクエストする
ポインタロックとは、デスクトップ アプリがポインタ アイコンを非表示にして、マウスの動きを別のものとして解釈する(3D の世界を見回すなど)ことを指す標準用語です。
mousemove
ドキュメント イベントの movementX
属性と movementY
属性により、最後の移動イベント以降にマウスポインタが移動した量がわかります。ただし、ポインタがウェブページの外に移動しても更新されません。
document.addEventListener("mousemove", (event) => {
console.log(`movementX: ${event.movementX} movementY: ${event.movementY}`);
});
マウスポインタをキャプチャする(またはポインタのロックをリクエストする)と、ポインタが外に移動することを心配する必要がなくなります。これは没入型のウェブゲームで特に役立ちます。ポインタがロックされると、すべてのマウスイベントはポインタロックのターゲット要素に移動します。
ターゲット要素で requestPointerLock()
を呼び出してポインタロックをリクエストし、pointerlockchange
イベントと pointerlockerror
イベントをリッスンしてポインタロックの変更をモニタリングします。
const myTargetElement = document.body;
// Call this function to request a pointer lock.
function requestPointerLock() {
myTargetElement.requestPointerLock();
}
document.addEventListener("pointerlockchange", () => {
if (document.pointerLockElement) {
console.log(`pointer is locked on ${document.pointerLockElement}`);
} else {
console.log("pointer is unlocked");
}
});
document.addEventListener("pointerlockerror", () => {
console.log("pointer lock error");
});
マウス アクセラレーションを無効にする
requestPointerLock()
を { unadjustedMovement: true }
を指定して呼び出し、マウス アクセラレーションに関する OS レベルの調整を無効にし、未加工のマウス入力にアクセスします。これにより、ポインタがロックされているときは、mousemove
イベントのマウス移動データにマウス アクセラレーションが含まれなくなります。
requestPointerLock()
から新たに返された Promise を使用して、リクエストが成功したかどうかを確認します。
function requestPointerLockWithUnadjustedMovement() {
const promise = myTargetElement.requestPointerLock({
unadjustedMovement: true,
});
if (!promise) {
console.log("disabling mouse acceleration is not supported");
return;
}
return promise
.then(() => console.log("pointer is locked"))
.catch((error) => {
if (error.name === "NotSupportedError") {
// Some platforms may not support unadjusted movement.
// You can request again a regular pointer lock.
return myTargetElement.requestPointerLock();
}
});
}
ポインタのロックを解放することなく、マウス移動の高速化データと非高速化データを切り替えることができます。必要なオプションでポインタのロックを再度リクエストするだけで済みます。このリクエストが失敗した場合、元のロックは変更されず、返された Promise は拒否されます。変更リクエストが失敗した場合、ポインタロック イベントは発生しません。
ブラウザ サポート
Pointer Lock API は各種ブラウザで十分にサポートされています。ただし、2020 年 10 月の時点で、マウス アクセラレーションの OS レベルの調整を無効にできるのは、Chromium ベースのブラウザ(Chrome や Edge など)のみです。更新については、MDN のブラウザの互換性の表をご覧ください。
オペレーティング システムのサポート
マウス アクセラレーションに関する OS レベルの調整の無効化は、ChromeOS、macOS Catalina 10.15.1、Windows でサポートされています。Linux が追随する。
サンプル
Pointer Lock API を試すには、Glitch でサンプルを実行します。必ずソースコードを確認してください。
関連情報
謝辞
この記事をレビューしてくれた James Hollyer、Thomas Steiner、Joe Medley、Kayce Basques、Vincent Scheib に感謝します。