zoukankan      html  css  js  c++  java
  • 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 {
                 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();
    }
    
  • 相关阅读:
    微服务实战(三):深入微服务架构的进程间通信
    微服务实战(二):使用API Gateway
    微服务实战(一):微服务架构的优势与不足
    函数声明与函数表达式
    CSS样式优先级
    iframe框架及优缺点
    JS事件流模型
    JS事件冒泡及阻止
    浏览器重绘与回流
    浏览器渲染与内核
  • 原文地址:https://www.cnblogs.com/jaycethanks/p/12060812.html
Copyright © 2011-2022 走看看