Pointer Lock API(3/3):一个Demo
简单的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的更多相关文章
- Pointer Lock API(2/3):属性、方法、事件
Pointer Lock API 提供了三个属性.两个方法.两个事件 Tabel Of Content 属性 Document.pointerLockElement Document.onpointe ...
- Pointer Lock API(1/3):Pointer Lock 的总体认识
前言 指针锁定(Pointer Lock),以前也叫鼠标锁定,提供了基于鼠标随时间的移动(如deltaΔ)的输入方法,不仅仅是视窗区域鼠标的绝对位置.指针锁定让你能够访问原始的鼠标移动,将鼠标事件的目 ...
- 指针锁定 Pointer Lock API 用法
指针锁定 Pointer Lock API 通过它可以访问原始的鼠标运动(基于指针的相对位移 movementX / movementY),把鼠标事件的目标锁定到一个特定的元素,同时隐藏视图中的指针光 ...
- Pointer Lock
Pointer Lock API 指针锁定(以前叫做 鼠标锁定) 提供了一种输入方法,这种方法是基于鼠标随着时间推移的运动的(也就是说,deltas),而不仅是鼠标光标的绝对位置.通过它可以访问原始的 ...
- Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)
在android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. ...
- 使用android的mediaplayer做成 一个demo,欢迎测试使用
附件是为一个定制视频产品而简单的写了一个demo,用来说明android的mediaplayer是如何使用的. http://files.cnblogs.com/guobaPlayer/palyerD ...
- [置顶]
一个demo学会css
全栈工程师开发手册 (作者:栾鹏) 一个demo学会css css选择器全解 css操作语法全解 学习了css权威指南这本书,自己喜欢边学边总结边写demo,所以写了这篇文章,包含了大部分的css编程 ...
- [置顶]
一个demo学会c#
学习了c#4.5高级编程这本书,自己喜欢边学边总结边写demo,所以写了这篇文章,包含了大部分的c#编程知识.让你一个demo掌握c#编程,如果有问题可以留言. 此demo主要包括五个文件:Stude ...
- Android 通知栏Notification的整合 全面学习 (一个DEMO让你全然了解它)
在android的应用层中,涉及到非常多应用框架.比如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架.通知机制,ActionBar框架等等. ...
随机推荐
- [每日一题系列] LeetCode 1013. 将数组分成和相等的三个部分
题目: 给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false. 形式上,如果可以找出索引 i+1 < j 且满足 (A[0] + A[1] + . ...
- 2653 区间xor
前言 这个题目在我之前那篇c++位运算的的随笔中提到过. 有兴趣的话去看看吧! 飞机场:https://www.cnblogs.com/laoguantongxiegogofs/p/12444517. ...
- ajax参数contentType与数据提交方式
使用bootstrapTable时,服务器端无法获取参数(flask,request.form.get方法),检查发现是因为ajax提交的时候,方式是payload,要想用form提交,需要设置con ...
- mimtproxy的使用(windows)
1.安装 pip3 install mitmproxy 或者下载安装指定版本:https://mitmproxy.org/downloads/ 2.配置证书 对于mitmproxy来说,如果想要截获H ...
- 《JavaScript 模式》读书笔记(2)— 基本技巧2
前一篇,简单介绍了一些js代码的基本技巧.那么这篇文章,我们继续后续的内容. 一.for循环 for循环经常用在遍历数组或者类数组对象,如引数(arguments)和HTML容器(HTMLCollti ...
- 【Python】2.19学习笔记 成员运算符,身份运算符,运算符优先级
成员运算符 暂时不会用,等学链表时再补充 \(in\) 与 \(not in\) \(in\):如果在指定序列中找到指定值,则返回\(true\) \(not in\):如果在指定序列中找到指定值,则 ...
- 2020年启蒙及小学识字练字APP或小程序测评榜
语文教学改革后,小学识字练字方面显得越来越重要.而市场上大大小小的识字练字应用琳琅满目,不同的定位,不同的核心功能,不同的费用.应该怎么选呢? 本篇将从多个角度对主流识字练字应用进行评测,评估对象为主 ...
- nested exception is java.lang.StackOverflowError解析
背景介绍: 项目是微服务的,使用docker容器,使用jenkins部署.测试环境有个公共服务一直以来都能正常发布,突然有一天不行了,经常发布失败,然后多发布几次就好了. 报错如下: 是栈溢出了,一般 ...
- Django 处理跨域的配置、前台处理ajax
一. Django处理跨域 跨域的处理方式有很多,使用最多的就是CORS(跨域资源共享),接下来大致提一下django中处理跨域的配置. 首先安装django-cors-headers模块: pip ...
- [ICRA 2019]Multi-Task Template Matching for Object Detection, Segmentation and Pose Estimation Using Depth Images
简介 本文作者提出新的框架(MTTM),使用模板匹配来完成多个任务,从深度图的模板上找到目标物体,通过比较模板特征图与场景特征图来预测分割mask和模板与检测物体之间的位姿变换.作者提 ...