0

各正方形が互いの上に描かれた色のレイヤーで構成されている n 行 n 列の正方形のグリッドを描画しようとしています。fillRect() を使用してキャンバスに色を描画すると、問題なく機能し、リソースを大量に消費していないように見えます。ただし、rect() を使用して各正方形の周囲に境界線を追加しようとすると、パフォーマンスが著しく低下します。

以下の関数を呼び出すたびに、clearRect() を使用してキャンバスをクリアします。

問題の機能:

/**
 * Draws an n x n grid of layered color squares of the given width.
 * @param {int} `width`      The width of each square in the grid.
 * @param {int} `leftOffSet` The left margin of the grid.
 * @param {int} `topOffSet`  The top margin of the grid.
 * @param {int} `n`          The dimension of the grid.
 * @param {object} `layers'  A linked-list of color layers.
 */
function drawMap(width, leftOffSet, topOffSet, n, layers) {
    for (var i = 0; i < n; i++) {
        for (var j = 0; j < n; j++) {

            var currentLayer = layers[i][j];
            while (typeof currentLayer.tile !== 'undefined') {
                var bg = currentLayer.tile.background;

                context.fillStyle = 'rgba(' + bg.r + ',' + bg.g + ',' + bg.b + ',' + bg.a + ')';
                context.fillRect(i * width + leftOffSet, j * width + topOffSet, width, width);

                currentLayer = currentLayer.next;
            }

            // BOTTLE NECK APPEARS TO BE HERE
            /*context.beginPath();
            context.rect(i * width + leftOffSet, j * width + topOffSet, width, width);
            context.stroke();
            context.closePath();*/

        }
    }
}

ボトルネックをコメントアウトすると、パフォーマンスは問題ありませんが、そのブロックのコメントを外すとすぐにパフォーマンスが低下します。これを最適化する方法はありますか?

4

1 に答える 1

1

context.stroke をループの外に置く

個々の rect を定義するときにストロークする必要はありません。最後に context.stroke を 1 回実行するだけです。

function drawMap(width, leftOffSet, topOffSet, n, layers) {

    // begin a new path
    context.beginPath();

    for (var i = 0; i < n; i++) {
        for (var j = 0; j < n; j++) {

            var currentLayer = layers[i][j];
            while (typeof currentLayer.tile !== 'undefined') {
                var bg = currentLayer.tile.background;

                context.fillStyle = 'rgba(' + bg.r + ',' + bg.g + ',' + bg.b + ',' + bg.a + ')';
                context.fillRect(i * width + leftOffSet, j * width + topOffSet, width, width);

                currentLayer = currentLayer.next;
            }

            // define new rects,
            //  but don't stroke every new rect
            context.rect(i * width + leftOffSet, j * width + topOffSet, width, width);

            // closePath is not needed if you're just rect-ing
            // context.closePath();


        }
    }

    // all done defining rects, now just do 1 stroke that draws them all
    context.stroke();

}
于 2013-08-18T21:36:06.823 に答える