0

I am drawing a circle (r = 100px and lineWidth of 500 px ) in HTML canvas, using the method .arc of canvas API for a google chrome app.

But because of the large lineWidth the inaccuracies in the circle are enlarged, and it doesn't looks like a circle anymore.

Here is a demo http://jsbin.com/ufofor/1/edit http://jsbin.com/ufofor/30/edit

var c = document.getElementById("canvas");
var g = c.getContext("2d");    
var r = 100;   

g.lineWidth = 500;    
g.arc(505, 505, r,0,2*Math.PI, true);
g.stroke();

Is there any way/hack to make a perfect circle , with a large lineWidth in canvas , using .arc method or any other ?


EDIT

The demo works fine in firefox, but in chrome you will find irregularities in the generated circle.

Chrome screenshot of demo

Firefox screenshot of demo

Thanks @Felix for pointing this out.

Tomarinator
  • 782
  • 1
  • 11
  • 28
  • I don't see how that is supposed to be a circle. Or do you want to draw a [circle sector](http://en.wikipedia.org/wiki/Circular_sector)? – Bergi Feb 24 '13 at 12:34
  • No it is actually a circle, not a sector. – Tomarinator Feb 24 '13 at 12:36
  • 1
    remove line g.lineCap= 'square'; seems to do it – QuentinUK Feb 24 '13 at 12:37
  • @QuentinUK , I was just experimenting with different lineCaps like square, butt and round but that doesn't do it. – Tomarinator Feb 24 '13 at 12:39
  • 2
    A full circle can be created with `g.arc(505, 505, r2, 0, 2 * Math.PI, true);`. There are enough examples on SO, for example http://stackoverflow.com/questions/14111548/why-is-the-canvas-circle-not-looking-like-a-circle/14111597. The parameters of the `arc` method are : `arc(x, y, radius, startAngle, endAngle, anticlockwise)`. See https://developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/Drawing_shapes#Arcs. – Felix Kling Feb 24 '13 at 12:40
  • So, what's the problem with the new demo? Looks like a circle to me... – Felix Kling Feb 24 '13 at 16:03
  • @FelixKling Its not a perfect circle because of the large line width. – Tomarinator Feb 24 '13 at 16:05
  • @Tomarinator: I assume you are using Chrome? I'm using Firefox and it looks pretty good in there. That's why I also didn't understand what you where talking about. But in Chrome it really looks a bit strange (just tested it). – Felix Kling Feb 24 '13 at 16:06
  • @FelixKling Actually I am using this in a chrome app so I need to get this working in Chrome, I will just add this to the question. – Tomarinator Feb 24 '13 at 16:09

3 Answers3

0

Changing your .arc code to the below creates a perfect circle - the inputs to the method seemed skewy :S

g.arc(505, 505, r2, 0, Math.PI / 360, true);
Paul Sullivan
  • 2,865
  • 2
  • 19
  • 25
  • 1
    And even the `Math.PI / 360` makes no sense to me - as another commenter posted it seems to be `2 * Math.PI` – Paul Sullivan Feb 24 '13 at 12:42
  • that just change the starting angle and ending angle of the circle, but doesnt change the outer egde of the circle it still looks like its a multi-sided polygon. – Tomarinator Feb 24 '13 at 12:45
  • 1
    @Tomarinator there is no such thing as a circle in computer science - all circles are multi sided polygons in reality as there is finite resolution and precision to be accurate – Paul Sullivan Feb 24 '13 at 12:48
  • If there was a way to change the number of sides in that multi-sided polygon, a more perfect cirlce could be drawn. – Tomarinator Feb 24 '13 at 12:59
0

The signature for arc is

arc(x, y, radius, startAngle, endAngle, anticlockwise)

where both startAngle and endAngle are in radians. So for a full circle, you want to draw from 0 to Math.PI * 2 - I have no idea where you got those 30 from.

Also, you might want to try to fill() your path instead of stroke()ing it with that absurd line width - which, in combination with the odd lineCap and lineJoin values, is probably the reason for the misshaped result.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

"My own 2 cents" if someone is still needing such thing as a "strokeWidth" for the arc() function ;)

// 10 is the strokeWidth for the arc()
for(var i=0; i<= 10; i++){
  context.arc(circleObj.center_x, circleObj.center_y, 50+i, 0, 2*Math.PI);
  context.stroke();
}

The above can even be used before a call to 'clip()' to be used as a mask ;p

Hoping it helped at least one needy soul .. ;)

BONUS ==> one of the things I'm working on which lead me here to solve your troubles as I ended mine :P

--> https://jsbin.com/xuvogoyizu/edit?js,output

Click & drag to control the position of this "strokeWidth-ed arc mask" ;)

StephaneAG
  • 1,107
  • 1
  • 12
  • 11