Pointer Lock API

これは実験段階の機能です。
この機能は複数のブラウザで開発中の状態にあります。各ブラウザで用いるために、適切なベンダー接頭辞が必要な場合があります。互換性テーブルをチェックしてください。また、実験段階の機能の構文と挙動は、仕様変更に伴い各ブラウザの将来のバージョンで変更になる可能性があることに注意してください。

Pointer Lock (以前は Mouse Lock と呼ばれていました) は、マウスカーソルの絶対位置だけでなく、時間の経過に伴うマウスの動き (すなわち、デルタ) に基づく入力方法を提供します。これにより、加工されていないマウスの動きへアクセスする、マウスイベントのターゲットをひとつの要素にロックする、マウスが一方向へどれだけ移動できるかの制限を除去する、視野からカーソルを取り除くことができます。

この API は、動きのコントロールやオブジェクトの回転、エントリの変更にかなりのマウス操作が必要になるアプリケーションで役立ちます。3D ビューやモデリングはもちろん、一人称視点によるもののような高度なビジュアルアプリケーションでは特に欠かせません。

例えばユーザがボタンをクリックすることなく、マウスを動かすだけで視点をコントロールできるアプリを作成できます。ボタンは他の操作のために使用できます。この種類のマウス入力は地図や衛星画像の閲覧、あるいは一人称視点 (ゲームや没入型の動画など) でとても役立ちます。

Pointer Lock では、カーソルがブラウザやスクリーンの境界を通り過ぎるときでもマウスイベントにアクセスできます。例えばユーザは限りなくマウスを動かすことで、3D モデルの回転や操作を続けることができます。Pointer Lock がなければ、ポインタがブラウザまたはスクリーンの端に達したときに回転や操作が止まります。ゲームのプレイヤーはこの機能に対して特にわくわくするでしょう。マウスカーソルがゲームのプレイ領域から外れて、ゲームからマウスのフォーカスを奪う別のアプリケーションを意図せずクリックしてしまうこと (悲劇!) を心配せずに、熱中してボタンのクリックやマウスカーソルをあちこちに動かすことができるようになるためです。

基本概念

Pointer Lock は mouse capture と関係があります。Mouse capture はマウスのドラッグ中にターゲットの要素へ継続的にイベントを提供しますが、マウスのボタンを離すとイベントが停止します。Pointer Lock は Mouse capture と以下の点が異なります:

  • Pointer Lock は永続的です。明示的に API が呼び出されるかユーザが特定の解放ジェスチャを行うまで、マウスを解放しません。
  • Pointer Lock はブラウザまたはスクリーンの境界に制限されません。
  • Pointer Lock はマウスボタンの状態に関係なく、イベントが発生し続けます。
  • Pointer Lock はカーソルを隠します。

Web ページで Pointer Lock を設定する方法の例を、以下に示します。

<button onclick="lockPointer();">Lock it!</button>
<div id="pointer-lock-element"></div>
<script>
// 注意: この例を記述した時点で、Mozilla と WebKit だけが Pointer Lock をサポートしています。

// フルスクリーン化および pointer lock を行う要素
var elem;

document.addEventListener("mousemove", function(e) {
  var movementX = e.movementX       ||
                  e.mozMovementX    ||
                  e.webkitMovementX ||
                  0,
      movementY = e.movementY       ||
                  e.mozMovementY    ||
                  e.webkitMovementY ||
                  0;

  // マウスの動きのデルタ値を表示
  console.log("movementX=" + movementX, "movementY=" + movementY);
}, false);

function fullscreenChange() {
  if (document.webkitFullscreenElement === elem ||
      document.mozFullscreenElement === elem ||
      document.mozFullScreenElement === elem) { // 古い API では 'S' が大文字
    // 要素がフルスクリーンになり、pointer lock を要求できます
    elem.requestPointerLock = elem.requestPointerLock    ||
                              elem.mozRequestPointerLock ||
                              elem.webkitRequestPointerLock;
    elem.requestPointerLock();
  }
}

