简单的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. 移动端1px的适配问题

    先看个概念: window.devicePixelRatio = 物理像素 / dips(独立像素) window.devicePixelRatio是设备的物理像素和独立像素的比例,可以叫设备像素比. ...

  2. 用Navicat Premium 连接mysql数据库时报错 -- 1130 Host xxxx is not allowed to connect to this MySQL server

    用Navicat Premium 连接mysql数据库时报错 报错原因:此时的MySQL默认不能远程连接. 解决方案:修改MySQL配置 具体步骤: 1.登陆服务器,进入数据库 mysql -uroo ...

  3. Simulink仿真入门到精通(三) Simulink信号

    3.1 Simulink信号概述 所谓信号,表示一种随着时间而变化的量,在时间轴上的采样时刻都对应有数值. 信号在Simulink中是相当重要的组成部分,有线(line)表示,在模型中穿针引线地将各模 ...

  4. span(行级元素)在不定高的div(块级元素)中垂直居中的方法

    设置父级元素: align-items: center; display: flex;

  5. python3:input() 函数

    一.知识介绍: 1.input() 函数,接收任意输入,将所有输入默认为字符串处理,并返回字符串类型: 2.可以用作文本输入,如用户名,密码框的值输入: 3.语法:input("提示信息:& ...

  6. 英伟达GPU虚拟化---申请英伟达测试License

    此文基于全新的License 2.0系统,针对vGPU License的试用申请以及软件下载和License管理进行了详细的说明,方便今后我们申请测试License,快速验证GPU的功能. 试用步骤: ...

  7. 不要再认为Stream可读性不高了!

    距离Java 8发布已经过去了7.8年的时间,Java 14也刚刚发布.Java 8中关于函数式编程和新增的Stream流API至今饱受"争议". 如果你不曾使用Stream流,那 ...

  8. JDK dump

    1. 查看整个JVM内存状态 jmap -heap 1237(pid) 2.生成dump文件 jmap -dump:file=文件名.dump 1237(pid)

  9. CF1324F Maximum White Subtree 题解

    原题链接 简要题意: 给定一棵树,每个点有黑白两种颜色:对每个节点,求出包含当前节点的连通图,使得白点数与黑点数差最小.输出这些值. F题也这么简单,咳咳,要是我也熬夜打上那么一场...可惜没时间打啊 ...

  10. CF 997A

    You’ve got a string a1,a2,…,an, consisting of zeros and ones.Let’s call a sequence of consecutive el ...