javascript - 提高精灵绘制性能
问题描述
我有这个函数来绘制一个精灵对象(它只是一个具有像素值数组的对象):
this.draw = (ctx, x, y, scale) => {
let i = 0;
let startIndex, red, green, blue, alpha, currentX, currentY;
while(i < this.size.width * this.size.height){
startIndex = i * 4;
red = this.pixArray[startIndex];
green = this.pixArray[startIndex + 1];
blue = this.pixArray[startIndex + 2];
alpha = this.pixArray[startIndex + 3];
// Draw, but not if the pixel is invisible
if(alpha != 0){
ctx.fillStyle = `rgba(${red}, " + ${green} + ", " + ${blue} + ", " + ${alpha / 255.0} + ")`;
currentX = i % this.size.width;
currentY = (i - currentX) / this.size.width;
ctx.fillRect(Math.round(x + (currentX * scale)), Math.round(y + (currentY * scale)),
Math.round(scale), Math.round(scale));
}
i++;
}
}
唯一缺少的是pixArray
,它是一个像素值的 Uint8Array。
但是,性能相当糟糕。我发现画布更改状态 ( ctx.fillStyle
) 会丢失一些性能,但有必要每次迭代都修改它。即使 fillStyle 保持不变,性能仍然无法接受。我意识到我可以选择或预渲染,但我希望避免这种情况。
解决方案
使用 anImageData
将您的数组直接传送到临时画布,然后在一次操作中以适当的比例将其绘制到目标画布:
const { width, height } = this.size;
const tCan = document.createElement('canvas');
// block scope to clean up temporary variables
{
const tCtx = tCan.getContext('2d');
const imgData = tCtx.createImageData(width, height);
tCan.width = width;
tCan.height = height;
imgData.data.set(this.pixArray);
tCtx.putImageData(imgData, 0, 0);
}
this.draw = (ctx, x, y, scale) => {
ctx.drawImage(tCan, x, y, Math.round(width * scale), Math.round(height * scale));
};
推荐阅读
- c# - Unity3D ArgumentOutOfRangeException:索引超出范围
- ruby-on-rails - 获取所有没有孩子的记录,即使它们存在于elasticsearch中
- git - 在预提交挂钩上检测文件模式更改
- bash - Ansible:在任务中访问 Shell Var
- sqlite - Flutter - 将自己的 SQLite .db 文件放在哪里?
- javascript - 如何分别设置占位符样式和输入文本数据方向?其中一个 RTL 另一个 LTR
- sql-server - T-SQL:行号仅适用于具有填充字段的行
- javascript - Internet Explorer 在核心 Vue.js 文件中发现错误
- python - 在 python 中使用多处理模拟并发客户端
- json - 从 JSON(非 iso 类型)解码日期 - Swift,可解码