3D grid animated

by Ali Khaled

HTML

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

JavaScript

var canvas = document.querySelector("canvas"),
    ctx = canvas.getContext("2d"),
    fov = 128,
    viewDist = 6,
    w = canvas.width / 2,
    h = canvas.height / 2,
    angle = -27,
    i, p1, p2,
    grid = 10,
    da = 1;

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();
    
    // Color a random cell
    var cx = parseInt(18 * Math.random() - 10, 10);
    var cy = parseInt(18 * Math.random() - 10, 10);
    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.fillStyle = 'rgb(200,0,0)';
    ctx.fill();

    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];
}