2

I made a grid for my background. I was able to make a grid using for loops on the X and Y to draw a square.

Is there a way to animate the grid to move on x and y using +=1 on both axes?

I was thinking to parent the grid into one big layer and animate the layer instead animating each square.

http://jsbin.com/emexaz/1/edit

EDIT: I'm trying to figure out using context.translate. but every interval per second(assuming setInterval's milisecond is to 1000), it doubles the value.

1 Answer 1

2

Here's how to loop a grid in canvas

There are several ways to draw a moving grid. This is one of them.

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/AjZhD/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var w=canvas.width;
    var h=canvas.height;
    var offsetX=0;
    var offsetY=0;
    var rectX=0;
    var rectY=0;

    setInterval(function(){drawGrid();},100);

    function drawGrid(){

      // move the grid
      offsetX+=5;
      offsetY+=5;
      if(offsetX==20){offsetX=0;}
      if(offsetY==20){offsetY=0;}
      rectX+=5;
      rectY+=5;
      if(rectX==w){rectX=0;}
      if(rectY==h){rectY=0;}

      ctx.save();
      ctx.clearRect(0,0, w, h);
      ctx.strokeStyle="gray";
      ctx.beginPath();
      // vertical grid lines
      for(var x=offsetX;x<w;x+=20){
            ctx.moveTo(x,0);
            ctx.lineTo(x,h);    
      }
      // horizontal grid lines
      for(var y=offsetY;y<h;y+=20){
            ctx.moveTo(0,y);
            ctx.lineTo(w,y);    
      }
      // "moving" rect
      ctx.fillStyle="red";
      ctx.rect(rectX-4,rectY-4,8,8);

      ctx.stroke();
      ctx.fill();
      ctx.restore();

  }

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

[edit for more details of how the code works]

Can do…here’s a more detailed explanation.

These var’s will let us move our gridlines right and down the canvas. They tell us where to draw the next frame of the grid and the next red rectangle:

    var offsetX=0;
    var offsetY=0;
    var rectX=0;
    var rectY=0;

Then setInterval is a loop that just calls drawGrid() every 100 milliseconds.

BTW, Loktar is entirely correct that for anything more than quick tests, you will want to use requestAnimationFrame instead of setInterval. requestAnimation frame has built in optimizations that increase performance and reduce resource usage.

    // repease drawGrid() every 100 milliseconds
    setInterval(function(){drawGrid();},100);

In drawGrid(), we increase offsetX/Y and rectX/Y which causes us to begin drawing our grid to the right and downward. Notice that after moving 20px, the grid is basically back in the same visual position as when we started! This allows us to simply reset our movement offsets back to 0 and create the visual illusion that the grid is marching more than 1 square right/down. The rectX/Y does continue right/down the grid however (adds to the illusion of movement).

      // move the grid
      offsetX+=5;
      offsetY+=5;
      if(offsetX==20){offsetX=0;}
      if(offsetY==20){offsetY=0;}
      rectX+=5;
      rectY+=5;
      if(rectX==w){rectX=0;}
      if(rectY==h){rectY=0;}

Finally we just draw the grid. First we draw the vertical lines until we reach the end of the canvas. Then the horizontal lines. And finally we draw the red rectangle that creates the visual illusion that the grid moves more than 1 grid square right/down.

      for(var x=offsetX;x<w;x+=20){
            ctx.moveTo(x,0);
            ctx.lineTo(x,h);    
      }
      // horizontal grid lines
      for(var y=offsetY;y<h;y+=20){
            ctx.moveTo(0,y);
            ctx.lineTo(w,y);    
      }
      // "moving" rect
      ctx.fillStyle="red";
      ctx.rect(rectX-4,rectY-4,8,8);

Depending on what you want the moving grid for, there are ways to make the grid fly by faster and more smoothly. Loktar described using requestAnimationFrame which does a better job than setInterval. If you want really fast and smooth, you can simply save an image of the complete grid and move that image instead of redrawing all the grid lines. Saving an image for reuse is called caching.

If you cache a grid that’s 1 grid square wider and 1 square taller than the canvas, you can reuse our visual illustion. You would start the animation with the oversized grid hanging further left and further top than the canvas. Then with each animation frame you would move the grid 1px right/down. After 20px, the cached image would be exactly aligned with the top/left of the canvas. Then you just move the cached grid to it’s starting position left and top of the canvas. And then just repeat the animation! Very fast, Very smooth.

Sign up to request clarification or add additional context in comments.

3 Comments

Nice demo +1! Here's an updated fiddle that uses requestAnimationFrame Id always recommend using requestAnimationFrame, but if for some reason you can you should use setTimeout since its better than setInterval jsfiddle.net/loktar/AjZhD/1 You should notice an increase in how smooth it animates now.
This is great! I wish you can explain this for me. kinda new in javascript and HTML5.
Can do...see my edit for a more detailed explanation of how the code works. And Keep coding JS+HTML5...a fantastic combination!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.