我有这段很棒的代码。
您可以想象,这个想法是绘制一个矩形网格。我想要一个大网格,比方说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();
}
答案 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>