Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS Pointer Lock

Tags:

javascript

I'm having trouble with pointer Locking. My code looks something like this...

Canvas = document.createElement('canvas');
...(Parameters)...
document.body.appendChild(Canvas);

Canvas.requestPointerLock = Canvas.requestPointerLock ||
             element.mozRequestPointerLock ||
             element.webkitRequestPointerLock;

Canvas.requestPointerLock();

When I run my code nothing happens with the pointer lock (everything else run noramly). The code i showed is just what i think is relevant to the issue but if more code from my program is needed just tell me.

like image 931
technik3k Avatar asked Apr 28 '16 01:04

technik3k


2 Answers

If we move 'requestPointerLock()' inside click event, it works fine. Sharing below sample code for reference.

<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Pointer lock</title>

<style type="text/css"> 
html {font-size: 10px; font-family: sans-serif;}
canvas {display: block; margin: 0 auto; border: 1px solid black;}
</style>
</head>

<body>
      <canvas width="640" height="360">
        Your browser does not support HTML5 canvas
      </canvas>
</body>

<script type="text/javascript">
// setup of the canvas

window.addEventListener('load', eventWindowLoaded, false);
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

function eventWindowLoaded() {  
  canvasDraw();
}

var x = 50;
var y = 50;

function canvasDraw() { 
  ctx.fillStyle = "black";
  ctx.fillRect(0,0,canvas.clientWidth,canvas.clientHeight);
  ctx.fillStyle = "#f00";  
  ctx.beginPath();
  ctx.arc(x,y,20,0,degToRad(360), true);
  ctx.fill();
}

// pointer lock object forking for cross browser
canvas.requestPointerLock = canvas.requestPointerLock || canvas.mozRequestPointerLock;
document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock;

canvas.onclick = function() {
  canvas.requestPointerLock();
}

// pointer lock event listeners
// Hook pointer lock state change events for different browsers
document.addEventListener('pointerlockchange', lockChangeAlert, false);
document.addEventListener('mozpointerlockchange', lockChangeAlert, false);

function lockChangeAlert() {
  if(document.pointerLockElement === canvas ||
  document.mozPointerLockElement === canvas) {
    console.log('The pointer lock status is now locked');
    document.addEventListener("mousemove", canvasLoop, false);
  } else {
    console.log('The pointer lock status is now unlocked');  
    document.removeEventListener("mousemove", canvasLoop, false);
  }
}


function canvasLoop(e) {
  var movementX = e.movementX || e.mozMovementX || 0;
  var movementY = e.movementY || e.mozMovementY ||  0;
  x += movementX;
  y += movementY; 
  canvasDraw();
  console.log("X position: " + x + ', Y position: ' + y);
}

// helper function
function degToRad(degrees) {
  var result = Math.PI/180 * degrees;
  return result;
}   
</script>
</html>
like image 50
Nitin Sinha Avatar answered Oct 22 '22 02:10

Nitin Sinha


According to the WC3 Docs on pointerlock:

requestPointerLock

If a user has exited pointer lock via the default unlock user gesture, or pointer lock has not previously been entered for this document, an event generated as a result of an engagement gesture must be received by the document before requestPointerLock will succeed.

It then talks about engagement gestures below.

Engagement gesture

An event generated by the user agent as a result of user interaction intended to interact with the page. e.g. click, but not mousemove. Engagement gestures are any events included in the definition of being allowed to show a popup with the addition of keypress and keyup.

So in order for your code to work, requestPointerLock should be called from an engagement gesture, for example a click event handler.

like image 45
0xcaff Avatar answered Oct 22 '22 02:10

0xcaff