Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw a smooth oval in canvas

I am trying to draw a smooth oval using ctx.clip property in my canvas.I have done with drawing part i am facing problem with oval arc line clarity.Any one have any idea regarding this just let me know? Here is my code.

<canvas id="c" width="400" height="400"></canvas>


var canvas = new fabric.Canvas('c');
var ctx = canvas.getContext('2d');
var cx=180;
var cy=200;
var w=300;
var h=250;
    // Quadratric curves example
    ctx.beginPath();
    var lx = cx - w/2,
        rx = cx + w/2,
        ty = cy - h/2,
        by = cy + h/2;
    var magic = 0.551784;
    var xmagic = magic*w/2;
    var ymagic = h*magic/2;
    ctx.moveTo(cx,ty);
    ctx.bezierCurveTo(cx+xmagic,ty,rx,cy-ymagic,rx,cy);
    ctx.bezierCurveTo(rx,cy+ymagic,cx+xmagic,by,cx,by);
    ctx.bezierCurveTo(cx-xmagic,by,lx,cy+ymagic,lx,cy);
    ctx.bezierCurveTo(lx,cy-ymagic,cx-xmagic,ty,cx,ty);

    ctx.fill();
    ctx.stroke();
    ctx.clip();



var text;
text = new fabric.Text('Honey', {
  fontSize: 50,
  left: 150,
  top: 150,
  lineHeight: 1,
  originX: 'left',
  fontFamily: 'Helvetica',
  fontWeight: 'bold'
});
canvas.add(text);

Here is my fiddle link

You can see this output over here the line border of oval not much clear. Here is output of screen shot

like image 573
Sanjay Nakate Avatar asked Sep 28 '13 13:09

Sanjay Nakate


People also ask

How do you draw an oval on a canvas?

The final code for drawing any oval shape: <canvas id="canvas4" width="400" height="200"></canvas> function drawOval(x, y, rw, rh) { var canvas = document. getElementById("canvas4"); var context = canvas. getContext("2d"); context.

How do you make a circle in canvas?

To draw arcs or circles, we use the arc() or arcTo() methods. Draws an arc which is centered at (x, y) position with radius r starting at startAngle and ending at endAngle going in the given direction indicated by counterclockwise (defaulting to clockwise).


2 Answers

try this it will help you //Script

var canvas = new fabric.Canvas('c');
 var w;
 var h;
 var ctx = canvas.getContext('2d');
 w=canvas.width / 4;
 h=canvas.height / 2.4;
canvas.clipTo = function(ctx) {
 ctx.save();
 ctx.scale(2, 1.2);
 ctx.arc(w, h, 90, 0, 2 * Math.PI, true);
 ctx.stroke();
 ctx.restore();
}

Fiddle Demo

like image 80
amit gupta Avatar answered Sep 21 '22 08:09

amit gupta


One problem is in the nature of your display screen...

Since pixels are rectangles and you're drawing a curve, your result will have "jaggies" as the curve tries to fit itself in rectangular spaces.

You can use an optical illusion to trick the eye into seeing a less jagged oval.

An optical trick:

Reduce the contrast between the background color and the oval color.

This is not a cure...the jaggies are still there.

But the eye recognizes less contrast and perceives the oval as more smooth.

So if your design accommodates this style change, this optical illusion might help.

Here's code and a Fiddle: http://jsfiddle.net/m1erickson/vDWR3/

var cx=180;
var cy=200;
var w=300;
var h=250;

// Start with a less-contrasting background
ctx.fillStyle="#ddd";
ctx.fillRect(0,0,canvas.width,canvas.height);

ctx.beginPath();
var lx = cx - w/2,
    rx = cx + w/2,
    ty = cy - h/2,
    by = cy + h/2;
var magic = 0.551784;
var xmagic = magic*w/2;
var ymagic = h*magic/2;
ctx.moveTo(cx,ty);
ctx.bezierCurveTo(cx+xmagic,ty,rx,cy-ymagic,rx,cy);
ctx.bezierCurveTo(rx,cy+ymagic,cx+xmagic,by,cx,by);
ctx.bezierCurveTo(cx-xmagic,by,lx,cy+ymagic,lx,cy);
ctx.bezierCurveTo(lx,cy-ymagic,cx-xmagic,ty,cx,ty);

ctx.fillStyle="#555";
ctx.strokeStyle=ctx.fillStyle;
ctx.lineWidth=1.5;
ctx.stroke();
like image 39
markE Avatar answered Sep 21 '22 08:09

markE