Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

canvas draw circle with quadratic curve

I know I can draw arc with arc function of canvas but when I increase the size of that arc it changes its start and end x,y points. So I was thinking if we can draw arc with some other way keeping its start end points fixed while increasing it size.

Edit
Below is the images showing what I am looking for. First image shows a rectangle. when its side is stretched it changed to circle(2nd image). when side is stretched further it changed to big circle. At in all images you can see that end points of circle are joined to corners of rectangle. This is what I want to do.

enter image description here
1st Image

enter image description here
2nd Image

enter image description here
3rd Image

Or you can see this video to understand what I am looking to do.


What I have done
This fiddle shows result of my work.
To draw rectangle just click and drag your mouse.

Here is the code

like image 282
Sandeep Kumar Avatar asked Jan 22 '13 07:01

Sandeep Kumar


People also ask

How do I draw a curve in canvas?

To draw a Bezier curve with HTML5 canvas, use the bezierCurveTo() method. The method adds the given point to the current path, connected to the previous one by a cubic Bezier curve with the given control points. You can try to run the following code to learn how to draw a Bezier curve on HTML5 Canvas.

How many coordinate points do you need to draw a canvas quadraticCurveTo?

quadraticCurveTo() method of the Canvas 2D API adds a quadratic Bézier curve to the current sub-path. It requires two points: the first one is a control point and the second one is the end point.

What is the syntax of a method that is used to draw quadratic curves on a canvas?

To create a quadratic curve with HTML5 Canvas, we can use the quadraticCurveTo() method. Quadratic curves are defined by the context point, a control point, and an ending point. Quadratic curves can be styled with the lineWidth, strokeStyle, and lineCap properties.


2 Answers

I believe you're looking for something like this:

draw(0);
$('#range').on('change', function(){
    range = parseInt($(this).val());
    draw(range)
})

function draw(val){
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d'),
    x = 100,
    y = 50,
    d;
    context.clearRect(0, 0, canvas.width, canvas.height);

    d = Math.sqrt(Math.pow(val,2) + Math.pow(50,2));

    context.beginPath();
    context.lineWidth = 1;

    context.arc(x,y+val,d,0,2*Math.PI);

    // line color
    context.strokeStyle = 'black';
    context.stroke();

    // Cut off the top of the circle.
    context.clearRect(0, 0, canvas.width, y);

    // This stuff's just to show some dots
    context.fillStyle = 'red';
    context.fillRect(x-1,y-1,2,2); // Middle
    context.fillRect(x-52,y-2,4,4);//Target point 1
    context.fillRect(x+48,y-2,4,4);// Target point 2

    context.fillRect(x-2,y+d+val-2,4,4); // Point on circle
    context.fillStyle = 'black';
}

Working sample

There are a couple disadvantages to this is that it gets "slower" the closer you get to the circle, because the circle's getting exponentially larger in the hidden section (The slider's controlling it's size), and that it doesn't work for diagonal lines as it is right now.

Other than that, it works like expected.

like image 100
Cerbrus Avatar answered Sep 23 '22 02:09

Cerbrus


Check this : http://jsfiddle.net/KZBzq/4/

Updated answer with bezierCurveTo

HTML

<label>Range :</label>
<input type="range" name="points" value="0" min="0" step="1" max="100" id="range"> 
<canvas id="myCanvas" width="578" height="250"></canvas> 

JS

draw(100); 

$('#range').on('change', function(){
  range = parseInt($(this).val());
  draw(100-range)
})

function draw(val){

  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d'),
  x = 100,
  y = 100,
  cp1x = x/2,
  cp2x = y/2,
  cp1y = val,
  cp2y = val;
  context.clearRect(0, 0, canvas.width, canvas.height);

  context.beginPath();
  context.lineWidth = 1;

  context.moveTo(25 , x);
  context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);

    // line color
    context.strokeStyle = 'black';
    context.stroke();

}

Now x and Y are fixed. Is this was your requirement?

like image 21
Praveen Vijayan Avatar answered Sep 21 '22 02:09

Praveen Vijayan