Recently, I was asked how to draw an ellipse in canvas. As a front-end engineer, I have little contact with graphics and WebGL, and my knowledge of Canvas is limited to the API corresponding to canvas drawing. When I encountered this problem, I was completely confused. I vaguely remember that canvas has a circle drawing API, and I took it for granted that there should also be a corresponding API for ellipse drawing. Pass in the coordinate point/long axis/short axis parameters. After the special try and research, share.
How does canvas draw circles
Native API: Arc Receive 😡 /y/start Angle/end Angle/draw direction False for clockwise (default) several parameters
const ctx = canvas.getContext('2d');
ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise)
Copy the code
Understand, in fact, the internal call of the computer is grating, the parameter equation of the circle x= Rcos θ y=rsinθ, so you can write a method to draw a circle
function circle(context, x, y, r) {
const step = 1/r;
context.beginPath();
context.moveTo(x + r, y);
for(let i = 0; i < 2 * Math.PI; i += step) {
context.lineTo(x + r * Math.cos(i), y + r * Math.sin(i));
}
context.closePath();
context.fill();
}
Copy the code
X and y are coordinates, r is radius, and 1/r is the Angle value corresponding to the line segment 1px, which is also the degree of fineness. When r is large, a fixed value can be written, such as 1/10, otherwise performance will be affectedCopy the code
Start drawing an ellipse
In fact, the latest version of Chrome has a native ellipse drawing API, but compatibility is not very good, x /y/horizontal axis length/vertical axis length/rotation Angle/actual Angle/end Angle/direction
ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
Copy the code
Similarly to circles, you can implement a method of drawing an ellipse by using the parametric equation of the ellipse: x= ACos θ | y=bsinθ
function ellipse(context, x, y, a, b) { const step = (a > b) ? 1 / a : 1 / b; context.beginPath(); context.moveTo(x + a, y); for (let i = 0; i < 2 * Math.PI; i += step) { context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i)); } context.closePath(); CTX. FillStyle = "rgba (0, 0,. 2)"; context.fill(); }Copy the code
Parameters and the original and draw the circle similar, step can be adjusted according to the actual situationCopy the code
There is a simpler and more efficient way to compress the standard circle into an ellipse, as you can see from the code, but with this method the width is also compressed when the border width is larger
function ellipse(context, x, y, a, b) { context.save(); const r = (a > b) ? a : b; const ratioX = a / r; const ratioY = b / r; context.scale(ratioX, ratioY); context.beginPath(); context.arc(x / ratioX, y / ratioY, r, 0, 2 * Math.PI, false); context.closePath(); context.restore(); CTX. FillStyle = "rgba (255, 0, 2)"; context.fill(); }Copy the code
With your mutual encouragement, need to learn a lot.Copy the code
Finally, I recommend a canvas related address: address