这篇文章发布于 2017年10月18日,星期三,01:16,归类于 JS API。 阅读 40454 次, 今日 7 次 16 条评论
by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=6473
本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。
一、Pointer Lock API是干嘛用的?
用一句话说明Pointer Lock API的作用就是:Pointer Lock API可以让你的鼠标无限移动,脱离浏览器窗体的限制!
这对于一些需要鼠标控制的应用非常有用。举个例子:某3D VR女友的游戏,你鼠标向上移动,则你的视角就会往下。
在默认网页环境下,你鼠标移动到浏览器上边缘就不能再往上了,结果,本来还差一点点角度就能看到胖次,结果卡在了关键地方,岂不非常影响游戏体验。
但是如果使用了Pointer Lock API,就不会出现这样的问题,鼠标可以无限移动,坐标可以无限增大,完全脱离了浏览器窗口的限制,可以完美享受沉浸式操作体验。
二、Pointer Lock API有哪些具体API名称?
目前,Pointer Lock API共支持3个属性,2个方法和2个事件,分别如下:
- 3个属性
- Document.pointerLockElement
- Document.onpointerlockchange
- Document.onpointerlockerror
- 2个方法
- Element.requestPointerLock()
- Document.exitPointerLock()
- 2个事件
- pointerlockchange
- pointerlockerror
其中,2个事件和其中2个属性是一一对应的,因此,我们实际上需要了解的知识点是下面这些:
Document.pointerLockElement
,以及Element.requestPointerLock()
,Document.exitPointerLock()
以及pointerlockchange
和pointerlockerror
事件。
1. Document.pointerLockElement
指当前页面触发鼠标无限滚动的元素,通常使用语法为:
var element = document.pointerLockElement;
返回的是一个DOM元素对象,如果当前页面是非鼠标锁定状态,则返回值是null
。
2. Element.requestPointerLock()
可以让页面进入鼠标锁定状态(鼠标直接消失),鼠标无限滚动,坐标无限变化。通常使用语法为:
var element.requestPointerLock();
3. Document.exitPointerLock()
让页面从鼠标锁定状态退出,通常使用语法为:
document.exitPointerLock();
浏览器默认支持按下ESC键退出鼠标锁定状态,但是用户有时候更习惯于点击取消等,此时就可以使用document.exitPointerLock()
进行设置。
4. pointerlockchange事件
当页面鼠标锁定状态改变的时候触发。例如:
document.addEventListener('pointerlockchange', function () {
// ...
}, false);
5. pointerlockerror事件
当页面鼠标锁定失败的时候触发。例如当你试图同时锁定同一个页面的多个<iframe>
时候,就会触发这个出错事件。
二、Pointer Lock API的图片无限3D旋转JS实例一则
看完了干巴巴的语法说明,我们还是来看一点鲜活的案例吧。
您可以狠狠的点击这里:JS Pointer Lock与图片无限3D旋转demo
默认进去会看到一个相貌平平的女生,然后点击这张图片:
此时鼠标会立即消失,同时图片就会根据你的鼠标位置开始翻江倒海,就像这样子:
而且鼠标的活动范围似乎没有边界,即使移动了一万个屏幕的宽度,我们的图片依然翻转个不停。这就是Pointer Lock API的特性表现。
相关代码如下:
<img id="image" src="mm1.jpg">
JS部分:
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); }
其中,应用了除了pointerlockerror
事件外的其他所有属性和方法(见红色高亮)。
原理大致如下:
点击图片,执行eleImage.requestPointerLock()
让页面进入鼠标锁定状态,此时会触发'pointerlockchange'
事件,于是,给页面绑定鼠标移动改变图片旋转的方法,为了避免重复绑定,我们借助document.pointerLockElement
判断页面的锁定状态。最后,为了方便取消页面的锁定状态,我们在页面上绑定了点击事件,通过document.exitPointerLock()
取消页面的锁定状态。
需要说明的:
event.movementX
和event.movementY
表示每次mousemove
事件触发时候,距离上次移动的水平和垂直位置大小,而不是具体的某个坐标值。因此,需要和初始坐标不断的累加确定当前移动位置。
四、结束语
最后说下Pointer Lock API的兼容性。
由于Pointer Lock API是与鼠标相关的API,因此所有移动端都不支持,因为没有必要支持。
对于桌面浏览器,Chrome,Firefox以及Edge浏览器都是支持的,并且现在使用可以不加私有前缀,直接走起。IE并不支持,但这并不妨碍我们进行增强使用Pointer Lock API。
以上~
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=6473
(本篇完)
- 今天才知道,Web网页也能阻止息屏了 (0.800)
- CSS3 pointer-events:none应用举例及扩展 (0.178)
- jQuery - 鼠标经过(hover)事件的延时处理 (0.089)
- MooTools和jQuery库继承实现class切换对比 (0.089)
- js页面文字选中后分享到新浪微博实现 (0.089)
- HTML5终极备忘大全(图片版+文字版) (0.089)
- CSSOM视图模式(CSSOM View Module)相关整理 (0.089)
- JS滚轮事件(mousewheel/DOMMouseScroll)了解 (0.089)
- 小卖弄:纯CSS实现的outline切换transition动画效果 (0.089)
- pointer-events:none提高页面滚动时候的绘制性能? (0.089)
- 更好的纯CSS滚动指示器技术实现 (RANDOM - 0.089)
结果发现鼠标移过浏览器编辑后,胖次部分是马赛克或者还没有构建…
大神咯咯。你这网站速度真的很快啊,几乎所有页面都是毫秒开。请问你是怎么做到的?能不能专门写篇网站加载速度优化的文章?谢谢咯咯。
你用个不太差的服务器基本都不会慢的
相貌平平???
2313
var element.requestPointerLock();
这是 ES8 的新语法吗?
你发了,公司要上市。
相貌平平???不存在的
每天学一点,天天更牛逼
涨见识了
一看举的例子这么污 就知道是你了
safari下demo跑不了
不错
又get到一个新技能
占楼用的哈哈
沙发~~ 写得很好,又涨见识了