简单的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. [每日一题系列] LeetCode 1013. 将数组分成和相等的三个部分

    题目: 给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false. 形式上,如果可以找出索引 i+1 < j 且满足 (A[0] + A[1] + . ...

  2. 2653 区间xor

    前言 这个题目在我之前那篇c++位运算的的随笔中提到过. 有兴趣的话去看看吧! 飞机场:https://www.cnblogs.com/laoguantongxiegogofs/p/12444517. ...

  3. ajax参数contentType与数据提交方式

    使用bootstrapTable时,服务器端无法获取参数(flask,request.form.get方法),检查发现是因为ajax提交的时候,方式是payload,要想用form提交,需要设置con ...

  4. mimtproxy的使用(windows)

    1.安装 pip3 install mitmproxy 或者下载安装指定版本:https://mitmproxy.org/downloads/ 2.配置证书 对于mitmproxy来说,如果想要截获H ...

  5. 《JavaScript 模式》读书笔记(2)— 基本技巧2

    前一篇,简单介绍了一些js代码的基本技巧.那么这篇文章,我们继续后续的内容. 一.for循环 for循环经常用在遍历数组或者类数组对象,如引数(arguments)和HTML容器(HTMLCollti ...

  6. 【Python】2.19学习笔记 成员运算符,身份运算符,运算符优先级

    成员运算符 暂时不会用,等学链表时再补充 \(in\) 与 \(not in\) \(in\):如果在指定序列中找到指定值,则返回\(true\) \(not in\):如果在指定序列中找到指定值,则 ...

  7. 2020年启蒙及小学识字练字APP或小程序测评榜

    语文教学改革后,小学识字练字方面显得越来越重要.而市场上大大小小的识字练字应用琳琅满目,不同的定位,不同的核心功能,不同的费用.应该怎么选呢? 本篇将从多个角度对主流识字练字应用进行评测,评估对象为主 ...

  8. nested exception is java.lang.StackOverflowError解析

    背景介绍: 项目是微服务的,使用docker容器,使用jenkins部署.测试环境有个公共服务一直以来都能正常发布,突然有一天不行了,经常发布失败,然后多发布几次就好了. 报错如下: 是栈溢出了,一般 ...

  9. Django 处理跨域的配置、前台处理ajax

    一. Django处理跨域 跨域的处理方式有很多,使用最多的就是CORS(跨域资源共享),接下来大致提一下django中处理跨域的配置. 首先安装django-cors-headers模块: pip ...

  10. [ICRA 2019]Multi-Task Template Matching for Object Detection, Segmentation and Pose Estimation Using Depth Images

    简介         本文作者提出新的框架(MTTM),使用模板匹配来完成多个任务,从深度图的模板上找到目标物体,通过比较模板特征图与场景特征图来预测分割mask和模板与检测物体之间的位姿变换.作者提 ...