document.addEventListener('fullscreenchange', fullscreenChange, false);
document.addEventListener('mozfullscreenchange', fullscreenChange, false);
document.addEventListener('webkitfullscreenchange', fullscreenChange, false);

function pointerLockChange() {
  if (document.mozPointerLockElement === elem ||
      document.webkitPointerLockElement === elem) {
    console.log("Pointer Lock was successful.");
  } else {
    console.log("Pointer Lock was lost.");
  }
}

document.addEventListener('pointerlockchange', pointerLockChange, false);
document.addEventListener('mozpointerlockchange', pointerLockChange, false);
document.addEventListener('webkitpointerlockchange', pointerLockChange, false);

function pointerLockError() {
  console.log("Error while locking pointer.");
}

document.addEventListener('pointerlockerror', pointerLockError, false);
document.addEventListener('mozpointerlockerror', pointerLockError, false);
document.addEventListener('webkitpointerlockerror', pointerLockError, false);

function lockPointer() {
  elem = document.getElementById("pointer-lock-element");
  // 要素のフルスクリーン化から始めてください。現在の実装では要素で
  // Pointer Lock を要求する前にフルスクリーンにすることを要求します。
  // これは将来変更される可能性があります。
  elem.requestFullscreen = elem.requestFullscreen    ||
                           elem.mozRequestFullscreen ||
                           elem.mozRequestFullScreen || // 古い API では 'S' が大文字
                           elem.webkitRequestFullscreen;
  elem.requestFullscreen();
}
</script>

メソッド/プロパティの概要

Pointer lock API は Fullscreen API と同様に、新たなメソッド requestPointerLock を追加することで DOM 要素を拡張しています。なお現在はベンダー接頭辞が付加されています。メソッドは以下のように記述します:

element.webkitRequestPointerLock(); // Chrome

element.mozRequestPointerLock(); // Firefox

requestPointerLock の現在の実装は、requestFullScreen および Fullscreen API に強く結び付けられています。要素が Pointer Lock できるようになる前に、まずはフルスクリーン状態に入らなければなりません。先に示したようにポインタをロックするプロセスは、要求の成功または失敗を示すイベント(pointerlockchange, pointerlockerror) とは非同期的です。これは Fullscreen API の requestFullScreen メソッドおよび fullscreenchange イベントや fullscreenerror イベントの動作と似ています。

Pointer Lock API は document インタフェースの拡張も行なっており、新たなプロパティやメソッドを追加しています。新たなプロパティは現在ロックされている要素 (もしあれば) へアクセスするために使用されるもので、pointerLockElement という名前で現在は接頭辞が付加されています。document の新たなメソッドは exitPointerLock で、名前がほのめかすとおり Pointer Lock から抜けるために使用します。

pointerLockElement プロパティは要素が現在 Pointer Lock 状態であるかを判断する (例えば真偽チェックを行う) ために、またはロックされた要素があればその要素への参照を得るために有用です。それぞれの使用法の例を示します:

document.pointerLockElement = document.pointerLockElement    ||
                              document.mozPointerLockElement ||
                              document.webkitPointerLockElement;

// 1) 真偽チェックとして使用 (Pointer Lock 状態か?)
if (!!document.pointerLockElement) {
  // ポインタはロックされている
} else {
  // ポインタはロックされていない
}

// 2) Pointer Lock 状態の要素へアクセスすするために使用
if (document.pointerLockElement === someElement) {
  // someElement は現在 Pointer Lock 状態である
}

documentexitPointerLock メソッドは Pointer Lock から抜けるために使用され、requestPointerLock と同様に pointerlockchange イベントや pointerlockerror イベントを用いて非同期的に動作します:

document.exitPointerLock = document.exitPointerLock    ||
                           document.mozExitPointerLock ||
                           document.webkitExitPointerLock;

