您可以在不使用字符串的情况下设置 HTML 画布样式吗?

Posted

技术标签:

【中文标题】您可以在不使用字符串的情况下设置 HTML 画布样式吗?【英文标题】:Can you set HTML canvas styles without using a string? 【发布时间】:2021-09-13 23:59:19 【问题描述】:

我制作了一个基于网络的概念验证,它在整个屏幕上绘制了数千个彩色 div,并通过在每个动画帧中更改每个 div 的颜色来为整个页面设置动画。 (显然是 JS 完成了这项工作。)令人震惊的是,性能远没有我想象的那么糟糕,但仍然有点糟糕。在使用 Chrome 浏览器分析器进行检查后,我发现性能瓶颈是,not 令人震惊,因为必须通过为每个 div 构建一个字符串来生成 每个 div 的颜色,每个动画帧。字符串连接是出了名的慢。我看到这个 web 应用程序 90% 以上的性能都被一行代码消耗掉了,而且是生成样式颜色字符串的代码。

为清楚起见,这是有问题的行:

// currentBox properties red, green, and blue are simple integers
element.style.backgroundColor =
  `rgb($currentBox.red, $currentBox.green, $currentBox.blue)`

我正在研究在 html 画布上绘图,希望能够用字符串以外的东西定义绘图/填充颜色,以减少这个性能瓶颈。

除了使用字符串之外,还有什么方法可以为 div/canvas 样式(尤其是颜色)着色?还是我需要一直深入到 WebGL 领域之类的?

我引用的是 MDN here。这使得字符串似乎是 CSS 或画布样式的唯一选择。但我希望有人知道另一个技巧。

【问题讨论】:

查看ImageBitmapRenderingContextImageDataImageBitmap 【参考方案1】:

我不确定您指的是什么“字符串”,但是当您通过element.style 属性设置任何内容时,您只能使用字符串,无论是颜色名称red 还是十六进制#FF0000 或RGB @ 987654325@ 它仍然是一个字符串。也许在您的情况下,瓶颈不是“字符串”,而是颜色的生成方式?

查看https://developer.mozilla.org/en-US/docs/Web/CSS/color_value,了解有关不同类型颜色格式的更多信息。

【讨论】:

这是我的恐惧。如果必须始终使用字符串,那么 Web 应用程序可能只是推进该项目的错误位置。我已经根据这个答案更新了原始帖子,使其更加清晰,谢谢。 也许您可以通过element.className 更改颜色而不是通过element.style 更改颜色? (通过 CSS 设置颜色表)【参考方案2】:

这可能只是因为您试图为每帧数千个元素设置动画。这可能是征税。我遇到了只为 500-1000 个元素设置动画的问题。我认为画布会更好地处理该动画。当然,如果没有您的代码,就很难确切地确定您在做什么。我只能提供一个使用 canvas API 在数千个矩形上运行动画的示例。

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const cw = canvas.width = innerWidth;
const ch = canvas.height = innerHeight;
let rectArr = [];

class  Rect 
  constructor(x, y, w, h) 
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.c = '#'+Math.floor(Math.random()*16777215).toString(16);
  
  draw() 
    this.c = '#'+Math.floor(Math.random()*16777215).toString(16);
    ctx.fillStyle = this.c;
    ctx.fillRect(this.x, this.y, this.w, this.h);
  


function createRects() 
  for (let i=0;i<2000;i++) 
    rectArr.push(new Rect(Math.random()*cw, Math.random()*ch, Math.random()*50, Math.random()*20))
  

createRects();

function animate() 
  for (let i=0;i<rectArr.length;i++) 
    rectArr[i].draw();
  


setInterval(animate, 300)
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【讨论】:

我没有展示太多周围的代码,因为问题仅限于浏览器确认的性能瓶颈,仅限于一行,并且似乎仅限于字符串的生成。您的解决方案也会生成/强制字符串值,这可能是您的瓶颈所在。

以上是关于您可以在不使用字符串的情况下设置 HTML 画布样式吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 Google 地图的情况下将纬度/经度转换为 HTML5 坐标?

如何在不损失图像质量的情况下调整图像大小以适合小型 HTML5 画布? [复制]

是否可以在不实际渲染画布的情况下创建画布来提取图像数据?

是否可以在不显示在页面/画布上的情况下获得图形的基数 64(Graph.Js)

p5.j​​s:如何在不改变背景或使用外部画布的情况下在画布形状上打孔?

为啥 2d 画布在不模糊的情况下无法缩放?