如何一次将多个矩形绘制到画布中?

时间:2015-08-08 11:52:11

标签: javascript canvas

我使用drawRect将大量(~20000)矩形绘制到HTML5画布上,每个都位于不同的预定位置。我是从循环中做到这一点:

for (var i = 0; i < 100; ++i) {
    for (var j = 0; j < 200; ++j) {
        context.fillStyle = '#000000';
        context.fillRect(i * 8, j * 2, 6, 1);
    }
}

Working demo on JSFiddle

这个片段将100个条形绘制成800px宽的画布,每个画布宽6px,每个画布由多个彼此堆叠的小(1x6)矩形组成:在提供的示例中静态计数为200,但是我的应用程序中的动态变化计数(因此需要重新渲染它们)。

这需要几十毫秒,本身并不严重。但是这整个过程会被重复调用,这会严重影响性能 ,而不是很好。

是否有一个解决方案或解决方法,比如说,在一个画布指令中绘制这样的条形图,希望更好地利用硬件加速?

每个矩形在我的应用程序中都会发光,因此水平切片并不是一个好方法。我已经尝试过使用屏幕外画布,在那里绘图,并将它的图像输出渲染到主画布,但是没有明显的性能提升。

3 个答案:

答案 0 :(得分:2)

您可以像这样初始化有用的变量:

var context = canvas.getContext("2d");
var map = context.getImageData(startX, startY, width, height);

其中canvas是document.getElementById("myCanvas")之类的返回值。

startX是起始点x,startY是起点y。您可以使用0作为它们的值,但我不想假设它从画布的左上角开始。 width是宽度,height是高度。现在,您可以拥有循环和设置值,如下所示:

map.data[4 * index] = r; //red
map.data[4 * index + 1] = g; //green
map.data[4 * index + 2] = b; // blue

完成循环后,保存一些内容,如下所示:

context.putImageData(map, startX, startY);

速度应该提高,因为您只阅读一次并且只绘制一次。关于循环,您只需设置值,与绘制到画布相比,这是一个便宜的操作。因此,这种优化的想法是:一次读取内容,在循环中设置值,只绘制一次,而不是每次获得输入时绘制。您也可以省略阅读相关部分并自行生成数据,但如果您需要了解已经绘制的内容,我决定向您展示如何读取数据。

答案 1 :(得分:2)

让自己成为包含单个全高条的单个(屏幕外)画布图像,然后对于每个动态高度条,只将所需的垂直像素数复制到屏幕画布上。

答案 2 :(得分:0)

看到这看起来某种背景,你将要绘制其他东西,你是否考虑将其转换为静态图像并将画布背景设置为此?您可以关闭/打开背景,或者在画布上绘制的任何内容将与填充/绘制发生的区域中的背景重叠。

当然,如果你要动态调整它,一个单独位于另一个下面的单独的画布元素也是需要考虑的事情。