Canvas Rotation optimisation tests

JavaScript performance comparison

Test case created by Tom32i

Preparation code

<canvas id="test-1" style="background: green;"></canvas>
<canvas id="test-2" style="background: blue;"></canvas>
<canvas id="test-3" style="background: yellow;"></canvas>
<canvas id="cache" style="background: pink;"></canvas>
<script>
Benchmark.prototype.setup = function() {
            function Canvas(width, height, id) {
              this.canvas = typeof(id) !== "undefined" ? document.getElementById(id) : document.createElement('canvas');
              this.canvas.width = width;
              this.canvas.height = height;
              this.context = this.canvas.getContext('2d');
            }
   
            Canvas.prototype.clear = function() {
              this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
            };
   
            function round(value) {
              return (0.5 + value) | 0;
            }
   
            function drawChainedRectangle(canvas, i) {
              var x = round(i % line) * 50,
                y = Math.floor(i / line) * 50;
   
              canvas.context.rect(x, y, 50, 50);
            }
   
            function drawRectangle(canvas, i) {
              var x = round(i % line) * 50,
                y = Math.floor(i / line) * 50;
   
              canvas.context.beginPath();
              canvas.context.rect(x, y, 50, 50);
              canvas.context.fillStyle = 'red';
              canvas.context.strokeStyle = 'blue';
              canvas.context.fill();
              canvas.context.stroke();
              canvas.context.closePath();
            }
   
            function to3D(x, y) {
              var H = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)),
                r = angle - Math.atan2(y, x);
   
              return [-Math.sin(r) * H, -Math.cos(r) * H * ratio];
            }
   
            var blocks = 1000,
              line = Math.sqrt(blocks),
              ratio = 0.5,
              angle = -Math.PI / 4;
};
</script>

Preparation code output

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Default
var a = new Canvas(800, 500, 'test-1'),
  c = a.context;

a.clear();

c.save();
c.translate(0, a.canvas.height / 2);
c.scale(1, ratio);
c.rotate(angle);

for (i = 0; i < blocks; i++) {
  drawRectangle(a, i);
}

c.restore();
pending…
Optimized Path
var a = new Canvas(800, 500, 'test-2'),
  c = a.context;
a.clear();

c.save();
c.translate(0, a.canvas.height / 2);
c.scale(1, ratio);
c.rotate(angle);

c.beginPath();

for (i = 0; i < blocks; i++) {
  drawChainedRectangle(a, i);
}

c.fillStyle = 'red';
c.strokeStyle = 'blue';
c.fill();
c.stroke();
c.closePath();

c.restore();
pending…
Caching
  var a = new Canvas(800, 500, 'test-3'),
    cache = new Canvas(80, 50, 'cache'),
    c = cache.context;

  cache.clear();

  c.save();
  c.translate(0, cache.canvas.height / 2);
  c.scale(1, ratio);
  c.rotate(angle);
  drawRectangle(cache, 0);
  c.restore();

  a.context.save();
  a.context.translate(0, a.canvas.height / 2);
  for (i = 0; i < blocks; i++) {
    var x = round(i % line) * 50,
      y = Math.floor(i / line) * 50;
    c.drawImage(a, cache.canvas, x, y);
  }
  a.context.restore();
pending…
Caching and positionning
  var a = new Canvas(800, 500, 'test-3'),
    cache = new Canvas(80, 50, 'cache'),
    c = cache.context;

  cache.clear();

  c.save();
  c.translate(0, cache.canvas.height / 2);
  c.scale(1, ratio);
  c.rotate(angle);
  drawRectangle(cache, 0);
  c.restore();

  a.context.save();
  a.context.translate(0, a.canvas.height / 2);
  for (i = 0; i < blocks; i++) {
    var x = round(i % line) * 50,
      y = Math.floor(i / line) * 50,
      pos = to3D(x, y);
    c.drawImage(a, cache.canvas, pos[0], pos[1]);
  }
  a.context.restore();
pending…

You can edit these tests or add even more tests to this page by appending /edit to the URL.

Compare results of other browsers

0 comments

Add a comment