Pointer Lock API(1/3):Pointer Lock 的总体认识

摘要:
一些基本概念Pointerlock依赖于鼠标捕捉。这不容易理解。它可能是在声明指针锁定之前进行初始化,或者确保它不会受到解锁手势的影响,以避免无法成功实现指针锁定pointerLockElement和exitPointerLock()。PointerLockAPI还提供了一个Document接口,添加了一个新属性和一个新方法。新属性用于访问当前锁定的元素pointerlockElement,新方法名为exitPointerLock(),用于退出指针锁定。

前言

指针锁定(Pointer Lock),以前也叫鼠标锁定,提供了基于鼠标随时间的移动(如deltaΔ)的输入方法,不仅仅是视窗区域鼠标的绝对位置。指针锁定让你能够访问原始的鼠标移动,将鼠标事件的目标锁定为单个元素,消除了单个方向上鼠标能够移动的最远距离限制,并且,可以把鼠标从视图中去除(隐藏效果)。 这对于Web的第一人称之类的3D游戏来说,是极为理想的实现。

可以在单个方向无限移动鼠标;可以隐藏视图上的鼠标图案

远远不止上面说到的两点,对于任何把鼠标作为重要输入的应用,该API都是非常重要的。可以帮助我们实现移动、翻转物体以及更改条目。例如,该API允许用户通过简单的仅仅移动鼠标而不使用按钮来控制画面的视角,这样依赖,就解放了按钮,作为其他的的输入需求,例如移动(想象cs游戏,我们用键盘控制行走,跳跃,鼠标控制视角)。除了游戏,该API大有应用,例如地图的拖拽,或者星体图的查看等等。

该API让我们实现复杂的鼠标交互功能成为现实,现在的Web页面、应用广泛应用。帮助我们通过鼠标移动物体,控制视角等。

指针锁定让你能够在鼠标即便超出了我们的视图范围,也能正常访问鼠标事件。

Pointer Lock API(1/3):Pointer Lock 的总体认识第1张

如上图,鼠标动作不受限于黄色的视图区域。

这一特点,可以用户能够在鼠标超出视图依然能无限制的操控、旋转视图中的物体元素。而如果没有指针锁定,这一点是没有办法实现的,鼠标在移动至超出页面或者屏幕边缘后,就无法继续控制视图中的物体元素了。

通过这样的实现,游戏玩家在按键,或者来回滑动鼠标时就不必担心跳出游戏视窗。(可以想象cs游戏,不全屏,小窗口运行的时候,只要不用鼠标点击游戏视窗之外,让游戏视窗失去鼠标焦点,鼠标永远都会在游戏视窗内)

通过指针锁定,可以在不改变我们“物理视图”尺寸的前提下,拓展鼠标的操作空间,拖拽范围。

一些基本概念

Pointer lock(指针锁定) 依赖于 mouse capture(鼠标捕捉) 。Mouse capture 提供了当鼠标在被拖动时,给目标元素连续不断的事件传送(也就是说通过鼠标按住视图中的物体元素时,拖拽鼠标,鼠标的事件状态不会断掉,或者说能保持在移动鼠标时,焦点不会从元素上失去),但是当松开鼠标按钮时,将停止(松开鼠标按钮,元素失去焦点,再拖拽鼠标,元素不受影响)。 而鼠标指针在以下一些方面不同于Mouse capture :

  • 指针锁定是持续的,指针锁定不会释放鼠标,除非有显式的API调用被触发,或者用户使用了特定的释放动作。(cs移动视角,并不需要按住鼠标)
  • 指针锁定不受限于视窗或者屏幕边界。
  • 指针锁定会无视鼠标状态地传送事件(和第一点说的一个事)。
  • 隐藏了鼠标指针图案。

方法 / 属性概览

简单的描述指针锁定的每个属性和方法。


requestPointerLock( )

指针锁定的API和全屏的API相似,通过添加新的方法来拓展DOM元素,requestPointerLock 如果你要在 canvas 元素中添加指针锁定,你可以像这样声明:

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

canvas.requestPointerLock()

如果用户已经通过默认的 解锁手势 退出了指针锁定,或者之前未为此文档输入过指针锁定,那么在requestPointerLock 成功之前,该文档必须接受到由于参与手势而产生的事件结果。

