I'm currently trying to use the Pointer Lock API into a Jupyter notebook. Basically I want to log a bunch of trackpad moves without being limited by the dimensions of the screen, then pass it on to Python to do some calculations on it. In what follow I'll just talk about getting the pointer lock.
Here's my approach: I create a new <div>
on top of the current notebook so I can use it to lock the pointer, let's call it canvas
, and call canvas.requestPointerLock();
. Pretty straightforward stuff.
My concern is that the same code (below) will work fine in a Javascript tester, but not in a Jupyter cell in %%javascript
mode.
var canvas = document.getElementById('canvasPA');
if (canvas !== null && typeof(canvas) != 'undefined') {
canvas.parentNode.removeChild(canvas);
}
/*
* Checking whether the web page can accommodate pointerLock
*/
var havePointerLock = 'pointerLockElement' in document
|| 'mozPointerLockElement' in document
|| 'webkitPointerLockElement' in document;
if (havePointerLock) {
console.log("Document has pointer lock capabilities."); // >> True
}
/*
* Defining the canvasPA div
*/
if (canvas === null || typeof(canvas) == 'undefined') {
console.log("New canvas.");
canvas = document.createElement('div');
canvas.id = 'canvasPA';
canvas.style = 'position: absolute; top: 250px; left: 550px; '
+ 'width: 1000px; height: 400px; '
+ 'background-color: #00BB5511; z-index: 1000;';
document.getElementsByTagName('body')[0].appendChild(canvas);
}
/*
* Defining the changePointerLock behavior.
* When the lock is released, all listeners are removed, then canvasPA is
* removed from the webpage.
*/
function changeCallback() {
var pointerLockElement = document.pointerLockElement
|| document.mozPointerLockElement
|| document.webkitPointerLockElement;
console.log( "pointerLockElement: " + pointerLockElement );
if(pointerLockElement === canvas) {
console.log('The pointer lock status is now locked onto canvas');
} else {
console.log('The pointer lock status is now unlocked');
// Removing all pointerLock-related listeners
document.removeEventListener('pointerlockchange', changeCallback, false);
document.removeEventListener('mozpointerlockchange', changeCallback, false);
document.removeEventListener('webkitpointerlockchange', changeCallback, false);
document.removeEventListener('pointerlockerror', errorCallback, false);
document.removeEventListener('mozpointerlockerror', errorCallback, false);
document.removeEventListener('webkitpointerlockerror', errorCallback, false);
// Remove canvas from the notebook
canvas = document.getElementById("canvasPA");
if (canvas !== null
&& typeof(canvas) != 'undefined'
&& canvas.parentNode !== null) {
canvas.parentNode.removeChild(canvas);
}
}
}
function errorCallback() {
console.log("Error when attempting to lock cursor...");
}
document.addEventListener('pointerlockchange', changeCallback, false);
document.addEventListener('mozpointerlockchange', changeCallback, false);
document.addEventListener('webkitpointerlockchange', changeCallback, false);
document.addEventListener('pointerlockerror', errorCallback, false);
document.addEventListener('mozpointerlockerror', errorCallback, false);
document.addEventListener('webkitpointerlockerror', errorCallback, false);
// Ask the browser to lock the pointer.
canvas.requestPointerLock = canvas.requestPointerLock
|| canvas.mozRequestPointerLock
|| canvas.webkitRequestPointerLock;
canvas.requestPointerLock();
With the Javascript tester my console prints:
Document has pointer lock capabilities.
New canvas.
pointerLockElement: [object HTMLDivElement]
The pointer lock status is now locked onto canvas
Then the cursor is locked and disappears. Then I press Escape, and the console logs:
pointerLockElement: undefined
The pointer lock status is now unlocked
However, when I try the exact same code in a Jupyter cell, I get:
Document has pointer lock capabilities.
New canvas.
Error when attempting to lock cursor...
And the cursor is never locked.
It would appear that something in a Jupyter notebook is preventing me to get the lock, but I cannot know for sure since the pointerlockerror
comes with no explanation.
Any thoughts?
I'm using Chrome (64.0.3282.140), Mac OS X 10.11.6.
Thanks a lot!
- Mathiev
So, I managed to make it work using this previous answer to a slightly different question:
https://stackoverflow.com/a/19901534/9349369
The problem is that requestPointerLock cannot be called automatically, it should be called from the user's callback
It worked for me, I now call requestPointerLock()
from a mouseclick
callback.
Glad that I found a solution, however I think the main question remains: how come it worked in "normal" javascript (see original question) and not from a Jupyter cell? I suppose that's less important now...