Ad

Is It Possible To Draw A Big Number Of Simple Geometric Figures In HTML5.canvas?

- 1 answer

I have this awesome piece of code.

The idea, as you can imagine,is to draw a grid of rectangles. I want a big grid, let's say 100 X 100 or more.

However, when i run the awesome piece of code for the desired size (100X 100), my browser crashes.

How can i achieve that?

* please note: when i say 100X100 i mean the final number of rectangles (10k) not the size of the canvas.

thank u

function init() {        
    var cnv = get('cnv');
    var ctx = cnv.getContext('2d');
    var ancho = 12; // ancho means width
    var alto = 12;  // alto means height
    ctx.fillStyle = randomRGB();

    for (var i = 0; i < cnv.width; i+= ancho) {
        for (var j = 0; j < cnv.height; j+= alto) {
            //dibujar means to draw, rectangulo means rectangle
            dibujarRectangulo(i+ 1, j+1, ancho, alto, ctx); 
        }
    }
}

function dibujarRectangulo(x, y, ancho, alto, ctx) {
    ctx.rect(x, y, ancho, alto);      
    ctx.fill();
    ctx.closePath();
}  
Ad

Answer

16,384 boxes on the wall

As I said in the comment its easy to draw a lot of boxes, it is not easy to have them all behave uniquely. Anyways using render to self to duplicate boxes exponential there are 128 * 128 boxes so that's 16K, one more iteration and it would be 64K boxes.

Its a cheat, I could have just drawn random pixels and called each pixel a box.

Using canvas you will get upto 4000 sprites per frame on a top end machine using FireFox with each sprite having a location, center point, rotation, x and y scale, and an alpha value. But that is the machine going flat out.

Using WebGL you can get much higher but the code complexity goes up.

I use a general rule of thumb, if a canva 2D project has more than 1000 sprites then it is in need of redesign.

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

/** CreateImage.js begin **/
var createImage = function (w, h) {
    var image = document.createElement("canvas");
    image.width = w;
    image.height = h;
    image.ctx = image.getContext("2d");
    return image;
}
/** CreateImage.js end **/
/** FrameUpdate.js begin **/
var w = canvas.width;
var h = canvas.height;
var cw = w / 2;
var ch = h / 2;
var boxSize = 10;
var boxSizeH = 5;
var timeDiv = 1.2;
var bBSize = boxSize * 128; // back buffer ssize
var buff = createImage(bBSize, bBSize);
var rec = createImage(boxSize, boxSize);
var drawRec = function (ctx, time) {
    var size, x, y;
    size = (Math.sin(time / 200) + 1) * boxSizeH;
    ctx.fillStyle = "hsl(" + Math.floor((Math.sin(time / 500) + 1) * 180) + ",100%,50%)";
    ctx.strokeStyle = "Black";
    ctx.setTransform(1, 0, 0, 1, 0, 0)
    ctx.clearRect(0, 0, boxSize, boxSize);
    x = Math.cos(time / 400);
    y = Math.sin(time / 400);
    ctx.setTransform(x, y, -y, x, boxSizeH, boxSizeH)
    ctx.fillRect(-boxSizeH + size, -boxSizeH + size, boxSize - 2 * size, boxSize - 2 * size);
    ctx.strokeRect(-boxSizeH + size, -boxSizeH + size, boxSize - 2 * size, boxSize - 2 * size);
}
function update(time) {
    var fw, fh, px, py, i;
    time /= 7;
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, w, h);
    drawRec(rec.ctx, time);
    time /= timeDiv;
    buff.ctx.clearRect(0, 0, bBSize, bBSize)
    buff.ctx.drawImage(rec, 0, 0);
    buff.ctx.drawImage(rec, boxSize, 0);

    fw = boxSize + boxSize; // curent copy area width
    fh = boxSize; // curent copy area height
    px = 0; // current copy to x pos
    py = boxSize; // current copy to y pos
    buff.ctx.drawImage(buff, 0, 0, fw, fh, px, py, fw, fh); // make square
    for (i = 0; i < 6; i++) {
        drawRec(rec.ctx, time);
        time /= timeDiv;
        buff.ctx.drawImage(rec, 0, 0);
        fh += fh; // double size across
        px = fw;
        py = 0;
        buff.ctx.drawImage(buff, 0, 0, fw, fh, px, py, fw, fh); // make rec
        drawRec(rec.ctx, time);
        time /= timeDiv;
        buff.ctx.drawImage(rec, 0, 0);
        fw += fw; // double size down
        px = 0;
        py = fh;
        buff.ctx.drawImage(buff, 0, 0, fw, fh, px, py, fw, fh);
    }
    // draw the boxes onto the canvas,
    ctx.drawImage(buff, 0, 0, 1024, 1024);
    requestAnimationFrame(update);
}
update();
.canv {
  width:1024px;
  height:1024px;
}
<canvas id="can" class = "canv" width=1024 height=1024></canvas>

Ad
source: stackoverflow.com
Ad