Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canvas arc() vs drawImage()

This may seem innocuous, but when doing it 1000+ times at 30 frames per second, it does add up. I have 3 sizes of circles that I draw, each with their own fill color (RGBA). Is it faster for me to draw them as images once, and use drawImage() with the data URLs, or to do arc() for each of them?

Extra information:

  • Using a single canvas for all circles
  • Context and canvas are cached
  • Full call for arc at the moment looks like

    this.scene.context.arc(newLocation, this.y+=this.speed/80, this.distance / 2, 0, Math.PI*2, false);

like image 730
LoveAndCoding Avatar asked Sep 03 '12 21:09

LoveAndCoding


People also ask

What is canvas arc?

The arc() is a method of the Canvas 2D API. The arc() method allows you to draw a circular arc. The following shows the syntax of the arc() method: ctx.arc(x, y, radius, startAngle, endAngle [, antiClockwise]) The arc() method draws a circular arc centered at (x,y) with the radius of radius .

How do you use the arc method in canvas?

The arc() method creates an arc/curve (used to create circles, or parts of circles). Tip: To create a circle with arc(): Set start angle to 0 and end angle to 2*Math. PI. Tip: Use the stroke() or the fill() method to actually draw the arc on the canvas.

Where is arc in canvas?

Select Arc from the Global navigation menu on the extreme left of the screen.


2 Answers

enter image description here

According to my tests, drawImage() is going to be significantly faster in most cases than using arc().

The drawImage() function can take either an <img> or <canvas> element as its parameter, and in Firefox, using an <img> tag was faster, though other browsers showed the opposite.

What it boils down to: Even for simple shapes, use drawImage()

like image 133
LoveAndCoding Avatar answered Sep 28 '22 09:09

LoveAndCoding


drawImage() is faster, but only in Firefox.

There's a trick that gives the same performance in Chrome as drawImage() gives in Firefox:

const drawCircle = function(ctx, x, y, radius) {
  ctx.lineWidth = radius * 2;
  ctx.lineCap = 'round';
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x, y);
  ctx.stroke();
}

In Chrome 84, this method using round line caps is about 3x faster than anything else:

Bar graph showing a performance comparison between Chrome and Firefox

Interestingly, Firefox 79 is the exact opposite: that trick turns out to be the slowest option, with arc being only a bit faster.

The tests I used are here.

like image 33
Joshua Wade Avatar answered Sep 28 '22 09:09

Joshua Wade