是否有可能在HTML5.canvas中绘制大量简单的几何图形?

时间:2016-01-20 01:54:33

标签: javascript html5 canvas

我有这段很棒的代码。

您可以想象,这个想法是绘制一个矩形网格。我想要一个大网格,比方说100 X 100或更多。

但是,当我运行所需大小的代码(100X 100)时,我的浏览器会崩溃。

我如何实现这一目标?

*请注意:当我说100X100时,我的意思是最终的矩形数(10k)不是画布的大小。

谢谢你

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();
}  

2 个答案:

答案 0 :(得分:2)

dibujarRectanglo()函数调用rect()函数,该函数将一个封闭的矩形子路径添加到当前路径。然后调用fill()函数来填充当前路径。然后调用closePath()函数来关闭子路径,由于子路径已经关闭,因此不执行任何操作。

换句话说,第一个dibujarRectanglo()函数调用是绘制一个包含1个矩形子路径的路径。第二个调用是绘制一个包含2个矩形子路径的路径。第三个调用是绘制一个包含3个矩形子路径的路径。等等。如果循环调用dibujarRectanglo()函数10000次,则总共将绘制1 + 2 + 3 + ... + 10000 = 50005000(即超过5000万)矩形子路径。

dibujarRectangle()函数应该每次都开始一个新的路径。例如......

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

然后10000个调用只绘制10000个矩形子路径,这比绘制5000万个矩形子路径要快得多。

答案 1 :(得分:1)

墙上有16,384个方框

正如我在评论中所说的那样容易画出很多盒子,让它们都表现得很独特并不容易。无论如何使用渲染自我复制框指数有128 * 128个框,所以16K,再迭代一次,它将是64K框。

它是一个骗子,我可以只绘制随机像素并将每个像素称为一个盒子。

使用画布,您将在使用FireFox的顶端机器上每帧获得多达4000个精灵,每个精灵具有位置,中心点,旋转,x和y比例以及alpha值。但那就是机器不断出现。

使用WebGL可以获得更高的代价,但代码复杂性也会提高。

我使用一般经验法则,如果canva 2D项目有超过1000个精灵,则需要重新设计。

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>