代码之家  ›  专栏  ›  技术社区  ›  AlgoRythm

提高sprite绘图性能

  •  1
  • AlgoRythm  · 技术社区  · 7 年前

    我有这个函数来绘制一个sprite对象(它只是一个像素值数组的对象):

    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 ,这是一个uint8像素值数组。

    然而,表现相当糟糕。我发现有些表演是在画布改变的状态下丢失的( ctx.fillStyle ),但每次迭代都需要修改。即使fillstyle保持不变,性能仍然是不可接受的。我知道我可以选择或预渲染,但我希望避免这种情况。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Patrick Roberts Benjamin Gruenbaum    7 年前

    使用一个 ImageData 要直接将数组blit到临时画布,然后在单个操作中将其绘制到具有适当比例的目标画布,请执行以下操作:

    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));
    };
    
    推荐文章