los API de bloqueo de puntero (anteriormente llamado API de bloqueo del mouse) proporciona métodos de entrada basados ​​en el movimiento del mouse a lo largo del tiempo (es decir, deltas), no solo en la posición absoluta del cursor del mouse en la ventana gráfica. Le da acceso al movimiento del mouse sin procesar, bloquea el objetivo de los eventos del mouse en un solo elemento, elimina los límites sobre la distancia que puede llegar al movimiento del mouse en una sola dirección y quita el cursor de la vista. Es ideal para juegos 3D en primera persona, por ejemplo.

Más que eso, la API es útil para cualquier aplicación que requiera una entrada significativa del mouse para controlar movimientos, rotar objetos y cambiar entradas, por ejemplo, permitiendo a los usuarios controlar el ángulo de visión moviendo el mouse sin hacer clic en ningún botón. Luego, los botones se liberan para otras acciones. Otros ejemplos incluyen aplicaciones para ver mapas o imágenes de satélite.

El bloqueo del puntero le permite acceder a los eventos del mouse incluso cuando el cursor pasa el límite del navegador o la pantalla. Por ejemplo, sus usuarios pueden continuar girando o manipulando un modelo 3D moviendo el mouse sin fin. Sin el bloqueo del puntero, la rotación o manipulación se detiene en el momento en que el puntero llega al borde del navegador o la pantalla. Los jugadores ahora pueden hacer clic en los botones y deslizar el cursor del mouse hacia adelante y hacia atrás sin preocuparse por salir del área de juego y hacer clic accidentalmente en otra aplicación que alejaría el enfoque del mouse del juego.

Conceptos básicos

El bloqueo del puntero está relacionado con la captura del mouse. La captura del mouse proporciona una entrega continua de eventos a un elemento de destino mientras se arrastra el mouse, pero se detiene cuando se suelta el botón del mouse. El bloqueo del puntero es diferente de la captura del mouse en las siguientes formas:

  • Es persistente: el bloqueo del puntero no libera el mouse hasta que se realiza una llamada explícita a la API o el usuario usa un gesto de liberación específico.
  • No está limitado por los límites del navegador o de la pantalla.
  • Continúa enviando eventos independientemente del estado del botón del mouse.
  • Oculta el cursor.

Descripción general del método / propiedades

Esta sección proporciona una breve descripción de cada propiedad y método relacionado con la especificación de bloqueo de puntero.

requestPointerLock ()

La API de bloqueo de puntero, similar a la API de pantalla completa, amplía los elementos DOM agregando un nuevo método, requestPointerLock(). Como recientemente se ha eliminado el prefijo, actualmente lo declararía algo como esto, por ejemplo, si quisiera solicitar el bloqueo del puntero en un canvas elemento:

canvas.requestPointerLock = canvas.requestPointerLock ||
                            canvas.mozRequestPointerLock;

canvas.requestPointerLock()

Si un usuario ha salido del bloqueo del puntero a través del gesto de desbloqueo predeterminado, o no se ha introducido previamente un bloqueo de puntero para este documento, un evento generado como resultado de una gesto de compromiso debe ser recibido por el documento antes requestPointerLock podría suceder. (de https://w3c.github.io/pointerlock/#extensions-to-the-element-interface)

pointerLockElement y exitPointerLock ()

La API de bloqueo de puntero también amplía la Document interfaz, agregando una nueva propiedad y un nuevo método. La nueva propiedad se utiliza para acceder al elemento actualmente bloqueado (si lo hay) y se denomina pointerLockElement y el nuevo método en Document es exitPointerLock() y, como su nombre lo indica, se utiliza para salir del bloqueo del puntero.

los pointerLockElement La propiedad es útil para determinar si algún elemento está actualmente bloqueado por un puntero (por ejemplo, para realizar una verificación booleana) y también para obtener una referencia al elemento bloqueado, si existe.

Aquí hay un ejemplo de uso pointerLockElement:

if(document.pointerLockElement === canvas ||
  document.mozPointerLockElement === canvas)
    console.log('The pointer lock status is now locked');else
    console.log('The pointer lock status is now unlocked');

los Document.exitPointerLock() El método se usa para salir del bloqueo del puntero, y como requestPointerLock, funciona de forma asincrónica utilizando el pointerlockchange y pointerlockerror eventos, sobre los que verá más a continuación.

document.exitPointerLock = document.exitPointerLock    ||
                           document.mozExitPointerLock;// Attempt to unlock
document.exitPointerLock();

evento pointerlockchange

Cuando cambia el estado de bloqueo del puntero, por ejemplo, al llamar requestPointerLock(), exitPointerLock(), el usuario pulsa la tecla ESC, etc. — el pointerlockchange El evento se envía al document. Este es un evento simple y no contiene datos adicionales.

if("onpointerlockchange"in document)
  document.addEventListener('pointerlockchange', lockChangeAlert,false);elseif("onmozpointerlockchange"in document)
  document.addEventListener('mozpointerlockchange', lockChangeAlert,false);functionlockChangeAlert()
  document.mozPointerLockElement === canvas)
    console.log('The pointer lock status is now locked');// Do something useful in responseelse
    console.log('The pointer lock status is now unlocked');// Do something useful in response

evento pointerlockerror

