当前位置: 代码迷 >> JavaScript >> 如何一次将多个矩形绘制到画布中?
  详细解决方案

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

热度:47   发布时间:2023-06-07 11:48:48.0

我正在使用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,但动态变化在我的应用程序中计算(因此需要重新渲染它们)。

这需要几十毫秒,本身并不严重。 但是重复调用整个过程,这会显着影响性能,而不是以良好的方式。

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

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

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

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

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

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

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

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

  相关解决方案