Dans Canvas, vous pouvez facilement utiliser la méthode de l'arc pour dessiner un cercle. À l'origine, un cercle peut également être considéré comme une ellipse de largeur et de hauteur égales, mais il n'existe aucun moyen de dessiner une ellipse dans Canvas. pour le simuler.
Nous devons d'abord clarifier quels paramètres sont nécessaires pour dessiner une ellipse. Les connaissances géométriques de base nous disent qu'une ellipse nécessite des coordonnées centrales, une largeur, une hauteur - ou un angle de rotation, mais cela peut être omis pour le moment, la rotation est plus facile.
1. Utilisez lineTo pour dessiner des ellipses
Vous avez bien lu, lineTo, une méthode purement utilisée pour dessiner des lignes droites, peut en fait être utilisée pour dessiner des ellipses ! ? Mais il existe, mais la méthode d'écriture est vraiment incroyable :
function DrawEllipse(Canvas,O,OA,OB){
//Dessinez une ellipse, exemple : var B=new Array(150,150); ;
avec ( Canvas){
var x=O[0] OA
var y=O[1];
moveTo(x,y); 0;i<=360 ;i ){
var ii=i*Math.PI/180;
var x=O[0] OA*Math.cos(ii); [1]-OB* Math.sin(ii);
lineTo(x,y);
}
}
}
Le principe de cette méthode est qu'un cercle a 360 degrés, puis utilisez lineTo pour faire une boucle 360 fois, tracez des segments de ligne pour chaque degré et enfin connectez-les en une ellipse. Les fonctions trigonométriques sinus et cosinus sont nécessaires au calcul.
Notez que le deuxième paramètre de cette méthode est un tableau, qui est la coordonnée centrale de l'ellipse.
L'idée est très étrange et l'ellipse dessinée est relativement lisse. Mais cela ne vaut pas la peine d'être utilisé par tout le monde – cette méthode effectuera un cycle 360 fois à chaque fois qu'elle dessine une ellipse, et ne dessine qu'un peu plus d'ellipses, ce qui est un test des performances du navigateur.
Nous avons juste besoin de comprendre ses idées
2. Utilisez un arc pour dessiner un cercle, puis redimensionnez-le en une ellipse
Le texte original de cette méthode est ici, et le noyau la fonction est la suivante :
var canvas = document.getElementById('myCanvas ');
var context = canvas.getContext('2d');
var centerX = 0;
var centerY = 0;
// enregistrer l'état
context.save();
// traduire le contexte
context.translate(canvas.width / 2, canvas.height / 2); horizontalement
context.scale( 2, 1);
// dessine un cercle qui sera étiré en un ovale
context.beginPath(); , 2 * Math.PI, false );
// restaurer l'état d'origine
context.restore()
Cette méthode utilise une fonction canevas dont je n'ai jamais parlé auparavant , à savoir l'échelle, qui peut implémenter un canevas de zoom. Il existe deux directions de mise à l'échelle : horizontale et verticale. Dans le code, le canevas est agrandi dans la direction horizontale, mais la direction verticale reste inchangée. Ainsi, le cercle dessiné par l'arc devient une ellipse.
Cette méthode a l'air très bien à première vue, avec moins de code et le principe est facile à comprendre. Mais après analyse, vous pouvez découvrir ses défauts évidents, à savoir : l'imprécision ! Par exemple, j'ai besoin d'une ellipse d'une largeur de 171 et d'une hauteur de 56. Si nous fixons le rayon d'arc à 28, alors nous serons déprimés par le nombre douloureux et incompréhensible 171/28/2.
Mais un compromis est de toujours fixer le rayon d'arc à 100, puis de l'agrandir s'il ne suffit pas, et de le rétrécir s'il le dépasse. Cependant, ce n'est toujours pas précis.
3, utilisez la courbe de Bézier bezierCurveTo
Comme je sentais que la méthode de mise à l'échelle ci-dessus était inexacte, je voulais trouver une méthode précise pour dessiner une ellipse, et je l'ai finalement trouvée sur stackoverflow :
Copier le code
oy = (h/2) * kappa, // point de contrôle décalage vertical
xe = x w, // x-end
ye = y h, // y-end
xm = x w / 2, // x-middle
ym = y h / 2 /; / y-milieu
ctx.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); ( xm - bœuf, vous, x, ym oy, x, ym);
ctx.closePath();
ctx.AVC
}
Cette méthode peut être considérée comme parfaite. Il a divisé une ellipse en quatre courbes de Bézier et les a reliées pour former une ellipse. Enfin, la largeur et la hauteur sont plus précises et les frais généraux sont moindres.
Mais cette méthode présente encore des défauts. Regardez le paramètre kappa, il a une valeur très particulière. Je pense que beaucoup de gens ne comprennent pas pourquoi il doit s'agir de cette valeur jusqu'à ce qu'un expert en géométrie vous dise pourquoi il doit s'agir de cette valeur - je ne le sais toujours pas. Et j’ai une forte envie de changer cela et de voir quelles en seront les conséquences.
Bien sûr, mon impulsion similaire à celle d'un patient atteint d'un trouble obsessionnel-compulsif ne peut pas être considérée comme un défaut de cette méthode. Son véritable défaut est : pourquoi utiliser 4 courbes de Bézier ? Personnellement, j'ai l'impression qu'une ellipse est évidemment composée de deux courbes de Bézier au lieu de quatre. Cette idée m'a finalement conduit à la manière parfaite de dessiner une ellipse.
4
, utilisez deux courbes de Bézier pour dessiner une ellipse
Afin de comprendre si la méthode précédente peut être simplifiée, j'ai spécialement enregistré un compte stackoverflow pour poser des questions Puisqu'il y a des images dans le. question, je n’avais pas assez de points à transférer, j’ai donc dû utiliser mon anglais à peine adéquat pour répondre aux questions des étrangers afin de gagner des points. Mais la chance est finalement venue et mon problème de points a été résolu en répondant à une question.
La question que j'ai posée sur la relation entre les courbes de Bézier et les ellipses est ici
Pour être honnête, je n'ai pas compris la plupart des réponses de l'étranger ci-dessous, mais heureusement, il a fourni un exemple de page de code, qui m'a fait comprendre. . Principe, je tiens à lui exprimer à nouveau ma gratitude. D'après sa réponse, la méthode que j'ai trouvée pour dessiner une ellipse est la suivante :
//Ellipse
CanvasRenderingContext2D.prototype.oval = function (x, y, width, height) {
var k = (width/0.75)/2,
w = width/ 2,
h = height/2;
this.beginPath();
this.moveTo(x, y-h);
this.bezierCurveTo(x k, y-h, x k); , y h, x, y h );
this.bezierCurveTo(x-k, y h, x-k, y-h, x, y-h);
this.closePath();
return this;
Cette méthode est précise, nécessite moins de code et ne présente aucune bizarrerie étrange. N'oubliez pas ceci, le rapport entre la largeur de l'ellipse et les coordonnées des points de contrôle de la courbe de Bézier qui dessine l'ellipse est le suivant :
Point de contrôle de Bézier x=(largeur de l'ellipse/0,75)/2 C'est déjà dans le code reflété dans.
Vous pouvez essayer les 4 méthodes ci-dessus pour dessiner une ellipse.
Si vous trouvez une méthode plus simple, partagez-la avec nous pour en discuter.