Улучшить производительность рисования спрайтов - PullRequest
0 голосов
/ 08 июня 2018

У меня есть эта функция для рисования объекта спрайта (который является просто объектом с массивом значений пикселей):

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 остается неизменным, производительность по-прежнему неприемлема.Я понимаю, что у меня есть возможность или предварительный рендеринг, но я хочу избежать этого.

1 Ответ

0 голосов
/ 08 июня 2018

Используйте 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));
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...