[Turn]html5 Canvas Drawing Tutorial (11)-use Lineto/arc/beziercurveto to draw an oval

Source: Internet
Author: User

In the canvas can be very convenient to draw a circle with the Arc method, the original circle can also be regarded as a wide and high equal ellipse, but there is no way to draw ellipse in the canvas, we have to use other methods to simulate.
We first need to explicitly draw an ellipse requires those parameters, basic geometry knowledge tells us that the ellipse needs center coordinates, width, height--or the angle of rotation, but this can be temporarily not, rotation is relatively easy.
1, use LineTo to draw ellipse
You are not mistaken, lineto such a purely used to draw a straight line method can be used to draw an ellipse!? But he does exist, but it's a bit of a mystery:

The code is as follows:
function//withvar x=o[0]+var y=o[1   for (var i=0;i<=360;i++var var x=o[0]+oa*   var y=o[1]-ob*


The principle of this method is that a circle has a 360 degree, then the LineTo Loop 360 times, draw each segment, and eventually even an ellipse. The sine cosine of the trigonometric functions is required for calculation.
Note that the 2nd parameter of this method is the array, which is the center coordinate of the ellipse.

The idea is very wonderful, and the ellipse is also more smooth. But not worth the use of--this method each draw an ellipse, it will cycle 360 times, only a little more than the ellipse, the performance of the browser is a test.
We'll just have to find out what he's thinking.
2, use arc to draw a circle and then scale it to an ellipse
The original text of this method is here, the core function is as follows:

The code is as follows:
varCanvas = document.getElementById (' MyCanvas '); varcontext = Canvas.getcontext (' 2d '); varCenterX = 0; varCenterY = 0; varRADIUS = 50; //Save StateContext.save ();//Translate ContextContext.translate (CANVAS.WIDTH/2, CANVAS.HEIGHT/2); //Scale Context horizontallyContext.scale (2, 1); //Draw Circle which 'll be stretched to an ovalContext.beginpath (); Context.arc (CenterX, CenterY, radius,0, 2 * math.pi,false); //restore to original stateContext.restore ()


This method uses a canvas function that I haven't talked about before, that is, scale, which allows the canvas to be scaled. Scaling has horizontal and vertical two directions, the code in the horizontal direction of the canvas is enlarged, and the vertical direction of the same, so, the original arc drawn by the circle becomes an ellipse.
This method is very good at first glance, the code is small, and the principle is easy to understand. But the analysis will be able to find his obvious shortcomings, that is--imprecise! For example, I need a width of 171 high 56 ellipse, at this time if we set the radius of Arc 28, then the back will be for 171/28/2 this egg pain of the unintelligible number depressed.

But the tradeoff is to always set the radius of arc to 100, then, not enough to enlarge, more than the narrowing. However, it is still not accurate.
3, using Bézier curve Beziercurveto
Since I felt that the above scaling method is not accurate, I would like to find a precise method of painting the ellipse, and finally found on the StackOverflow:

The code is as follows:
functionDrawEllipse (CTX, X, Y, W, h) {varKappa = 0.5522848; Ox= (W/2) * Kappa,//control Point Offset horizontalOy = (H/2) * Kappa,//Control Point Offset verticalXE = x + W,//X-endYe = y + h,//Y-endXM = x + W/2,//X-middleYm = y + h/2;//Y-middleCtx.beginpath (); Ctx.moveto (x, YM); Ctx.beziercurveto (x, YM-Oy, XM-Ox, Y, xm, y); Ctx.beziercurveto (XM+ Ox, y, xe, YM-Oy, XE, YM); Ctx.beziercurveto (Xe, YM+ Oy, XM +Ox, Ye, xm, ye); Ctx.beziercurveto (XM-Ox, ye, x, ym +Oy, X, YM); Ctx.closepath (); Ctx.stroke (); } 


This method can be considered to be more perfect. He divides an ellipse into 4 Bezier curves and uses them as an ellipse. The final width height is also more accurate and less expensive.
However, this approach still has drawbacks. Look at that kappa parameter, there is a very strange value, I believe a lot of people in the geometry experts tell you why he wants to take this value before, do not understand why do not have to take this value-I still do not know. And I have a very strong desire to change him to see what the consequences of the impulse.

Of course, my obsessive-compulsive impulse is not a drawback of this approach, and his real drawback is-why use 4 Bezier curves? I personally think that an ellipse is obviously made up of two Bezier curves rather than 4. The idea finally made me find the perfect way to draw an ellipse.
4, use two Bezier curves to draw an ellipse
In order to understand the previous method can be streamlined, I specifically registered a StackOverflow account to ask questions, because the problem has pictures, not enough points can not be passed, I have to use barely English level to answer the questions of foreigners earn points. But at the end of the good luck, answering a question solved my points problem.
I mention the Bezier curve and the elliptic relationship problem here.
To tell the truth, the following foreigner's answer I mostly did not understand, but fortunately he provided a code sample page, let me understand the principle, here to express his thanks again. And according to his answer, I found the method of drawing ellipse as follows:

The code is as follows:
//EllipseCanvasRenderingContext2D.prototype.oval =function(x, y, width, height) {varK = (width/0.75)/2, W= WIDTH/2, h = height/2; This. Beginpath (); This. moveTo (x, yh);  This. Beziercurveto (X+k, Y-h, X+k, Y+h, X, y+h);  This. Beziercurveto (X-k, Y+h, X-k, y-h, X, yh);  This. Closepath ();return  This; } 


This method is both precise and less code, and there is no strange and difficult place to understand. Just keep in mind that the width of the ellipse is proportional to the coordinates of the control point of the Bezier curve that draws the ellipse as follows:
Bezier Control Point x= (ellipse width/0.75)/2 This is already reflected in the code.

You can experiment with the above 4 methods to draw an ellipse.
If you find a simpler way, please share it with us.

[Turn]html5 Canvas Drawing Tutorial (11)-use Lineto/arc/beziercurveto to draw an oval

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.