2

I want to customize arc() function to be able to make my own circle, but I can't get it to draw a flattened cicrle.

enter image description here

How can I do this?

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(100, 75, 50, 0, 2 * Math.PI);
ctx.stroke();
<canvas id="myCanvas" width="200" height="150" style="border:1px solid #d3d3d3;"></canvas>
Alex Nikolsky
  • 2,087
  • 6
  • 21
  • 36
  • Honestly, I don't see a circle in the image. It seems like some weird shape and so I don't think a single `arc` command could help you with this. – Harry Nov 01 '15 at 12:47
  • Possible duplicate of [How to draw an oval in html5 canvas?](http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas) – JSDBroughton Nov 01 '15 at 12:49
  • @Harry I'm sorry I hadn't a decent image editor. It's supposed to be smooth. – Alex Nikolsky Nov 01 '15 at 12:49
  • Ok, if it is supposed to look more like an oval with the bottom half in Y-axis flattened out then have a look at the method to create an oval in the linked thread. [**Here**](http://codepen.io/hari_shanx/pen/rOKRqq) is a modified version of that answer to help you. – Harry Nov 01 '15 at 12:55
  • 1
    Or, if you are looking for a semi-circle with a flat bottom, then use `1 * Math.PI` instead of `2 * Math.PI` in `arc` command and use `closePath` after it. – Harry Nov 01 '15 at 13:01

2 Answers2

5

Arc will always be a piece of a circle. Use scale to transform your circle to an ellipse:

Edit: Use save and restore to keep the canvas state. This will keep the line-width constant.

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth=5;
ctx.save();
ctx.beginPath();
ctx.scale(2,1);
ctx.arc(50, 75, 40, 0, 2*Math.PI);
ctx.restore();
ctx.stroke();
<canvas id="myCanvas" width="200" height="150" style="border:1px solid #d3d3d3;"></canvas>
woestijnrog
  • 1,549
  • 12
  • 9
2

To keep it consistent with the existing functionality and not have to deal with the complexity of varying line width. This one draws the arc by sweeping out a set of points. Change the 2 in the steps calc to higher numbers to have the code run quicker or reduce 2 to 1 for slower but better quality. Making it smaller than one is pointless

// set up code;
var canvas = document.getElementById("canV");
var ctx = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height
ctx.clearRect(0,0,cw,ch)
ctx.globaleAlpha = 1;


// function to draw a arc with two radius wr the width radius
// and hr the height radius; start end are the start and end angles
function arc2(x, y, wr, hr, start, end){
    var i, xx, yy, step;
    step = 2 / Math.max(wr,hr); // get number of steps around
    for(i = start; i <= end; i+= step){ // from start to end
        if(i > end -step / 2){  // ensure that there is no floating
            i = end;              // point error at end of sweep
        }
        xx = Math.cos(i) * wr + x;      // calculate point on circle
        yy = Math.sin(i) * hr + y;
        if(i === start){                // if first Point move to
            ctx.moveTo(xx,yy);
        }else{
            ctx.lineTo(xx,yy);
        }
    }// all done return;
}
// demo to draw circles till the cows come home
var circleDraw = function () {
    var x, y, rw, rh;
    // get some randoms numbers for circles
    x = Math.random() * (cw / 2) + cw / 4;
    y = Math.random() * (ch / 2) + ch / 4;
    rw = Math.random() * ch / 4 + 20;
    rh = Math.random() * ch / 4 + 20;
    ctx.strokeStyle = "hsl(" + Math.floor(Math.random() * 260) + ",100%,50%)";
        ctx.fillStyle = "hsl(" + Math.floor(Math.random() * 260) + ",100%,50%)";
        ctx.lineWidth = Math.random() * 10;
  
    ctx.beginPath();
  
    // draw the arc with new function
    arc2(x, y, rw, rh, 0, Math.PI * 2);
    
    ctx.closePath(); // close the path
  
   // fill and or stoke it
    if (Math.random() > 0.5) {
        ctx.fill();
    }
    if (Math.random() > 0.5) {
        ctx.stroke();
    }
    setTimeout(circleDraw, 200);
}
setTimeout(circleDraw, 200);
.canC {
    width:256px;
    height:256px;
}
<canvas class="canC" id="canV" width=256 height=256></canvas>
Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • Upvote for the trigonometry -- you've got to love math(!), but I would have to double upvote woestijnrog's answer. – markE Nov 02 '15 at 00:35