【发布时间】:2019-02-19 10:49:17
【问题描述】:
我有一种方法可以在使用requestAnimationFrame 进行下一次重绘之前在Canvas 内渲染一个矩形矩阵。我正在努力实现最佳性能。我解决这个问题的第一个方法是在Canvas 中实时创建矩形。
render(display: PanelDisplay): void {
const ctx = this.parameters.canva.getContext("2d");
const widthEachBit = Math.floor(this.parameters.canva.width / display[0].length);
const heightEachBit = Math.floor(this.parameters.canva.height / display.length);
ctx.lineWidth = 1;
ctx.strokeStyle = this.parameters.colorStroke;
for(var i = 0; i < display.length; i++) {
for(var j = 0; j < display[i].length; j++) {
const x = j*widthEachBit;
const y = i*heightEachBit;
ctx.beginPath();
ctx.fillStyle = display[i][j] == 1 ? this.parameters.colorBitOn : this.parameters.colorBitOff;
ctx.rect(x, y, widthEachBit, heightEachBit);
ctx.fill();
ctx.stroke();
}
}
}
这样做会导致 3k 元素矩阵的性能平庸:
- 铬:20-30 fps
- 火狐:40 fps
作为第二种方法,我决定预渲染这两个矩形并使用drawImage 在Canvas 上渲染它们:
render(display: PanelDisplay): void {
const ctx = this.parameters.canva.getContext("2d");
const widthEachBit = Math.floor(this.parameters.canva.width / display[0].length);
const heightEachBit = Math.floor(this.parameters.canva.height / display.length);
// Render the different canvas once before instead of recalculating every loop
const prerenderedBitOn = this._prerenderBit(this._prerenderedOn, widthEachBit, heightEachBit, this.parameters.colorBitOn);
const prerenderedBitOff = this._prerenderBit(this._prerenderedOff, widthEachBit, heightEachBit, this.parameters.colorBitOff);
for(var i = 0; i < display.length; i++) {
for(var j = 0; j < display[i].length; j++) {
const x = j*widthEachBit;
const y = i*heightEachBit;
ctx.drawImage(display[i][j] == 1 ? prerenderedBitOn : prerenderedBitOff, x, y);
}
}
}
private _prerenderBit(canvas: HTMLCanvasElement, widthEachBit: number, heightEachBit: number, color: string) {
canvas.width = widthEachBit;
canvas.height = heightEachBit;
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.fillStyle = color;
ctx.rect(0, 0, widthEachBit, heightEachBit);
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = this.parameters.colorStroke;
ctx.stroke();
return canvas;
}
这样做的结果我在 Firefox 中得到了更好的结果,而在 Chrome 中得到了最差的结果:
- 铬:10 fps
- 火狐:50 fps
我不太确定我应该如何解释这些结果。作为第三种方法,我正在考虑预先创建 n Canvas 其中 n 是矩阵的大小,并且仅在下一次重绘之前更新需要更新的那些。在此之前,我想听听您的意见,为什么我在一个浏览器上预渲染得到更好的结果,而在另一个浏览器上预渲染得到最差的结果。我还希望获得任何反馈以获得更好的性能。如有必要,我可以提供性能堆栈跟踪。
【问题讨论】:
标签: javascript typescript google-chrome firefox canvas