Search code examples
javascriptcanvassetintervalanimatedrect

Use setInterval to infinitely draw rectangles


I'm trying to learn how to learn basic animation using ONLY canvas with the setInterval function. I'm trying to draw a simple rectangle to the screen and move it to the right 1 pixel every 100 milliseconds. However when I do it paints over the previous rectangle. I called clearRect() but that doesn't seem to do anything.

How can I make this rectangle smoothly travel across the screen without leaving a trail? Also if there is a better way to do this rather than using clearRect() and translate() please do share.

var ctx = document.getElementById('mycanvas').getContext('2d');
var a = setInterval(draw,100);

var x = 50;
function draw()
{
    ctx.clearRect(0,0,300,300);
    ctx.translate(1,0);
    ctx.rect(x,50,50,50);
    ctx.stroke();
}

Solution

  • You can do it two different ways:

    You can continue to use rect() and stroke(), but you need to call beginPath() beforehand. When you call methods like rect(), a list, called the "path," is kept of all of the shapes, or "subpaths," that you've created. Then, when you call stroke(), the entire path is drawn. Thus, even if you clear the screen, all of the past rectangles are still remembered in the path, and drawn again. beginPath() clears that list.

    var x = 50;
    function draw() {
        ctx.clearRect(0, 0, 300, 300);
        ctx.beginPath();
        ctx.rect(x, 50, 50, 50);
        ctx.stroke();
        x++;
    }
    

    Or, you can combine the rect() and stroke() into one line, and not need to call beginPath(). That's because the rectangle is both created and drawn at the same time, and isn't put in the list.

    var x = 50;
    function draw() {
        ctx.clearRect(0, 0, 300, 300);
        ctx.strokeRect(x, 50, 50, 50);
        x++;
    }
    

    Either way, I advise incrementing x instead of using translate(), because translate() basically moves the imaginary "pen" that is drawing on the canvas. So if you translate(50, 50), and then you try to draw a rectangle at (0, 0) on the canvas, it will actually be at (50, 50).

    As Microsoft puts it on MSDN, "The translate method effectively remaps the (0,0) origin on a canvas."

    If you repeatedly do that, it will become difficult to keep track of where you're actually drawing.