javascript画布动画效果

时间:2015-08-25 21:33:50

标签: javascript html5 canvas

我目前正试图弄清楚如何在每一行中然后回来改变画布中的弧线。 假设我有像这样的弧线

 * * * *
 * * * *
 * * * *

我想做的是做动画,其执行如下

* * * *       * * * *     * * * *    * * * *   o o o o   * * * * 
* * * *       * * * *     * * * *    o o o o   * * * *   * * * *
* * * *       * * * *     o o o o    * * * *   * * * *   * * * *
* * * *       o o o o     * * * *    * * * *   * * * *   * * * *

到目前为止,我刚刚使用

在画布上绘制了弧线
      var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext("2d");
canvas.width = 280;
canvas.height = 100;
var x = 18;
var y = 15;
var rows_x=1;
var rows_y=9;
for (var i = 1; i < 37; i++) {
    ctx.beginPath();
    ctx.arc(x, y, 5, 0, 2 * Math.PI);

    ctx.stroke();
    x += 30;
    if (i % 9 === 0) {
        x = 18;
        y += 25;
    }
}
x = 18;
y = 15;

function large() {
    ctx.clearRect(0, 0, 280, 100);
    for (var i = 1; i < 37; i++) {
        ctx.beginPath();
        if (i >rows_x&& i <= 9) {
            ctx.arc(x, y, 10, 0, 2 * Math.PI);
            ctx.fillStyle = 'green';
            ctx.fill();
           rows_x += 9;
            rows_y += 10;

        }
     else {
        ctx.arc(x, y, 5, 0, 2 * Math.PI);
        ctx.stroke();

    }
    x += 30;
    if (i % 9 == 0) {
        x = 18;
        y += 25
    }
}}


setInterval(large,1000)

这个我的代码有一些小故障,但这并不重要。弧的大小之间的变化是即时的,这意味着它不是动画或至少看起来不像那样,在这种情况下如何实现动画效果?

1 个答案:

答案 0 :(得分:0)

您可以使用 setTimout()功能和递归调用来执行动画。

修改

要执行某些动画过渡,您可以使用Covariance and Contravariance in Generics方法,这是在下次重新绘制之前更新动画的有用方法。

所以,我已经制作了一个可以处理任意行数的通用代码。

      //Retrieve context
  var context = document.querySelector('#canvas').getContext('2d');

  var count = 0;
  var toRadius = 0;
  var line_drawn = 0;
  //Enter a number of line
  var number_line = 5;

  //Init function to buil our grid
  function init(a){
    var x = 10;
    var y = 10;
    //Calculate size of the grid
    var size = Math.pow(number_line,2);
    //Build our grid 4x4
    for (var i = 0; i < size; ++i){
      context.beginPath();
      context.arc(x, y, 5, 0, 2 * Math.PI);
      context.stroke();
      x += 30;
      ++count;
      count === number_line
      ? (count = 0, y += 25, x = 10)
      : y;
    }
    //Call our draw function, start to fill bottom lane
    draw(10, 10 + 25 * a)
  }


  function change(iterator){
    setTimeout(function(){
      //Reset our canvas
      context.clearRect(0,0,600,600);
      //Calculate the index of the new line that must be filled
      var index = number_line - 1 - iterator;
      //Re-build our grid and fill the new line
      init(index);
    }, 500);
  }

  function circle(x, y, radius){
    context.arc(x, y, radius, 0, 2 * Math.PI);
    context.fillStyle = 'green';
    context.fill();
    radius++;
    if (radius < 11){
      window.requestAnimationFrame(function(){
        circle(x, y, radius);
      });
    }
  }


  function draw(x, y) {
    context.beginPath();
    //Use requestAnimationFrame
    window.requestAnimationFrame(function(){
      circle(x, y, toRadius);
    });
    ++count;
    //If we haven't draw all the line
    if (count < number_line) {
      //draw the next circle
      draw(x+30, y);
    } else {
      count = 0;
      ++line_drawn;
      line_drawn < number_line + 1
      ? change(line_drawn)
      : ( line_drawn = 0, change(line_drawn) );
    }
  }

  //Start to build the grid
  init(number_line - 1);

在你的HTML中:

<canvas id="canvas" width="600px" height="600px"></canvas>

您可以在此处看到window.requestAnimationFrame()