Cuando hay un error causado por llamar requestPointerLock() o exitPointerLock(), los pointerlockerror El evento se envía al document. Este es un evento simple y no contiene datos adicionales.

document.addEventListener('pointerlockerror', lockError,false);
document.addEventListener('mozpointerlockerror', lockError,false);functionlockError(e)alert("Pointer lock failed");

Nota: hasta Firefox 50, los eventos anteriores tenían el prefijo moz en Firefox.

Extensiones para eventos de mouse

La API de bloqueo de puntero extiende la normal MouseEvent interfaz con atributos de movimiento. Dos nuevos atributos para los eventos del mouse:movementX y movementY: Proporciona el cambio en las posiciones del mouse. Los valores de los parámetros son los mismos que la diferencia entre los valores de MouseEvent propiedades, screenX y screenY, que se almacenan en dos mousemove eventos, eNow y ePrevious. En otras palabras, el parámetro de bloqueo del puntero movementX = eNow.screenX - ePrevious.screenX.

Estado bloqueado

Cuando el bloqueo del puntero está habilitado, el estándar MouseEvent propiedades clientX, clientY, screenX, y screenY se mantienen constantes, como si el mouse no se estuviera moviendo. los movementX y movementY las propiedades continúan proporcionando el cambio de posición del mouse. No hay limite para movementX y movementY valores si el mouse se mueve continuamente en una sola dirección. El concepto del cursor del mouse no existe y el cursor no puede moverse fuera de la ventana o ser sujetado por un borde de la pantalla.

Estado desbloqueado

Los parametros movementX y movementY son válidos independientemente del estado de bloqueo del mouse y están disponibles incluso cuando están desbloqueados para su conveniencia.

Cuando el mouse está desbloqueado, el cursor del sistema puede salir y volver a ingresar a la ventana del navegador. Si eso pasa, movementX y movementY podría establecerse en cero.

Tutorial de ejemplo simple

Hemos escrito un demostración simple de bloqueo de puntero para mostrarle cómo usarlo para configurar un sistema de control simple (ver código fuente). La demostración se ve así:

Un círculo rojo encima de un fondo negro.

Esta demostración utiliza JavaScript para dibujar una bola sobre un

elemento. Cuando hace clic en el lienzo, el bloqueo del puntero se usa para quitar el puntero del mouse y permitirle mover la bola directamente con el mouse. Veamos cómo funciona esto.

Establecemos las posiciones xey iniciales en el lienzo:

var x =50;var y =50;

Los métodos de bloqueo de puntero están actualmente prefijados, por lo que a continuación los bifurcaremos para las diferentes implementaciones del navegador.

canvas.requestPointerLock = canvas.requestPointerLock ||
                            canvas.mozRequestPointerLock;

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

Ahora configuramos un detector de eventos para ejecutar el requestPointerLock() en el lienzo cuando se hace clic en él, lo que inicia el bloqueo del puntero.

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

Ahora para el detector de eventos de bloqueo de puntero dedicado: pointerlockchange. Cuando esto ocurre, ejecutamos una función llamada lockChangeAlert() para manejar el cambio.

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

Esta función verifica la propiedad pointLockElement para ver si es nuestro lienzo. Si es así, adjuntó un detector de eventos para manejar los movimientos del mouse con el updatePosition() función. Si no es así, vuelve a eliminar el detector de eventos.

functionlockChangeAlert()

La función updatePosition () actualiza la posición de la pelota en el lienzo (x y y), y también incluye if() declaraciones para comprobar si la pelota se ha salido de los bordes del lienzo. Si es así, hace que la bola se enrolle hasta el borde opuesto. También incluye una verificación de si un requestAnimationFrame() se ha realizado previamente la llamada, y si es así, la vuelve a llamar según sea necesario, y llama al canvasDraw() función que actualiza la escena del lienzo. También se configura un rastreador para escribir los valores X e Y en la pantalla, como referencia.

var tracker = document.getElementById('tracker');var animation;functionupdatePosition(e)
  x += e.movementX;
  y += e.movementY;if(x > canvas.width +RADIUS)
    x =-RADIUS;if(y > canvas.height +RADIUS)
    y =-RADIUS;if(x <-RADIUS)
    x = canvas.width +RADIUS;if(y <-RADIUS)
    y = canvas.height +RADIUS;
  tracker.textContent ="X position: "+ x +", Y position: "+ y;if(!animation)
    animation =requestAnimationFrame(function()
      animation =null;canvasDraw(););

los canvasDraw() función dibuja la bola en la corriente x y y posiciones:

functioncanvasDraw()
  ctx.fillStyle ="black";
  ctx.fillRect(0,0, canvas.width, canvas.height);
  ctx.fillStyle ="#f00";
  ctx.beginPath();
  ctx.arc(x, y,RADIUS,0,degToRad(360),true);
  ctx.fill();

limitaciones de iframe

El bloqueo del puntero solo puede bloquear un iframe a la vez. Si bloquea un iframe, no puede intentar bloquear otro iframe y transferirle el objetivo; el bloqueo del puntero saldrá por error. Para evitar esta limitación, primero desbloquee el iframe bloqueado y luego bloquee el otro.

Mientras que los iframes funcionan de forma predeterminada, los iframes “en espacio aislado” bloquean el bloqueo del puntero. La capacidad de evitar esta limitación, en forma de combinación de atributo / valor.