Pointer Lock API

相关背景

痛点:在激烈的射击游戏中切换视角,很容易就把光标移出窗口,游戏就很难进行下去


image.png

概念:指针锁定(以前叫做 鼠标锁定) 提供了一种输入方法,这种方法是基于鼠标随着时间推移的运动的(也就是说,deltas),而不仅是鼠标光标的绝对位置。通过它可以访问原始的鼠标运动,把鼠标事件的目标锁定到一个单独的元素,这就消除了鼠标在一个单独的方向上到底可以移动多远这方面的限制,并从视图中删去光标。

作用:可以实现窗口内的光标锁定,让你的鼠标无限移动,脱离浏览器窗体的限制!

效果:http://120.131.8.110:8080/api/api.html

特点:
它是持久性的。指针锁定不释放鼠标,直到作出一个显式的 API 调用或是用户使用一个专门的释放手势。
它不局限于浏览器或者屏幕边界。
它持续发送事件,而不管鼠标按钮状态如何。
它隐藏光标。

兼容性:

image.png

目前,Pointer Lock API共支持3个属性,2个方法和2个事件,分别如下:

3个属性
Document.pointerLockElement
Document.onpointerlockchange
Document.onpointerlockerror
2个方法
Element.requestPointerLock()
Document.exitPointerLock()
2个事件
pointerlockchange
pointerlockerror

方法(异步)

(1)Element.requestPointerLock()
可以让页面进入鼠标锁定状态(鼠标直接消失),鼠标无限滚动,坐标无限变化。

(2)Document.exitPointerLock()
让页面从鼠标锁定状态退出

事件

(1)pointerlockchange 事件
当指针锁定状态改变时 – 例如,当调用 requestPointerLock, exitPointerLock,用户按下 ESC 键,等等。— pointerlockchange 事件被分发到 document。 这是一个简单事件所以不包含任何的额外数据。

(2)pointerlockerror 事件
当调用 requestPointerLock 或 exitPointerLock而引发错误时, pointerlockerror 事件被分发到 document。这是一个简单事件所以不包含任何的额外数据。

鼠标事件扩展

鼠标事件的两个新参数—movementX
和 movementY
—提供了鼠标位置的变化情况。这两个参数的值,等于两个MouseEvent属性( screenX和 screenY)之间值的变化程度,这些 MouseEvent 属性被存储在两个连续的鼠标移动事件( eNow和 ePrevious
)中。换言之,指针锁定参数 movementX = eNow.screenX - ePrevious.screenX
。(译注:不存在名为 eNow 或 ePrevious 的事件或属性,eNow 代指当前的鼠标移动事件,ePrevious 代指前一个鼠标移动事件)

锁定状态

当指针锁定被启动之后,正常的 MouseEvent 属性 clientX, clientY, screenX, 和 screenY ,保持不变,就像鼠标没有在移动一样。 movementX 和 movementY 属性持续提供鼠标的位置变化。如果鼠标在一个方向上持续移动,movementX 和 movementY的值是没有限制的。不存在鼠标光标的概念,而且光标无法移到窗口之外,而且也不会被屏幕边缘所固定。

未锁定状态

无论鼠标锁定状态是怎样的, movementX 和 movementY 参数一直有效,并且为了方便起见,甚至在未锁定状态也是有效的。
当鼠标被解除锁定,系统光标可以退出并重新进入浏览器窗口。如果发生这种情况,movementX 和 movementY 会被设置成0。

属性

Document.pointerLockElement
当前页面触发鼠标无限滚动的元素,适用于确定当前是否有被指针锁定的元素(例如,用来做一个布尔检查),以及当有元素被锁定时获取该元素的一个引用

// 1) 用于布尔检查--我们被指针锁定了吗?
if (!!document.pointerLockElement) {
  // 指针被锁定
} else {
  // 指针未被锁定
}

// 2) 用于访问指针锁定的元素
if (document.pointerLockElement === someElement) {
  // someElement 当前被指针锁定
}
var eleImage = document.getElementById('image');
  if (eleImage) {
    // 起始值
    var moveX = 0, moveY = 0;
    // 图片无限变换的方法
    var rotate3D = function (event) {
      moveX = moveX + event.movementX;
      moveY = moveY + event.movementY;
      eleImage.style.transform = 'rotateX(' + moveY + 'deg) rotateY(' + moveX + 'deg)';
    };
    
    // 触发鼠标锁定
    eleImage.addEventListener('click', function () {
      eleImage.requestPointerLock();
    });
    
    // 再次点击页面,取消鼠标锁定处理
    document.addEventListener('click', function () {
      if (document.pointerLockElement == eleImage) {
        document.exitPointerLock();
      }
    });
    
    // 检测鼠标锁定状态变化
    document.addEventListener('pointerlockchange', function () {
      if (document.pointerLockElement == eleImage) {
        document.addEventListener("mousemove", rotate3D, false);
      } else {
        document.removeEventListener("mousemove", rotate3D, false);
      }
    }, false);
  }

你可能感兴趣的:(Pointer Lock API)