title: HTML 5 Canvas Animation - Move multiple objects one after another
body: <p>I have this animation which moves a row of circles from A(x,y) to B(x,y). ButI'm having trouble trying to replicate this into an array of circles where each row moves (one after another) from A to B. However, I also want to maintain the original location of the array so that essentially, it makes a copy of the row and moves the copy. Any help would be greatly appreciated!</p>
  
  <p>EDIT: I have edited the code so that it now has two rows that remain stationary when one is moving - but now, I want to be able to move more than one row (as described in the example below).</p>
  
  <p>EDIT 2: Here's a jsfiddle instead so it's easier to understand what I mean.</p>
  
  <p><a href="https://jsfiddle.net/vLvk1bsc/2/" rel="nofollow">https://jsfiddle.net/vLvk1bsc/2/</a></p>
  
  <p>For example, I want to emulate something like this.</p>
  
  <p>ORIGINAL ----------------- NEW</p>
  
  <ol>
  <li><p>r r r r r r. --------------- A. g g g g g g</p></li>
  <li><p>p p p p p p  ------------   B. r r r r r r</p></li>
  <li><p>g g g g g g  ------------   C. r r r r r r</p></li>
  </ol>
  
  <p>The sequence of the animation would therefore be as follows:</p>
  
  <ol>
  <li><p>3 --- a. A copy of row 3 moves to row A</p></li>
  <li><p>1 --- b. A copy of row 1 moves to row B</p></li>
  <li><p>1 --- c. A copy of row 1 moves to row C</p>
  
  <pre><code>var canvas = document.getElementById("canvas");
  var context = canvas.getContext("2d");
  
  window.requestAnimFrame = (function (callback) {
      return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
          window.setTimeout(callback, 1000 / 60);
      };
  })();
  
  setTimeout(function () {
      draw();
      animate(movingRow2);
  }, 100);
  
  var movingRow = [];
  var frozenRow = [];
  
  var cx = 50;
  var cy = 70;
  
  for (var i = 0; i &lt; 6; i++) {
      movingRow.push({ x: cx, y: cy, borderWidth: 1, color: "orange"});
      frozenRow.push({ x: cx, y: cy, borderWidth: 1, color: "blue"});
  
      cx += 40;
  }
  
  var movingRow2 = [];
  var frozenRow2 = [];
  
  var cx = 50;
  var cy = 110;
  
  for (var i = 0; i &lt; 6; i++) {
      movingRow2.push({ x: cx, y: cy, borderWidth: 1, color: "green"});
      frozenRow2.push({ x: cx, y: cy, borderWidth: 1, color: "pink"});
  
      cx += 40;
  }
  
  function drawCircle(myCircle, context) {
      context.beginPath();
      context.arc(myCircle.x, myCircle.y, 15, 0, 2 * Math.PI);
      context.fillStyle = myCircle.color;
      context.fill();
      context.stroke();
      context.closePath();
  }   
  
  function draw() {
      context.save();
      context.clearRect(0, 0, canvas.width, canvas.height);
  
      for (var i = 0; i &lt; movingRow.length; i++) {
          drawCircle(movingRow[i], context);
          drawCircle(frozenRow[i], context);
  
          drawCircle(movingRow2[i], context);
          drawCircle(frozenRow2[i], context);
     }
  }
  
  var newX = 320;
  var newY = 70;
  
  var pathArray = [];
  
  pathArray.push({
      x: movingRow2[0].x,
      y: movingRow2[0].y
  });
  
  pathArray.push({
      x: newX,
      y: newY
  });
  
  var polyPoints = makePolyPoints(pathArray);
  
  var position = 0;
  var speed = 1;
  
  function animate(m) {
  
      // calculate the new position
      position += speed;
  
      if (position &gt; polyPoints.length - 1) {
          return;
      }
  
      // a single point in the array
      var pt = polyPoints[position];
  
      var step = 0;
  
      // update x and y
      for (var i = 0; i &lt; m.length; i++) {
          m[i].x = pt.x + step;
          m[i].y = pt.y;
  
          step += 40;
      }
  
      draw();
  
      // request new frame
      requestAnimationFrame(function() {
          animate(m);
      });
  }
  
  function makePolyPoints(pathArray) {
  
      // list of points for each frame of the shape
      var points = [];
      // how quickly the transition occurs
      var speed = 150;
  
      for (var i = 1; i &lt; pathArray.length; i++) {
  
          var startPt = pathArray[i - 1];
          var endPt = pathArray[i];
  
          // calculate difference between start and end points 
          var dx = endPt.x - startPt.x;
          var dy = endPt.y - startPt.y;
  
          for (var n = 0; n &lt;= speed; n++) {  
              // calculate the x and y positions for each frame
              var x = startPt.x + dx * n / speed;
              var y = startPt.y + dy * n / speed;
  
              // append the points to the array to be used in the animation
              points.push({
                  x: x,
                  y: y
              });
          }
      }
  
      return points;
  }
  </code></pre></li>
  </ol>