Skip to content

Instantly share code, notes, and snippets.

@GerHobbelt
Forked from stepheneb/README.md
Created August 12, 2012 11:53
Show Gist options
  • Save GerHobbelt/3331545 to your computer and use it in GitHub Desktop.
Save GerHobbelt/3331545 to your computer and use it in GitHub Desktop.
HTML5 Canvas path benchmark (various composition modes)
# Editor backup files
*.bak
*~

Canvas Path Benchmark …… ? 8

This example benchmarks the time taken to draw a line consisting of 5000 separate segments into an HTML5 Canvas, using any of the composition modes.

Watch the 'Time of Last Set' numbers to see the difference between the various composition modes while the benchmark progresses to plot 5000 line segments.

This benchmark accompanies this Canvas benchmark, which uses the 'source-over' default composition mode.

source: gist.github.com/gists/3331545

<!DOCTYPE html>
<html>
<head>
<title>Canvas Path Benchmark</title>
<style type="text/css">
body { margin: 0px 10px; }
h1 { font-size: 1.3em; line-height: 1.0em; }
table { font-size: 0.8em; margin: 0px 10px; padding: 2px }
th { text-align: center; font-weight: bold; padding: 0px 10px 0px 10px; }
td { text-align: center; font-weight: normal; padding: 0px 10px 0px 10px; }
ul.hlist { display: inline-block; list-style-type: none; margin: 0px; padding-left: 15px; }
ul.hlist li { display: inline-table; vertical-align: top; list-style-type: none }
#canvas { width: 400px; height: 400px; padding:0px;
background-color: #eeeeee; color:gray; border: solid 1px #cccccc }
</style>
<script type="text/javascript">
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
window.cancelRequestAnimFrame = (function() {
return window.cancelCancelRequestAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
window.clearTimeout;
})();
</script>
</head>
<body>
<h1>Canvas Path Benchmark</h1>
<p id="user-agent"></p>
<ul class="hlist">
<li><canvas id="canvas"></canvas></li>
<li>
<table>
<thead>
<th>Line Segments</td>
<th>Elapsed Time</td>
<th>Time of Last Set</td>
</thead>
<tbody id="results"></tbody>
</table>
</li>
</ul>
<script type="text/javascript">
window.onload=function() {
var user_agent = document.getElementById("user-agent");
user_agent.innerHTML = navigator.userAgent;
var canvas = document.getElementById("canvas");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
var half_width = canvas.width / 2;
var half_height = canvas.height / 2;
var xpos = half_width;
var ypos = half_height;
var ctx = canvas.getContext('2d');
var composites = [ 'source-atop', 'source-in', 'source-out', 'source-over', 'destination-atop', 'destination-in', 'destination-out', 'destination-over', 'lighter', 'copy', 'xor' ];
var composite_idx = 3;
ctx.globalCompositeOperation = composites[composite_idx];
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(255,65,0, 1.0)";
var i, j;
var factor = 15;
var factor_div_2 = factor / 2;
var correction = 0.0035;
function addLineSegments(num) {
for (i=0; i < num; i++) {
ctx.beginPath();
ctx.moveTo(xpos, ypos);
xpos += (factor * Math.random() - factor_div_2) + (half_width - xpos) * correction;
ypos += (factor * Math.random() - factor_div_2) + (half_height - ypos) * correction;
ctx.lineTo(xpos, ypos);
ctx.closePath();
ctx.stroke();
}
};
var results = document.getElementById("results");
var table_row, table_data;
function addToResults(samples, elapsed_time, sample_time) {
table_row = document.createElement('tr');
table_data = document.createElement('td');
table_data.innerHTML = samples;
table_row.appendChild(table_data);
table_data = document.createElement('td');
table_data.innerHTML = elapsed_time;
table_row.appendChild(table_data);
table_data = document.createElement('td');
table_data.innerHTML = sample_time;
table_row.appendChild(table_data);
table_data = document.createElement('td');
table_data.innerHTML = composites[composite_idx];
table_row.appendChild(table_data);
results.appendChild(table_row);
};
var increment = 250;
var count = 0;
var composite_count = Math.floor(4500 / composites.length);
var elapsed_time = 0;
var sample_time, sample_start, sample_end;
function runSet() {
sample_start = +new Date();
addLineSegments(increment);
sample_end = +new Date();
sample_time = sample_end-sample_start;
elapsed_time += sample_time;
count += increment;
composite_count -= increment;
addToResults(count, elapsed_time, sample_time);
if (composite_count <= 0) {
composite_idx++;
composite_idx %= composites.length;
ctx.globalCompositeOperation = composites[composite_idx];
}
}
function benchmark(){
if (count < 5000) {
requestAnimFrame(benchmark, canvas);
runSet();
}
};
requestAnimFrame(benchmark, canvas);
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment