我有这个功能来绘制一个精灵对象(它只是一个像素值数组的对象):

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保持不变,性能仍然不可接受。我知道我可以选择或预先渲染,但我希望避免这种情况。

最佳答案

使用ImageData将数组直接绘制到临时画布上,然后通过一次操作以适当的比例将其绘制到目标画布上:

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

关于javascript - 提高子画面绘制性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50752542/

10-16 19:33