Home > Web Front-end > H5 Tutorial > 4 ways to draw ellipses in HTML5 Canvas_html5 tutorial tips

4 ways to draw ellipses in HTML5 Canvas_html5 tutorial tips

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Release: 2016-05-16 15:47:04
Original
1931 people have browsed it

Overview

Canvas in HTML5 does not directly provide a method for drawing ellipses. The following is a summary of several drawing methods. Each method has its own advantages and disadvantages, which should be selected according to the situation. The parameters of each method are the same:

1.context is the 2D drawing environment object of Canvas,
2.x is the abscissa of the ellipse center,
3.y is the ordinate of the ellipse center,
4.a is the length of the transverse semi-axis of the ellipse ,
5.b is the length of the longitudinal semi-axis of the ellipse.

Parametric equation method

This method uses the parametric equation of the ellipse to draw the ellipse

Copy the code
The code is as follows:

//----------Use parametric equations to draw ellipses---------------------
//Function Parameters x and y are the center of the ellipse; a and b are the horizontal and vertical semi-axes of the ellipse respectively.
//The length of the vertical semi-axis cannot be 0 at the same time.
//The disadvantage of this method is that when lineWidth is wider, the ellipse will be smaller. When flat
//The long axis end inside the ellipse is sharper, not smooth, and less efficient
function ParamEllipse(context, x, y, a, b)
{
//max is equal to 1 Divide by the larger of the major axis values ​​a and b
//i increases by 1/max each cycle, indicating an increase in degree
//This can make the path (arc) drawn in each cycle Close to 1 pixel
var step = (a > b) ? 1 / a : 1 / b;
context.beginPath();
context.moveTo(x a, y); //From the ellipse Start drawing from the left endpoint
for (var i = 0; i < 2 * Math.PI; i = step)
{
//The parametric equation is x = a * cos(i), y = b * sin(i),
//The parameter is i, indicating the degree (radians)
context.lineTo(x a * Math.cos(i), y b * Math.sin(i));
}
context.closePath();
context.stroke();
};

Uniform compression method

This method uses the principle of uniform compression in mathematics to uniformly compress a circle into an ellipse. Theoretically, a standard ellipse can be obtained. The following code will cause inconsistent line widths. For the solution, see Simonleung's comment on the 5th floor. .

Copy code
The code is as follows:

//------------Uniform compression method for drawing ellipses--------------------
//The method The arc method is used to draw a circle, combined with scale for
//Scale in the horizontal or vertical axis direction (uniform compression)
//The edge of the ellipse drawn by this method is thicker as it is closer to the end of the long axis, and the longer axis The line width of the endpoint is the normal value
//The closer the edge is to the minor axis, the flatter and thinner the ellipse will be, and even discontinuity will occur. This is the result of scale
//This shortcoming is sometimes an advantage, such as When expressing the three-dimensional effect of the ring (planetary halo)
//For the case where the parameter a or b is 0, this method is not applicable
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
//Select the larger of a and b as the radius parameter of the arc method
var r = (a > b) ? a : b;
var ratioX = a / r; //Horizontal axis scaling ratio
var ratioY = b / r; //Vertical axis scaling ratio
context.scale(ratioX, ratioY); //Scale (uniform compression)
context.beginPath();
//Draw counterclockwise from the left endpoint of the ellipse
context.moveTo((x a) / ratioX, y / ratioY);
context.arc(x / ratioX , y / ratioY, r, 0, 2 * Math.PI);
context.closePath();
context.stroke();
context.restore();
};

Cubic Bezier Curve Method 1

Drawing an ellipse with a cubic Bezier curve is an approximation in actual drawing, and it is also an approximation in theory. But because of its high efficiency, it is often used to draw ellipses in computer vector graphics, but I am not very clear about the specific theory. The degree of approximation lies in the selection of the positions of the two control points. The control point positions of this method were obtained by my own experiments, and the accuracy is okay.

Copy the code
The code is as follows:

