webglで作られていると話題のブラウザゲームをやろうとしたら、Chromeに「マウスカーソルが無効になります。」的な警告が表示された。
なんだこれは。。
調べてみると、HTML5のpointer lock apiというものらしい。現在のステータスはWorking Draft
https://www.w3.org/TR/pointerlock/
ちょっと試してみた。
https://hai3.net/dev/pointerlock.html
エレメントのrequestPointerメソッドを実行すると、pointerlockが使えるということがわかった。
でもこのpointerLockはまだベンダプレフィックスが付いているので、
body.requestPointerLock = body.requestPointerLock || body.mozRequestPointerLock || body.webkitRequestPointerLock;
body.requestPointerLock();
こんな書き方をしなければいけない。。
requestPointerLockを呼ぶと、ブラウザに「ロックを許可する」「許可しない」の選択肢が表示される。
それをユーザが許可すると「pointerlockchange」イベント、許可をしないと「pointerlockerror」イベントが発生する。
これもベンダプレフィックス付きなので、pointerlockchange mozpointerlockchange webkitpointerlockchange全てイベントリスナに登録しておいたほうが良い。
pointerlockchangeイベントはロックされた時とロック解除された時にイベントが来るので、どっちの状態で発生したイベントかは、document.pointerLockElementの存在を確認すればいい。
$(document).on('pointerlockchange mozpointerlockchange webkitpointerlockchange', function(a,b){
if(document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement){
console.log('ポインタロックした');
}
else{
console.log('ポインタロックを解除した');
}
});
ポインタロック中は、ポインタが移動しない。
つまり、mousemoveイベントを拾っても、ポインタの座標は変化しない。
じゃあ何ができるのって話なんだけど、ポインタの移動量を拾える。
マウスイベントのmovementX、movementYがそれに当たるんだけど、やっぱりこれもベンダプレフィックス付きなので注意。。
$(document).on('mousemove', function(e){
e = e.originalEvent;
console.log('Xの移動量', e.movementX || e.mozMovementX || e.webkitMovementX);
console.log('Yの移動量', e.movementY || e.mozMovementY || e.webkitMovementY);
});
これらを使ったデモが、冒頭でも載せたこれ
https://hai3.net/dev/pointerlock.html
Chromeはフルスクリーンにしなくてもポインタロックが使えるんだけど、firefoxはフルスクリーンの時にしかポインタロックができないみたい。
ポインタのスクリーン座標に依存しないようなゲームとかでは使えるなあ。