Pointer lock hides the cursor and reports raw movementX/movementY deltas with no screen edges, for first-person games and 3D viewers. Unlike pointer capture it lasts until document.exitPointerLock() or the user presses Escape. It needs a click, so a headless run proves nothing; desktop Chrome 1 , Firefox 555 and Safari 10 support it.
canvas.onclick = () => canvas.requestPointerLock({ unadjustedMovement: true }); // no acceleration
const look = (e) => { camera.rotation.y -= e.movementX * 0.002; };
document.addEventListener('pointerlockchange', () => {
if (document.pointerLockElement === canvas) document.addEventListener('mousemove', look);
else document.removeEventListener('mousemove', look);
});unadjustedMovement arrived in Chrome 88, Safari 18.4 and Firefox 152.