jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
HTML5 Canvas Dashed Lines
<style>
canvas {
border: solid 1px black;
box-shadow: inset 0px 2px 13px #999;
margin:2px;
border-radius: 5px;
}
</style>
<canvas id="c1"></canvas>
<canvas id="c2"></canvas>
<canvas id="c3"></canvas>
<canvas id="c4"></canvas>
<script>
CanvasRenderingContext2D.prototype.dashedLine1 = function(x0, y0, x1, y1, pattern) {
var length = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
var vector = {
x: (x1 - x0) / length,
y: (y1 - y0) / length
};
var dist = 0;
var i = 0;
pattern = pattern && pattern.length ? pattern : [4, 4];
while (dist < length) {
var dashLength = Math.min(pattern[i++ % pattern.length], length - dist);
dist += dashLength;
(i % 2) && this.moveTo(x0, y0);
x0 += dashLength * vector.x;
y0 += dashLength * vector.y;
(i % 2) && this.lineTo(x0, y0);
}
};
CanvasRenderingContext2D.prototype.dashedLine2 = function(x1, y1, x2, y2, dashLen) {
if (dashLen == undefined) dashLen = 2;
this.moveTo(x1, y1);
var dX = x2 - x1;
var dY = y2 - y1;
var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
var dashX = dX / dashes;
var dashY = dY / dashes;
var q = 0;
while (q++ < dashes) {
x1 += dashX;
y1 += dashY;
this[q % 2 == 0 ? 'moveTo' : 'lineTo'](x1, y1);
}
this[q % 2 == 0 ? 'moveTo' : 'lineTo'](x2, y2);
};
CanvasRenderingContext2D.prototype.dashedLine3 = function(fromX, fromY, toX, toY, pattern) {
var lt = function(a, b) {
return a <= b;
};
var gt = function(a, b) {
return a >= b;
};
var capmin = function(a, b) {
return Math.min(a, b);
};
var capmax = function(a, b) {
return Math.max(a, b);
};
var checkX = {
thereYet: gt,
cap: capmin
};
var checkY = {
thereYet: gt,
cap: capmin
};
if (fromY - toY > 0) {
checkY.thereYet = lt;
checkY.cap = capmax;
}
if (fromX - toX > 0) {
checkX.thereYet = lt;
checkX.cap = capmax;
}
this.moveTo(fromX, fromY);
var offsetX = fromX;
var offsetY = fromY;
var idx = 0,
dash = true;
var ang = Math.atan2(toY - fromY, toX - fromX);
var factx = Math.cos(ang);
var facty = Math.sin(ang);
while (!(checkX.thereYet(offsetX, toX) && checkY.thereYet(offsetY, toY))) {
var len = pattern[idx];
offsetX = checkX.cap(toX, offsetX + (factx * len));
offsetY = checkY.cap(toY, offsetY + (facty * len));
if (dash) this.lineTo(offsetX, offsetY);
else this.moveTo(offsetX, offsetY);
idx = (idx + 1) % pattern.length;
dash = !dash;
}
};
CanvasRenderingContext2D.prototype.dashedLine4 = function(x0, y0, x1, y1, pattern) {
var length = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
var vector = {
x: (x1 - x0) / length,
y: (y1 - y0) / length
};
var dist = 0;
var i = 0;
pattern = pattern && pattern.length ? pattern : [4, 4];
while (dist < length) {
var dashLength = Math.min(pattern[i++ % pattern.length], length - dist);
var draw = (i % 2);
dist += dashLength;
draw && this.moveTo(x0, y0);
x0 += dashLength * vector.x;
y0 += dashLength * vector.y;
draw && this.lineTo(x0, y0);
}
};
var D = 450;
var COUNT = 1000;
var cnv1 = document.getElementById('c1');
var cnv2 = document.getElementById('c2');
var cnv3 = document.getElementById('c3');
var cnv4 = document.getElementById('c4');
cnv1.width = cnv1.height = D;
cnv2.width = cnv2.height = D;
cnv3.width = cnv3.height = D;
cnv4.width = cnv4.height = D;
var ctx1 = cnv1.getContext('2d');
var ctx2 = cnv2.getContext('2d');
var ctx3 = cnv3.getContext('2d');
var ctx4 = cnv4.getContext('2d');
var points = [];
var patterns = [];
var i, j;
for (i = 0; i < COUNT; i++) {
for (j = 0; j < 4; j++) {
points.push(Math.random() * D);
}
for (j = 0; j < 2; j++) {
patterns.push(Math.random() * 10 + 2);
}
}
ui.benchmarks[0].setup = function() { ctx1.clearRect(0, 0, D, D) };
ui.benchmarks[1].setup = function() { ctx2.clearRect(0, 0, D, D) };
ui.benchmarks[2].setup = function() { ctx3.clearRect(0, 0, D, D) };
ui.benchmarks[3].setup = function() { ctx4.clearRect(0, 0, D, D) };
</script>
Ready to run.
Test | Ops/sec | |
---|---|---|
method #1 |
| ready |
method #2 |
| ready |
method #3 |
| ready |
method #1 (mod) |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.