Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to draw multiple filled circles in one path on canvas

I am trying to make a performance optimization in the HTML5 canvas drawing code. In particular I am looking at filled circles and lines. For lines I did optimization like that: for every segment of the line it did the following:

  • Begin path
  • Move to
  • Line to
  • Close path
  • Stroke

We got improvement once we opened path once and performed moveTo and lineTo for all points and after that closed path and did Stroke. Perf gain was pretty good.

I try to do similar thing for filled circles. Right now filled circles rendered in similar manner: for every circle:Begin path, draw arc, set shape fill style, fill. Test (http://jsperf.com/rendering-filled-circle/7 ) shows that rendering and filling multiple circles at once would be faster. However, I will need to use moveTo before every call to arc otherwise I will get incorrect result: https://jsfiddle.net/gaeb9es8/1/ enter image description here Here is what I expect: https://jsfiddle.net/j4b7jz03/1/ enter image description here

function render2(x, y, context){
            // x, y are arrays of points to render in a single path
            context.beginPath();
            for (var i=0; i< x.length; i++){
                //context.moveTo(x[i], y[i]);
                context.arc(x[i], y[i], 5, 0, 2 * Math.PI, false);
            }
            context.closePath();
            context.fill();          
        }

So the question is: is there a way to draw multiple filled circles of the same color in the same path on canvas and without using moveTo? moveTo is causing perf regression.

like image 846
vmg Avatar asked Sep 17 '25 20:09

vmg


1 Answers

Any other method would be awkward and yield less performance than moveTo.

Remove the closePath in your second bit of code.

enter image description here

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

ctx.beginPath();
for(var i=0;i<50;i++){
  var cx=Math.random()*canvas.width;
  var cy=Math.random()*canvas.height;
  ctx.moveTo(cx,cy);
  ctx.arc(cx,cy,7,0,Math.PI*2);
}
ctx.fillStyle='red';
ctx.fill();
<canvas id="canvas" width=300 height=300></canvas>
like image 70
markE Avatar answered Sep 21 '25 05:09

markE