• 动画原理——边界


    书籍名称:HTML5-Animation-with-JavaScript

    书籍源码:https://github.com/lamberta/html5-animation

    1.判断球体是否出界程序

    一.画板的边界就是整个画板,也就是画板的形成的矩形。

    var left = 0,
     top = 0,
     right = canvas.width,
     bottom = canvas.height;

    二.判断一个球体是否跑出边界,要考虑球的半径,位置,和边界。用代码表示,if中的条件,分别对应右左上下的出界条件。

    if (ball.x – ball.radius > canvas.width ||
     ball.x + ball.radius < 0 ||
     ball.y – ball.radius > canvas.height ||
     ball.y + ball.radius < 0) {
     balls.splice(balls.indexOf(ball), 1);
    }

    三.判断球体出界程序

    01-removal.html

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Removal</title>
        <link rel="stylesheet" href="../include/style.css">
      </head>
      <body>
        <header>
          Example from <a href="http://amzn.com/1430236655?tag=html5anim-20"><em>Foundation HTML5 Animation with JavaScript</em></a>
        </header>
        <canvas id="canvas" width="400" height="400"></canvas>
        <textarea id="log"></textarea>
    
        <script src="../include/utils.js"></script>
        <script src="./classes/ball.js"></script>
        <script>
        window.onload = function () {
          var canvas = document.getElementById('canvas'),
              context = canvas.getContext('2d'),
              log = document.getElementById('log'),
              balls = [],
              numBalls = 10;
    
          for (var ball, i = 0; i < numBalls; i++) {
            ball = new Ball(20);
            ball.id = "ball" + i;
            ball.x  = Math.random() * canvas.width;
            ball.y  = Math.random() * canvas.height;
            ball.vx = Math.random() * 2 - 1;
            ball.vy = Math.random() * 2 - 1;
            balls.push(ball);
          }
    
          function draw (ball, pos) {
            ball.x += ball.vx;
            ball.y += ball.vy;
            if (ball.x - ball.radius > canvas.width ||
                ball.x + ball.radius < 0 ||
                ball.y - ball.radius > canvas.height ||
                ball.y + ball.radius < 0) {
              balls.splice(pos, 1); //remove ball from array
              if (balls.length > 0) {
                log.value = "Removed " + ball.id;
              } else {
                log.value = "All gone!";
              }
            }
            ball.draw(context);
          }
    
          (function drawFrame () {
            window.requestAnimationFrame(drawFrame, canvas);
            context.clearRect(0, 0, canvas.width, canvas.height);
    
            var i = balls.length;
            while (i--) {
              draw(balls[i], i);
            }
          }());
        };
        </script>
      </body>
    </html>
    View Code

    2.重新生成已经出界的对象

    02-fountain.html

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Fountain</title>
        <link rel="stylesheet" href="../include/style.css">
      </head>
      <body>
        <header>
          Example from <a href="http://amzn.com/1430236655?tag=html5anim-20"><em>Foundation HTML5 Animation with JavaScript</em></a>
        </header>
        <canvas id="canvas" width="400" height="400"></canvas>
    
        <script src="../include/utils.js"></script>
        <script src="./classes/ball.js"></script>
        <script>
        window.onload = function () {
          var canvas = document.getElementById('canvas'),
              context = canvas.getContext('2d'),
              balls = [],
              numBalls = 80,
              gravity = 0.5;
    
          for (var ball, i = 0; i < numBalls; i++) {
            ball = new Ball(2, Math.random() * 0xffffff);
            ball.x  = canvas.width / 2;
            ball.y  = canvas.height;
            ball.vx = Math.random() * 2 - 1;
            ball.vy = Math.random() * -10 - 10;
            balls.push(ball);
          }
    
          function draw (ball) {
            ball.vy += gravity;
            ball.x += ball.vx;
            ball.y += ball.vy;
            if (ball.x - ball.radius > canvas.width ||
                ball.x + ball.radius < 0 ||
                ball.y - ball.radius > canvas.height ||
                ball.y + ball.radius < 0) {
              ball.x = canvas.width / 2;
              ball.y = canvas.height;
              ball.vx = Math.random() * 2 - 1;
              ball.vy = Math.random() * -10 - 10;
            }
            ball.draw(context);
          }
    
          (function drawFrame () {
            window.requestAnimationFrame(drawFrame, canvas);
            context.clearRect(0, 0, canvas.width, canvas.height);
    
            balls.forEach(draw);
          }());
        };
        </script>
      </body>
    </html>
    View Code

    3.无限屏幕

    这个概念很简单,是对重新生成方法的拓展。就是当目标从右侧出去,他讲从左侧进入。

    03-ship-sim-2.html

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Ship Sim 2</title>
        <link rel="stylesheet" href="../include/style.css">
        <style>
          #canvas {
            background-color: #000000;
          }
        </style>
      </head>
      <body>
        <header>
          Example from <a href="http://amzn.com/1430236655?tag=html5anim-20"><em>Foundation HTML5 Animation with JavaScript</em></a>
        </header>
        <canvas id="canvas" width="400" height="400"></canvas>
        <aside>Press left and right arrow keys to rotate ship, up to add thrust.</aside>
    
        <script src="../include/utils.js"></script>
        <script src="./classes/ship.js"></script>
        <script>
        window.onload = function () {
          var canvas = document.getElementById('canvas'),
              context = canvas.getContext('2d'),
              ship = new Ship(),
              vr = 0,
              vx = 0,
              vy = 0,
              thrust = 0;
    
          ship.x = canvas.width / 2;
          ship.y = canvas.height / 2;
    
          window.addEventListener('keydown', function (event) {
            switch (event.keyCode) {
            case 37:      //left
              vr = -3;
              break;
            case 39:      //right
              vr = 3;
              break;
            case 38:      //up
              thrust = 0.05;
              ship.showFlame = true;
              break;
            }
          }, false);
    
          window.addEventListener('keyup', function () {
            vr = 0;
            thrust = 0;
            ship.showFlame = false;
          }, false);
    
          (function drawFrame () {
            window.requestAnimationFrame(drawFrame, canvas);
            context.clearRect(0, 0, canvas.width, canvas.height);
    
            ship.rotation += vr * Math.PI / 180;
            var angle = ship.rotation, //in radians
                ax = Math.cos(angle) * thrust,
                ay = Math.sin(angle) * thrust,
                left = 0,
                right = canvas.width,
                top = 0,
                bottom = canvas.height;
    
            vx += ax;
            vy += ay;
            ship.x += vx;
            ship.y += vy;
            
            //screen wrapping
            if (ship.x - ship.width / 2 > right) {
              ship.x = left - ship.width / 2;
            } else if (ship.x + ship.width / 2 < left) {
              ship.x = right + ship.width / 2;
            }
            if (ship.y - ship.height / 2 > bottom) {
              ship.y = top - ship.height / 2;
            } else if (ship.y < top - ship.height / 2) {
              ship.y = bottom + ship.height / 2;
            }
            ship.draw(context);
          }());
        };
        </script>
      </body>
    </html>
    View Code

    4.反弹

    一.反弹

    当一个球体的边界碰到左边的边界,重新设置球体的x轴的速度为反向,Y不变,这样就实现了反弹。

    04-bouncing-1.html

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Bouncing 1</title>
        <link rel="stylesheet" href="../include/style.css">
      </head>
      <body>
        <header>
          Example from <a href="http://amzn.com/1430236655?tag=html5anim-20"><em>Foundation HTML5 Animation with JavaScript</em></a>
        </header>
        <canvas id="canvas" width="400" height="400"></canvas>
    
        <script src="../include/utils.js"></script>
        <script src="./classes/ball.js"></script>
        <script>
        window.onload = function () {
          var canvas = document.getElementById('canvas'),
              context = canvas.getContext('2d'),
              ball = new Ball(),
              vx = Math.random() * 10 - 5,
              vy = Math.random() * 10 - 5;
    
          ball.x = canvas.width / 2;
          ball.y = canvas.height / 2;
    
          (function drawFrame () {
            window.requestAnimationFrame(drawFrame, canvas);
            context.clearRect(0, 0, canvas.width, canvas.height);
    
            var left = 0,
                right = canvas.width,
                top = 0,
                bottom = canvas.height;
    
            ball.x += vx;
            ball.y += vy;
    
            if (ball.x + ball.radius > right) {
              ball.x = right - ball.radius;
              vx *= -1;
            } else if (ball.x - ball.radius < left) {
              ball.x = left + ball.radius;
              vx *= -1;
            }
            if (ball.y + ball.radius > bottom) {
              ball.y = bottom - ball.radius;
              vy *= -1;
            } else if (ball.y - ball.radius < top) {
              ball.y = top + ball.radius;
              vy *= -1;
            }
            ball.draw(context);
          }());
        };
        </script>
      </body>
    </html>
    View Code

    二.反弹能量减少

    先前的实例是建立在反弹能量不减少的情况,上例系数为-1,而生活中,反弹都会流失一部分能量,所以系数的绝对值是要小于1的,0.7是一个比较逼真的数字。

    05-bouncing-2.html

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Bouncing 2</title>
        <link rel="stylesheet" href="../include/style.css">
      </head>
      <body>
        <header>
          Example from <a href="http://amzn.com/1430236655?tag=html5anim-20"><em>Foundation HTML5 Animation with JavaScript</em></a>
        </header>
        <canvas id="canvas" width="400" height="400"></canvas>
    
        <script src="../include/utils.js"></script>
        <script src="./classes/ball.js"></script>
        <script>
        window.onload = function () {
          var canvas = document.getElementById('canvas'),
              context = canvas.getContext('2d'),
              ball = new Ball(),
              vx = Math.random() * 10 - 5,
              vy = Math.random() * 10 - 5,
              bounce = -0.7,
              gravity = 0.1;
    
          ball.x = canvas.width / 2;
          ball.y = canvas.height / 2;
    
          (function drawFrame () {
            window.requestAnimationFrame(drawFrame, canvas);
            context.clearRect(0, 0, canvas.width, canvas.height);
    
            var left = 0,
                right = canvas.width,
                top = 0,
                bottom = canvas.height;
    
            vy += gravity;
            ball.x += vx;
            ball.y += vy;
    
            if (ball.x + ball.radius > right) {
              ball.x = right - ball.radius;
              vx *= bounce;
            } else if (ball.x - ball.radius < left) {
              ball.x = left + ball.radius;
              vx *= bounce;
            }
            if (ball.y + ball.radius > bottom) {
              ball.y = bottom - ball.radius;
              vy *= bounce;
            } else if (ball.y - ball.radius < top) {
              ball.y = top + ball.radius;
              vy *= bounce;
            }
            ball.draw(context);
          }());
        };
        </script>
      </body>
    </html>
    View Code
  • 相关阅读:
    指针数组与数组指针
    209. 长度最小的子数组
    面试题 05.08. 绘制直线(位运算)
    1160. 拼写单词
    88. 合并两个有序数组
    80. 删除排序数组中的重复项 II(On)
    python自定义异常和主动抛出异常
    类的构造方法1(类中的特殊方法)
    python之判断一个值是不是可以被调用
    主动调用其他类的成员(普通调用和super方法调用)
  • 原文地址:https://www.cnblogs.com/winderby/p/4254970.html
Copyright © 2020-2023  润新知