I need to draw a lot of points on a HTML5 canvas, and it is taking pretty long. My code looks like this:
var points = getPoints() // Array of {x,y,color}
var ctx = canvas.getContext("2d");
for (var i = 0; i < points.length; i++) {
ctx.fillStyle = points[i].color
ctx.beginPath()
ctx.arc(points[i].x, points[i].y, radius, 0, Math.PI * 2, true)
ctx.fill() }
I am wondering what performance tweaks I could do to speed this up. I only have 5 different colors. For example, would I benefit form sorting the points list on-the-fly to change ctx.fillStyle
only 5 times instead of one time per point?
For example, would I benefit form sorting the points list on-the-fly to change ctx.fillStyle only 5 times instead of one time per point?
In my experience, yes - changing .fillStyle
frequently is quite expensive.
I had code that was plotting a large number of rectangles in a canvas and the time to plot rectangles with only two infrequently varying colours was significantly better than plotting with many frequently changing colours.
Anyhow, since you only have five different colours:
.drawImage()
to blit the right colour circle into your destination canvas without having to recalculate the arc coordinatespoints[i]
to an local variable inside the loop to avoid dereferencing it over and over.On my laptop this code is drawing 3000 circles on a 400x400 canvas in 7 milliseconds:
var colours = ['red', 'green', 'blue', 'yellow', 'magenta'];
var n = colours.length;
var r = 10;
var d = r * 2;
var off = document.createElement('canvas');
off.width = n * d;
off.height = d;
var ctx = off.getContext('2d');
for (var i = 0; i < n; ++i) {
ctx.fillStyle = colours[i];
ctx.beginPath();
ctx.arc(i * d + r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
}
var canvas = document.getElementById('canvas');
var ctx2 = canvas.getContext('2d');
var t0 = Date.now();
for (var i = 0; i < 3000; ++i) {
var c = Math.floor(n * Math.random());
var x = Math.floor(canvas.width * Math.random());
var y = Math.floor(canvas.height * Math.random());
ctx2.drawImage(off, c * d, d, d, x - r, y - r, d, d);
}
var t1 = Date.now();
alert((t1 - t0) + "ms");
See http://jsfiddle.net/alnitak/Dpgts/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With