3D grid animated

by cvalleskey

HTML

<script src="http://abdiassoftware.com/easycanvas/easyCanvas.1.1.min.js"></script>
<canvas width=800 height=400></canvas>

CSS

body { background: #222; }

JavaScript

var canvas = document.querySelector("canvas"),
    ctx = canvas.getContext("2d"),
    fov = 180,
    viewDist = 4,
    w = canvas.width / 2,
    h = canvas.height / 2,
    angle = -25,
    i, p1, p2,
    grid = 20,
    da = -0.05,
    t = Date.now();

function loop() {

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    ctx.beginPath();
    
    // create vertical lines
    /*for (i = -grid; i <= grid; i++) {
        p1 = rotateX(i, -grid);
        p2 = rotateX(i, grid);
        ctx.moveTo(p1[0], p1[1]);
        ctx.lineTo(p2[0], p2[1]);
    }*/

    // create horizontal lines
    /*for (i = -grid; i <= grid; i++) {
        p1 = rotateX(-grid, i);
        p2 = rotateX(grid, i);
        ctx.moveTo(p1[0], p1[1]);
        ctx.lineTo(p2[0], p2[1]);
    }*/

    //ctx.stroke();
    
    for (i = -grid; i <= grid; i++) {
      for (r = -grid; r <= grid; r++) {

      // Color a random cell
      var cx = i;
      var cy = r + ((Date.now() - t) % 1000)/1000;
      var c1, c2, c3, c4; // corners

      c1 = rotateX(cx, cy);         // upper left corner
      c2 = rotateX(cx + 1, cy);     // bottom right corner
      c3 = rotateX(cx + 1, cy + 1); // bottom right corner
      c4 = rotateX(cx, cy + 1);     // bottom right corner

      ctx.beginPath();
      ctx.moveTo(c1[0], c1[1]);
      ctx.lineTo(c2[0], c2[1]);
      ctx.lineTo(c3[0], c3[1]);
      ctx.lineTo(c4[0], c4[1]);
      ctx.closePath();
      ctx.lineWidth = 4;
      ctx.strokeStyle = 'rgb(200,0,0)';
      ctx.stroke();
      }
    }

    angle += da;
    if (angle < -35 || angle > 35) da = -da;

    requestAnimationFrame(loop);
}
loop();

function rotateX(x, y) {

    var rd, ca, sa, ry, rz, f;

    rd = angle * Math.PI / 180;
    ca = Math.cos(rd);
    sa = Math.sin(rd);

    ry = y * ca;
    rz = y * sa;

    f = fov / (viewDist + rz);
    x = x * f + w;
    y = ry * f + h;

    return [x, y];
}