简单的Demo演练

点击跳转至Code Pen以查看演示和源码

完整代码

<!DOCTYPE HTML>
<html lang="en-US"> <head>
<meta charset="UTF-8">
<title>Pointer lock demo</title>
<link type="text/css" rel="stylesheet" href="style.css">
<style>
html,
body {
margin: 0;
padding: 0;
} html {
font-family: sans-serif;
} canvas {
display: block;
margin: 0 auto;
border: 1px solid black;
} .information {
width: 640px;
margin: 0 auto 50px;
} #tracker {
position: absolute;
top: 0;
right: 10px;
background-color: white;
} h1 {
font-size: 200%;
}
</style>
</head> <body>
<div class="information">
<h1>Pointer lock demo</h1> <p>本演示演示了指针锁API的用法。 单击画布区域,您的鼠标将直接控制画布内的球,而不是鼠标指针。 您可以按Escape键以返回到标准预期状态。</p>
</div> <canvas width="640" height="360">
Your browser does not support HTML5 canvas
</canvas>
<div id="tracker"></div> <script src="app.js"></script>
</body>
<script>
const RADIUS = 20; function degToRad(degrees) {
var result = Math.PI / 180 * degrees;
return result;
} // setup of the canvas var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d'); var x = 50;
var y = 50; function canvasDraw() {
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();
}
canvasDraw(); // pointer lock object forking for cross browser canvas.requestPointerLock = canvas.requestPointerLock ||
canvas.mozRequestPointerLock; document.exitPointerLock = document.exitPointerLock ||
document.mozExitPointerLock; canvas.onclick = function() {
canvas.requestPointerLock();
}; // pointer lock event listeners // Hook pointer lock state change events for different browsers
document.addEventListener('pointerlockchange', lockChangeAlert, false);
document.addEventListener('mozpointerlockchange', lockChangeAlert, false); function lockChangeAlert() {
if (document.pointerLockElement === canvas ||
document.mozPointerLockElement === canvas) {
console.log('The pointer lock status is now locked');
document.addEventListener("mousemove", updatePosition, false);
} else {
console.log('The pointer lock status is now unlocked');
document.removeEventListener("mousemove", updatePosition, false);
}
} var tracker = document.getElementById('tracker'); var animation; function updatePosition(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();
});
}
}
</script> </html>

代码说明

设定x,y 初始值:

var x = 50;
var y = 50;

指针锁定方法(这里考虑了firefox浏览器兼容):

//声明
canvas.requestPointerLock = canvas.requestPointerLock || canvas.mozRequestPointerLock;
//退出
document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock;

现在,我们给canvas设定一个点击事件来监听触发requestPointerLock()方法,当点击时,将启动指针锁定。:

canvas.onclick = function() { //canvas元素绑定点击事件
canvas.requestPointerLock();
}

对于专用指针锁定事件侦听器:pointerlockchange。我们运行一个名为lockChangeAlert()的函数来处理更改。

// pointer lock event listener

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

该函数检查poinLockElement 属性,是不是我们的canvas元素,如果是,则通过附加一个事件侦听函数updatePosition()来处理鼠标移动。如果不是,他将再次移除事件侦听。

function lockChangeAlert() {
if (document.pointerLockElement === canvas ||
document.mozPointerLockElement === canvas) {
console.log('The pointer lock status is now locked');
document.addEventListener("mousemove", updatePosition, false);
} else {
console.log('The pointer lock status is now unlocked');
document.removeEventListener("mousemove", updatePosition, false);
}
}

updatePosition()函数更新canvas中小球的位置(x,y值),同时也包括了if条件判断检查小球是否超出了canvas画布的边界。如果是,那么它会让小球绕到对面的那边,它还包括检查之前是否已经进行了requestAnimationFrame()调用,如果进行了调用,就会再次以required被调用,并且唤起canvasDraw()函数,来更行canvas画面,还设置了一个跟踪器,以将X和Y值写到屏幕上,以供参考。

var tracker = document.getElementById('tracker');

var animation;
function updatePosition(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();
});
}
}

canvasDraw()函数以最新的坐标绘制小球的位置

function canvasDraw() {
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();
}