//---------Use cubic Bezier curve to simulate ellipse 1------------------------
//This method will also produce the phenomenon that when the lineWidth is wider and the ellipse is flatter,
//the long axis end is sharper and not smooth
function BezierEllipse1(context, x, y, a, b)
{
//The key is the setting of the two control points in bezierCurveTo
//0.5 and 0.6 are the two key coefficients (obtained from experiments in this function)
var ox = 0.5 * a,
oy = 0.6 * b;

context.save();
context.translate(x, y);
context.beginPath();
//Draw counterclockwise starting from the lower end of the vertical axis of the ellipse
context .moveTo(0, b);
context.bezierCurveTo(ox, b, a, oy, a, 0);
context.bezierCurveTo(a, -oy, ox, -b, 0, -b) ;
context.bezierCurveTo(-ox, -b, -a, -oy, -a, 0);
context.bezierCurveTo(-a, oy, -ox, b, 0, b);
context.closePath();
context.stroke();
context.restore();

};

Cubic Bezier Curve Method 2

This method was changed from a reply to a post in StackOverFlow. It has higher accuracy and is also a method commonly used to draw ellipses.

Copy the code
The code is as follows:

//---------Use cubic Bezier curve to simulate ellipse 2------- ----------------
//This method will also produce the phenomenon that when the lineWidth is wider and the ellipse is flatter
//, the long axis end is sharper and not smooth
//This method is more accurate than the previous Bezier method, but slightly less efficient
function BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848 ,
ox = a * k, // Horizontal control point offset
oy = b * k; // Vertical control point offset

ctx.beginPath();
//Draw four cubic Bezier curves clockwise starting from the left endpoint of the ellipse
ctx.moveTo(x - a, y);
ctx.bezierCurveTo (x - a, y - oy, x - ox, y - b, x, y - b);
ctx.bezierCurveTo(x ox, y - b, x a, y - oy, x a, y);
ctx.bezierCurveTo(x a, y oy, x ox, y b, x, y b);
ctx.bezierCurveTo(x - ox, y b, x - a, y oy, x - a, y);
ctx.closePath();
ctx.stroke();
};

Raster method

This method can use basic algorithms in graphics to draw ellipses based on the characteristics of Canvas that can operate pixels. For example, the midpoint ellipse drawing algorithm, etc.

One example is a blog post by garden friend "Doudou Gou" "HTML5 Canvas Improvement Class (1) - Raster Graphics (1) Midpoint Circle Drawing Algorithm". This method is relatively "original", has great flexibility, high efficiency, and high accuracy, but it is relatively complicated to implement a valuable function for drawing ellipses. For example, when the line width changes, the algorithm is more complicated. Although it is an algorithm for drawing circles, the algorithm for drawing ellipses is similar to it. You can refer to it below.

Summary

Basically all methods cannot achieve 100% accuracy because they are limited by the display resolution.

In fact, the best method should be arc() scale(). The canvas drawing library KineticJS uses this method.

In other drawing software, there is no inherent arc() scale() method like HTML5 canvas. Bezier curves are usually used to simulate approximate ellipses. No matter how many Bezier curves are, they are just approximations. Regarding using Bezier curves to simulate ellipses, you can refer to this information: Drawing an elliptical arc using polylines, quadratic or cubic Bezier curves.

Since arc() scale() is a method already implemented by the browser, it has the highest theoretical accuracy, so it is the best in terms of efficiency, accuracy and ease of use.

After drawing the ellipse with arc() scale(), the two methods context.stroke() and context.restore() are called in a different order, and the results will be very interesting. Usually you should restore() first and then stroke().

Demo

The following are several demonstrations of drawing elliptic functions in addition to the raster method. The demonstration code is as follows:

Copy code
The code is as follows:







注意,要成功运行代码,需要支持HTML5的Canvas的浏览器。
Related labels:
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Issues
html5 validation for symfony 2.1
From 1970-01-01 08:00:00
0
0
0
The difference between HTML and HTML5
From 1970-01-01 08:00:00
0
0
0
html5 show hide
From 1970-01-01 08:00:00
0
0
0
Can PDF files run HTML5 and Javascript?
From 1970-01-01 08:00:00
0
0
0
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template