动画原理——边界

书籍名称: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

 

posted on 2015-01-28 09:33  吹过的风  阅读(161)  评论(0编辑  收藏  举报