Pointer Lock API(3/3):一个Demo的更多相关文章

  1. Pointer Lock API(2/3):属性、方法、事件

    Pointer Lock API 提供了三个属性.两个方法.两个事件 Tabel Of Content 属性 Document.pointerLockElement Document.onpointe ...

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

    前言 指针锁定(Pointer Lock),以前也叫鼠标锁定,提供了基于鼠标随时间的移动(如deltaΔ)的输入方法,不仅仅是视窗区域鼠标的绝对位置.指针锁定让你能够访问原始的鼠标移动,将鼠标事件的目 ...

  3. 指针锁定 Pointer Lock API 用法

    指针锁定 Pointer Lock API 通过它可以访问原始的鼠标运动(基于指针的相对位移 movementX / movementY),把鼠标事件的目标锁定到一个特定的元素,同时隐藏视图中的指针光 ...

  4. Pointer Lock

    Pointer Lock API 指针锁定(以前叫做 鼠标锁定) 提供了一种输入方法,这种方法是基于鼠标随着时间推移的运动的(也就是说,deltas),而不仅是鼠标光标的绝对位置.通过它可以访问原始的 ...

  5. Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)

    在android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. ...

  6. 使用android的mediaplayer做成 一个demo,欢迎测试使用

    附件是为一个定制视频产品而简单的写了一个demo,用来说明android的mediaplayer是如何使用的. http://files.cnblogs.com/guobaPlayer/palyerD ...

  7. [置顶] 一个demo学会css

    全栈工程师开发手册 (作者:栾鹏) 一个demo学会css css选择器全解 css操作语法全解 学习了css权威指南这本书,自己喜欢边学边总结边写demo,所以写了这篇文章,包含了大部分的css编程 ...

  8. [置顶] 一个demo学会c#

    学习了c#4.5高级编程这本书,自己喜欢边学边总结边写demo,所以写了这篇文章,包含了大部分的c#编程知识.让你一个demo掌握c#编程,如果有问题可以留言. 此demo主要包括五个文件:Stude ...

  9. Android 通知栏Notification的整合 全面学习 (一个DEMO让你全然了解它)

    在android的应用层中,涉及到非常多应用框架.比如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架.通知机制,ActionBar框架等等. ...

随机推荐

  1. ADO.NET连接数据库DBHelper工具类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. scrapy-redis分布式爬取知乎问答,使用docker布置多台机器。

    先上结果: 问题: 答案: 可以看到现在答案文档有十万多,十万个为什么~hh 正文开始: 分布式爬虫应该是在多台服务器(A B C服务器)布置爬虫环境,让它们重复交叉爬取,这样的话需要用到状态管理器. ...

  3. python装饰器见解笔记

    def zsq(fun): def zsq_n(*args,**kwargs) print('这是装饰器需要运行内容') r = fun(*args,**kwargs) print('在被装饰函数执行 ...

  4. 为.net Core 3.0 WebApi 创建Linux守护进程

    前言 我们一般可以在Linux服务器上执行 dotnet <app_assembly.dll> 命令来运行我们的.net Core WebApi应用.但是这样运行起来的应用很不稳定,关闭终 ...

  5. R时间序列分析实例

    一.作业要求 自选时间序列完成时间序列的建模过程,要求序列的长度>=100. 报告要求以下几部分内容: 数据的描述:数据来源.期间.数据的定义.数据长度. 作时间序列图并进行简单评价. 进行时间 ...

  6. C++ 函数模板/类模板

    #include <iostream> #include <vector> using namespace std; template < class T > // ...

  7. Spark实战--搭建我们的Spark分布式架构

    Spark的分布式架构 如我们所知,spark之所以强大,除了强大的数据处理功能,另一个优势就在于良好的分布式架构.举一个例子在Spark实战--寻找5亿次访问中,访问次数最多的人中,我用四个spar ...

  8. linux相关的帮助文档

    几乎所有linux发行版都会提供大量的有用的文档. 手册页 linux发行版包含了有关常用命令.系统调用和库函数的手册页.手册页被分成不同的章节并分别标以序号: Section      名称     ...

  9. vue中的$props、$attrs和$listeners研究 [包装iview组件]

    $props:当前组件接收到的 props 对象.Vue 实例代理了对其 props 对象属性的访问. $attrs:包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 ...

  10. Antd 表格内通过rowClassName实现隔行变色的显示方法(转载)

    ant design中 table组件很方便,在项目中遇到了需要实现奇偶行颜色不同以方便阅读的功能,主要用到了rowClassName这一api,通过判断index的奇偶来实现不同的样式分配. row ...