使用“请求”动画帧来设置矩形的平移动画

时间:2015-02-16 22:10:47

标签: html5 canvas html5-canvas requestanimationframe

首先,我创建了 Live Code

问题:

我可以在X坐标上制作一个矩形的循环动画吗?

问题:

目前,我的动画只会发生一次。翻译在屏幕外再也看不见了。即便将pos.x重置为零。

(function(){
  var pos =  {x: 0, y:0};
  var c = document.getElementById('day1'),
      ctx = c.getContext('2d');

  function repaint(){
    ctx.fillStyle = 'white'
    ctx.fillRect(0,0,c.width,c.height);
  }

  function draw (){
    //paints over the last square otherwise this will create a ghost or tail effect
    repaint();
    //adds to 1 to translate or resets to 0
    if(pos.x <= 100){
              pos.x++;
    } else {
      pos.x = 0;
      //at the very least this should be drawing a new rect 1 pixel lower than the last
      pos.y++;
    }

    //paints the black rectangle 
    ctx.fillStyle = 'black';
    //moves the position and animates till offscreen
    ctx.translate(pos.x, pos.y);
    ctx.fillRect(0,50,50,50);
    //watch the console.logs()
    console.log(pos);
    window.requestAnimationFrame(draw);
  }

  draw();
})();

2 个答案:

答案 0 :(得分:3)

这是因为tranform()是累积的。即使您重置x transform(),也会继续添加。你可以通过速度的对数增加看出这一点。

如果您绝对想要使用变换,请使用setTransform()代替,这样可以设置绝对位置。

替换此行:

ctx.translate(pos.x, pos.y);

使用:

// the two last arguments (e,f) are for translation
ctx.setTransform(1, 0, 0, 1, pos.x, pos.y);

或者只是跳过使用翻译并直接在x和y处绘制对象。

<强> Updated pen

答案 1 :(得分:2)

translate(x,y)-method移动当前帧的视点。该方法在渲染后不重置变换矩阵。 因此,如果要将矩形每帧移动一个像素,则必须每帧调用translate(1,0)。在100像素之后,如果要循环,则调用translate(-100,0)。

var xCounter = 0;
function draw()
{
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, c.width, c.height);
    if(xCounter <= 100)
    {
        ctx.translate(1, 0);
        xCounter++;
    }
    else
    {
        ctx.translate(-xCounter, 1);
        xCounter = 0;
    }
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, 50, 50);
    window.requestAnimationFrame(draw);
}
draw();

我会避免翻译方法:

function draw()
{
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, c.width, c.height);
    if(pos.x <= 100)
    {
        pos.x++;
    }
    else
    {
        pos.x = 0;
        pos.y++;
    }
    ctx.fillStyle = 'black';
    ctx.fillRect(pos.x, pos.y, 50, 50);
    window.requestAnimationFrame(draw);
}
draw();