Le canevas dans HTML5 ne fournit pas directement de méthode pour dessiner des ellipses. Ce qui suit est un résumé de plusieurs méthodes de dessin. Diverses méthodes ont leurs propres avantages et inconvénients et sont sélectionnés selon la situation. Les paramètres de chaque méthode sont les mêmes:
Le contexte est l'objet d'environnement de dessin 2D de Canvas,
X est la coordonnée horizontale du centre de l'ellipse.
Y est la coordonnée verticale du centre de l'ellipse.
A est la longueur du demi-axe horizontal de l'ellipse.
B est la longueur du demi-axe vertical de l'ellipse.
Méthode d'équation des paramètresCette méthode utilise les équations paramétriques de l'ellipse pour dessiner une ellipse
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Les paramètres x et y de la fonction sont le centre de l'ellipse; A et B sont le demi-axe horizontal de l'ellipse, respectivement
// La longueur du demi-axe vertical ne peut pas être 0 en même temps
// L'inconvénient de cette méthode est que lorsque la linwidth est plus large et que l'ellipse est flatteuse
// l'extrémité principale de l'axe de l'ellipse intérieure est nette, pas lisse et a une faible efficacité
Fonction Paramellipse (contexte, x, y, a, b)
{
// Max est le plus grand des principaux valeurs de l'axe a et b
// j'augmente 1 / max pour chaque cycle, indiquant l'augmentation du degré
// Cela fera le chemin (Arc) dessiné dans chaque boucle près de 1 pixel
var Step = (a> b)? 1 / A: 1 / B;
context.beginPath ();
context.moveto (x + a, y); // tire du point final gauche de l'ellipse
pour (var i = 0; i <2 * math.pi; i + = étape)
{
// L'équation des paramètres est x = a * cos (i), y = b * sin (i),
// Le paramètre est i, indiquant le degré (radian)
context.lineto (x + a * math.cos (i), y + b * math.sin (i));
}
context.closepath ();
context.stroke ();
};
Méthode de compression uniformeCette méthode utilise le principe de compression uniforme en mathématiques pour comprimer uniformément le cercle en une ellipse, qui peut théoriquement obtenir une ellipse standard. Le code suivant aura des problèmes avec les largeurs de ligne incohérentes. La solution consiste à voir les commentaires de Simonleung au 5ème étage.
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// La méthode consiste à dessiner le cercle en utilisant la méthode d'arc et à combiner l'échelle pour
// Mise à l'échelle dans la direction de l'axe horizontal ou vertical (même compression)
// Le bord de l'ellipse dessinée dans cette méthode devient plus épais car le bord est plus proche de l'extrémité de l'axe majeur, et la largeur de ligne de l'extrémité de l'axe majeur est normale
// Plus le bord est proche de l'axe mineur, plus la plus plate et plus mince de l'ellipse, et même une interruption est causée. Ceci est le résultat de l'échelle.
// Ce désavantage est parfois un avantage, comme lors de l'expression de l'effet tridimensionnel de l'anneau (halo planétaire)
// Pour le cas où les paramètres A ou B sont 0, cette méthode n'est pas applicable
fonction evencompelipse (contexte, x, y, a, b)
{
context.save ();
// sélectionnez le plus grand de A et B comme paramètre de rayon de la méthode d'arc
var r = (a> b)? R: B;
VAR RATIOX = A / R; // Ratio de mise à l'échelle de l'axe horizontal
var ratioy = b / r; // Ratio de mise à l'échelle de l'axe dimensionnel
context.scale (ratiox, ratioy); // Échelle (même compression)
context.beginPath ();
// dessinez dans le sens antihoraire à partir de l'extrémité gauche de l'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 ();
};
Méthode CUBIC Bezier Curve OneLe dessin de courbe Cubic Bezier d'une ellipse est une approximation lorsqu'il est réellement dessiné, et en théorie, c'est aussi une approximation. Cependant, en raison de sa grande efficacité, il est souvent utilisé pour dessiner des ellipses dans les graphiques vectoriels informatiques, mais je ne suis pas très clair sur la théorie spécifique. L'approximation réside dans la sélection des positions des deux points de contrôle. La position du point de contrôle de cette méthode a été obtenue par moi-même et la précision est OK.
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Cette méthode produira également lorsque la largeur de ligne est plus large et que l'ellipse est plus plate.
// l'extrémité de l'axe long est nette et non lisse
fonction bezierellipse1 (contexte, x, y, a, b)
{
// La clé est le réglage de deux points de contrôle dans Beziercurveto
//0.5 et 0,6 sont deux coefficients clés (obtenus pour l'expérimentation dans cette fonction)
var ox = 0,5 * a,
OY = 0,6 * b;
context.save ();
context.translate (x, y);
context.beginPath ();
// dessinez dans le sens antihoraire à partir de l'extrémité inférieure de l'axe longitudinal de l'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 ();
};
Méthode de la courbe cubique de Bezier deuxCette méthode est modifiée de la réponse à un post dans StackOverflow, avec une grande précision et est également une méthode couramment utilisée pour dessiner des ellipses.
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Cette méthode produira également lorsque la largeur de ligne est plus large et que l'ellipse est flatteuse
//, l'extrémité de l'axe long est nette et non lisse
// Cette méthode est plus précise que la méthode Bessel précédente, mais a une méthode légèrement moins efficace
fonction bezierellipse2 (ctx, x, y, a, b)
{
var k = .5522848,
ox = a * k, // décalage du point de contrôle horizontal
oy = b * k; // décalage du point de contrôle vertical
ctx.beginPath ();
// Dessinez quatre courbes de Bezier cubes dans le sens des aiguilles d'une montre à partir du point d'extrémité gauche de l'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 ();
};
Méthode de réseauCette méthode peut dessiner des ellipses en fonction des caractéristiques de la canevas en mesure de faire fonctionner des pixels et d'utiliser des algorithmes de base en graphiques. Par exemple, l'algorithme d'ellipse de dessin médian, etc.
Un exemple est un article de blog de Doudou, un ami du jardin, la classe d'amélioration du canevas HTML5 (i) - Raster Graphics (1) Milieu et Circle Algorithme. Cette méthode est relativement primitive, flexible, efficace et précise, mais il est plus compliqué de réaliser une fonction utile pour dessiner des ellipses. Par exemple, lorsque la largeur de ligne change, l'algorithme devient plus compliqué. Bien qu'il s'agisse d'un algorithme pour dessiner des cercles, l'algorithme pour dessiner des ellipses est similaire, vous pouvez donc vous y référer ci-dessous.
Démo
Voici plusieurs démonstrations de dessin de fonctions d'ellipse en plus de la méthode raster. Le code de démonstration est le suivant:
<div id = "canvaswrap" style = "background: #ffff; largeur: 600px; hauteur: 600px; bordure: 1px noir solide;"> </ div>
<script type = "text / javascript"> // <! [cdata [
toile var,
contexte;
var div = document.getElementById ("canvaswrap");
div.innerhtml = "";
canvas = document.CreateElement ("Canvas");
canvas.style.width = "600px"
canvas.style.height = "600px"
Canvas.Width = 600;
canvas.height = 600;
context = canvas.getContext ("2d");
div.ApendChild (toile);
fonction execDraw ()
{
// résoudre le problème de la largeur de ligne inférieure ou égale à 1 en chrome
context.linewidth = 1,1;
context.strokestyle = "noir"
Paramellipse (contexte, 130, 80, 50, 50); //Cercle
Paramellipse (contexte, 130, 80, 100, 20); // ellipes
Evencompellipse (contexte, 130, 200, 50, 50); //Cercle
Evencompellipse (contexte, 130, 200, 100, 20); // Ellipe
Bezierellipse1 (contexte, 470, 80, 50, 50); //Cercle
Bezierellipse1 (contexte, 470, 80, 100, 20); // Ellipe
Bezierellipse2 (contexte, 470, 200, 50, 50); //Cercle
Bezierellipse2 (contexte, 470, 200, 100, 20); // Ellipe
// Détection de la similitude (degré de chevauchement)
Paramellipse (contexte, 300, 450, 250, 50);
context.strokestyle = "jaune";
Bezierellipse1 (contexte, 300, 450, 250, 50);
context.strokestyle = "bleu";
Bezierellipse2 (contexte, 300, 450, 250, 50);
};
fonction clearcavnas ()
{
context.Clearrect (0, 0, 600, 600);
};
//]]> </ script>
<p>
<bouton onclick = "execDraw ();" type = "Button"> EXECUTER </ftones>
<bouton onclick = "clearCanvas ();" type = "Button"> Clean </ Button>
</p>
Notez que pour exécuter le code avec succès, un navigateur qui prend en charge le toile compatible HTML5 est requis.
C'était la première fois que j'écrivais un blog, et ce n'était pas facile de le faire toute la journée! Le modèle de peau foncée dans le parc du blog ne montre pas bien le code inséré. J'ai pris beaucoup de mal pour obtenir le format de code!