function pointerLockChange() {
  document.pointerLockElement = document.pointerLockElement    ||
                                document.mozPointerLockElement ||
                                document.webkitPointerLockElement;

  if (!!document.pointerLockElement) {
    console.log("Still locked.");
  } else {
    console.log("Exited lock.");
  }
}

document.addEventListener('pointerlockchange', pointerLockChange, false);
document.addEventListener('mozpointerlockchange', pointerLockChange, false);
document.addEventListener('webkitpointerlockchange', pointerLockChange, false);

// ロック解除を試みる
document.exitPointerLock();

pointerlockchange イベント

Pointer Lock の状態が変化したとき、例えば requestPointerLock あるいは exitPointerLock を呼び出したときや、ユーザが ESC キーを押下したときなどに、pointerlockchangedocument に発生します。これはシンプルなイベントであり、付加的なデータは含まれません。

現在このイベントは Firefox で mozpointerlockchange 、Chrome で webkitpointerlockchange のように接頭辞が付加されています。

pointerlockerror イベント

requestPointerLock または exitPointerLock の呼び出しによりエラーが発生したときは、pointerlockerror イベントが document に発生します。これはシンプルなイベントであり、付加的なデータは含まれません。

現在このイベントは Firefox で mozpointerlockerror、Chrome で webkitpointerlockerror のように接頭辞が付加されています。

Mouse イベントの拡張

Pointer Lock API は通常の MouseEvent を movement 属性によって拡張します。

partial interface MouseEvent {
    readonly attribute long movementX;
    readonly attribute long movementY;
};
現在 movement 属性は Firefox で .mozMovementX および .mozMovementY、Chrome で .webkitMovementX および .webkitMovementY のように接頭辞が付加されています。

Mouse イベントの新たなパラメータである movementXおよび movementY は、マウスポインタの位置の変化を提供します。パラメータの値は MouseEvent のプロパティである screenX および screenY の値同士の差と同じであり、それらの値は後発の mousemove イベントである eNow および ePrevious に保存されます。言い換えると、Pointer Lock のパラメータ movementX は、eNow.screenX - ePrevious.screenX になります。

ロックされた状態

Pointer Lock が有効であるとき、標準の MouseEvent である clientXclientYscreenX、および screenY は、マウスが動いていないかのように値が固定されます。movementX プロパティおよび movementY プロパティが、マウスの位置の変化を提供し続けます。マウスが一方向へ連続的に移動するとしても、movementX および movementY の値に制限はありません。マウスカーソルは存在せず、ウィンドウから外れたりスクリーンの端で止まったりしないという考え方です。

ロックが解除された状態

パラメータ movementX および movementY はマウスのロック状態にかかわらず有効であり、ロックされていない状態でも利便性のために使用できます。

マウスのロックが解除されると、システムカーソルが存在するようになり、ブラウザがウィンドウに戻ります。これが発生したとき、movementX および movementY は 0 に設定されるかもしれません。

iframe の制限

Pointer Lock は一度に 1 つだけの iframe をロックできます。iframe をひとつロックすると、別の iframe をロックしてターゲットを切り替えようとすることはできません。Pointer Lock はエラーになります。この制限を避けるため、始めにロックされた iframe のロックを解除してから別の iframe をロックしてください。

iframe の規定の動作では、"サンドボックス化された" iframe が Pointer Lock をブロックします。<iframe sandbox="allow-pointer-lock"> という属性/値の組み合わせによってこの制限を避けられることが、Chrome でまもなく可能になる予定です。

ブラウザ実装状況

機能 Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
基本サポート

23 が目標webkit*

CR/72574 をご覧ください

14.0 (14.0)

バグ 633602

未サポート 未サポート 未サポート
機能 Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
基本サポート 未サポート 未サポート 未サポート 未サポート 未サポート

* about:flags で機能を有効にするか、--enable-pointer-lock フラグをつけて Chrome を起動することが必要です。

参考情報

W3C Pointer Lock API SpecificationED

MouseEvent

Document Tags and Contributors

Contributors to this page: yyss
最終更新者: yyss,