The rest is simple. You just need to apply the game loop to the canvas. We've already encountered this a few times; you create a function called animate() and let it run in a continuous loop:
function animate() {
planes.clearPlanes(contextPlane);
planes.items.forEach(function(el) {
planes.updatePlane(el);
planes.drawPlane(contextPlane, el.x, el.y);
});
requestID = requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
Note, that we added the used functions to the planes object as well, to keep all plane-related function code together.
First, we clear the canvas. planes.clearPlanes() literally just clears the context we pass to it.
Then we iterate through the planes.items array holding all planes and update each plane with planes.updatePlane(). We pass it the respective plane and it either moves the x and y coordinates to the start if the plane has reached its destination or it moves them to the next way point coordinate:
updatePlane: function(plane) {
plane.currentIndex++;
if (plane.currentIndex >= plane.wayPoints.length) {
plane.currentIndex = 0;
plane.x = plane.startX;
plane.y = plane.startY;
} else {
plane.x = plane.wayPoints[plane.currentIndex].x;
plane.y = plane.wayPoints[plane.currentIndex].y;
}
}
The use of currentIndex should become clearer here. It keeps track of where each plane is on its path as well as moving the plane forward by one way point on each update.
Finally, we draw the plane (this is where we realize we haven't built an actual plane but a tomato colored circle):
drawPlane: function(ctx, x, y) {
ctx.beginPath();
ctx.fillStyle = 'tomato';
ctx.arc(x, y, 1, 0, 2*Math.PI);
ctx.fill();
}
Finally, you kick it off with requestAnimationFrame(). You can use setInterval() but you should use requestAnimationFrame() instead. It will allow the browser to choose the best time to trigger its callback before the next repaint. This is much more economical compared to the brute force setInterval(). It also has the additional benefit of interrupting the loop when the browser tab the app runs on is not in focus. Note also, that we save the requestID of each loop. You might remember that we use this unique ID to cancel the current loop with cancelAnimationFrame(requestID) when the user presses a button to set off a new loop.
Done. Well done.