Прежде всего, я создал Live Code

ВОПРОС:

Могу ли я сделать циклическую анимацию прямоугольника, перемещаемого по координате X?

Проблема:

В настоящее время моя анимация визуально появляется только один раз. Перевод уходит за пределы экрана, чтобы его больше никогда не видели. Даже если позиция 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();
})();
1
Armeen Harwood 17 Фев 2015 в 01:10

2 ответа

Лучший ответ

Это потому, что 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 напрямую.

Обновленное перо

3
user1693593user1693593 16 Фев 2015 в 23:35

Метод 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();

Я бы избегал метода translate:

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();
2
Martin Wantke 17 Фев 2015 в 02:51