我使用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);
}
}
这个片段将100个条形绘制成800px宽的画布,每个画布宽6px,每个画布由多个彼此堆叠的小(1x6)矩形组成:在提供的示例中静态计数为200,但是我的应用程序中的动态变化计数(因此需要重新渲染它们)。
这需要几十毫秒,本身并不严重。但是这整个过程会被重复调用,这会严重影响性能 ,而不是很好。
是否有一个解决方案或解决方法,比如说,在一个画布指令中绘制这样的条形图,希望更好地利用硬件加速?
每个矩形在我的应用程序中都会发光,因此水平切片并不是一个好方法。我已经尝试过使用屏幕外画布,在那里绘图,并将它的图像输出渲染到主画布,但是没有明显的性能提升。
答案 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)
看到这看起来某种背景,你将要绘制其他东西,你是否考虑将其转换为静态图像并将画布背景设置为此?您可以关闭/打开背景,或者在画布上绘制的任何内容将与填充/绘制发生的区域中的背景重叠。
当然,如果你要动态调整它,一个单独位于另一个下面的单独的画布元素也是需要考虑的事情。