夜间模式CodeSnippetStyle:
日间模式CodeSnippetStyle:

0%


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();
}
posted @ 2019-12-18 16:58  暮冬有八  阅读(275)  评论(0编辑  收藏  举报
BACK TO TOP

😀迷海无灯听船行。Github WeChat