不是太容易理解,大概是在声明指针锁定之前,先初始化,或者先确定不会受到解锁手势的影响,以免无法成功实现指针锁定


pointerLockElement 和 exitPointerLock()

该Pointer lock API 还提供了Document接口,加入了一个新属性和一个新方法。 新属性用于访问当前被锁定的元素,名为pointerlockElement, 而新方法名为exitPointerLock(), 用于退出指针锁定。

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');
}

Document.exitPointerLock()方法用于退出指针锁定,与requestPointerLock一样,它使用pointerlockchangepointerlockerror事件异步工作

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

// Attempt to unlock
document.exitPointerLock();

pointerlockchange 事件

当指针锁定的状态改变,例如,当调用requestPointerLock(), exitPointerLock()方法,以及用户按Esc按键, 则pointerlockchange事件将会被发送至document。 下面是一个没有额外数据的样例:

if ("onpointerlockchange" in document) {
  document.addEventListener('pointerlockchange', lockChangeAlert, false);
} else if ("onmozpointerlockchange" in document) {
  document.addEventListener('mozpointerlockchange', lockChangeAlert, false);
}

function lockChangeAlert() {
  if(document.pointerLockElement === canvas ||
  document.mozPointerLockElement === canvas) {
    console.log('The pointer lock status is now locked');
    // Do something useful in response
  } else {
    console.log('The pointer lock status is now unlocked');
    // Do something useful in response
  }
}

pointerlockerror 事件

当在调用 requestPointerLock() or exitPointerLock()的时候发生错误, pointerlockerror 事件将会被发送到 document,以下是一个样例:

document.addEventListener('pointerlockerror', lockError, false);
document.addEventListener('mozpointerlockerror', lockError, false);

function lockError(e) {
  alert("Pointer lock failed"); 
}

免责声明:文章转载自《Pointer Lock API(1/3):Pointer Lock 的总体认识》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C4 模型GZFramework代码生成器插件使用教程下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Hadoop是什么

Hadoop原来是Apache Lucene下的一个子项目,它最初是从Nutch项目中分离出来的专门负责分布式存储以及分布式运算的项目。简单地说来,Hadoop是一个可以更容易开发和运行处理大规模数据的软件平台。下面列举hadoop主要的一些特点: 扩容能力(Scalable):能可靠地(reliably)存储和处理千兆字节(PB)数据。 成本低(Econ...

Git知识总览(三) 分支的创建、删除、切换、合并以及冲突解决

  前两篇博客集中的聊了git的一些常用命令,具体请参见《Git知识总览(一) 从 git clone 和 git status 谈起》、《Git知识总览(二) git常用命令概览》。本篇博客主要涉及了在git版本管理中的分支的创建、切换以及合并。并且罗列了在merge分支使发生冲突时的解决方式。同时还介绍了如何删除本地分支以及远程分支。本篇博客除了参考...

Zeal——好用的离线 API 文档大全!

Zeal——好用的离线 API 文档大全!摘自: https://www.cnblogs.com/souldee/p/9523497.html 介绍 作为一名程序员,工作中学习中免不了是要查询API文档的,毕竟我们能记住的东西有限,而且经常也会碰到某个API一时想不起来的情况,而每次还要打开网页去查询还是挺麻烦的,这时候拥有一个款好用的本地离线API文...

基于laravel制作API接口

基于laravel制作API接口 关于APIAPI(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。需要注意的是:API有它的具体用途,我们应该清楚它是干啥的。访问API的时候应该输入什...

redis基础数据结构源码浅析

基于redis 5.0.6 先列个表格 类型 实现 string sds list quicklist set intset hashtable zset ziplist skiplist+hashtable hash ziplist hashtable string redis的string(字符串)实现称为SDS(...

Android指针管理:RefBase,SP,WP (二)

(1)在Android中,RefBase结合了sp和wp,实现了一套通过引用计数的方法来控制对象声明周期的方法。 RefBase的定义在/frameworks/base/include/utils/RefBase.h,实现在/frameworks/base/libs/utils/RefBase.cpp。wp的定义在/frameworks/base/incl...