使用请求动画帧为矩形的平移设置动画

Using Request animation frame to animate Translate of a rectangle

首先我创建了 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();
})();

因为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

translate(x, y)-方法移动当前帧的视点。该方法不会在渲染后重置变换矩阵。 因此,如果您想每帧将矩形移动一个像素,则必须每帧调用 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();