Leinwand in HTML5 bietet keine direkte Methode zum Zeichnen von Ellipsen. Das Folgende ist eine Zusammenfassung mehrerer Zeichenmethoden. Verschiedene Methoden haben ihre eigenen Vor- und Nachteile und werden gemäß der Situation ausgewählt. Die Parameter jeder Methode sind gleich:
Der Kontext ist das 2D -Zeichnungsumfeld von Canvas.
x ist die horizontale Koordinate der Zentrum der Ellipse.
y ist die vertikale Koordinate des Zentrums der Ellipse.
A ist die Länge der horizontalen Halbachse der Ellipse.
B ist die Länge der vertikalen Halbaxis der Ellipse.
ParametergleichungsmethodeDiese Methode verwendet die parametrischen Gleichungen der Ellipse, um eine Ellipse zu zeichnen
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Die Parameter x und y der Funktion sind die Mitte der Ellipse; A und B sind die horizontale Halbachse der Ellipse
// Die Länge der vertikalen Halbachse kann nicht gleichzeitig 0 sein
// Der Nachteil dieser Methode ist, dass wenn die Linwidth breiter ist und die Ellipse schmeichelhaft ist
// Die Hauptachseende der inneren Ellipse ist scharf, nicht glatt und hat eine geringe Effizienz
Funktionsparamellipse (Kontext, x, y, a, b)
{
// max ist der größere der Hauptachelenwerte A und B
// I Erhöhung 1/max für jeden Zyklus, was auf die Zunahme des Grades hinweist
// Dadurch wird der Pfad (ARC) in jeder Schleife nahe 1 Pixel gezeichnet
var Step = (a> b)? 1 / a: 1 / b;
context.beginPath ();
context.moveto (x + a, y); // Zeichnen Sie vom linken Endpunkt der Ellipse
für (var i = 0; i <2 * math.pi; i += Schritt)
{
// Die Parametergleichung ist x = a * cos (i), y = b * sin (i),
// Der Parameter ist I, der den Grad (Radian) angibt
context.lineto (x + a * math.cos (i), y + b * math.sin (i));
}
context.closepath ();
context.stroke ();
};
Einheitliche KomprimierungsmethodeDiese Methode verwendet das Prinzip der einheitlichen Komprimierung in der Mathematik, um den Kreis gleichmäßig in eine Ellipse zu komprimieren, die theoretisch eine Standard -Ellipse erhalten kann. Der folgende Code hat Probleme mit inkonsistenten Linienbreiten. Die Lösung besteht darin, die Kommentare von Simonleung im 5. Stock zu sehen.
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Die Methode besteht darin, den Kreis mithilfe der ARC -Methode zu zeichnen und Skala für zu kombinieren
// Skalierung in der horizontalen oder vertikalen Achsenrichtung (sogar Kompression)
// Die Kante der in dieser Methode gezogenen Ellipse wird dicker, da die Kante näher am Ende der Hauptachse liegt, und die Linienbreite des Endes der Hauptachse ist normal
// Je näher die Kante an der kleinen Achse liegt, desto flacher und dünner die Ellipse und sogar Unterbrechung wird verursacht. Dies ist das Ergebnis der Skala.
// Dieser Nachteil ist manchmal ein Vorteil, z.
// für den Fall, in dem die Parameter A oder B 0 sind, ist diese Methode nicht anwendbar
Funktion evencompellipse (Kontext, x, y, a, b)
{
context.save ();
// Wählen Sie das größere von A und B als Radius -Parameter der ARC -Methode aus
var r = (a> b)? A: B;
var Ratiox = a / r; // Skalierungsverhältnis der horizontalen Achse
var ratioy = b / r; // Dimensionalachse Skalierungsverhältnis
Context.Scale (Ratiox, Ratioy); // Skalierung (sogar Komprimierung)
context.beginPath ();
// gegen den Uhrzeigersinn vom linken Ende der Ellipse zeichnen
context.moveto ((x + a) / rettiox, y / ratioy);
context.arc (x / rettiox, y / ratioy, r, 0, 2 * math.pi);
context.closepath ();
context.stroke ();
context.restore ();
};
Kubikbezier -Kurvenmethode einsDie kubische Bezier -Kurve -Zeichnung einer Ellipse ist eine Annäherung beim Tatsächlich und theoretisch auch eine Näherung. Aufgrund seiner hohen Effizienz wird es jedoch häufig verwendet, um Ellipsen in Computervektorgrafiken zu zeichnen, aber ich bin nicht sehr klar über die spezifische Theorie. Die Näherung liegt in der Auswahl der Positionen der beiden Kontrollpunkte. Die Kontrollpunktposition dieser Methode wurde von mir selbst erhalten und die Genauigkeit ist in Ordnung.
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Diese Methode erzeugt auch, wenn die Linienbreite breiter ist und die Ellipse flacher ist.
// Das Ende der langen Achse ist scharf und nicht glatt
Funktion Bezierellipse1 (Kontext, x, y, a, b)
{
// Der Schlüssel ist die Einstellung von zwei Steuerpunkten in BezierCurveto
//0.5 und 0,6 sind zwei wichtige Koeffizienten (für das Experimentieren in dieser Funktion erhalten)
var ox = 0,5 * a,,
oy = 0,6 * b;
context.save ();
context.translate (x, y);
context.beginPath ();
// gegen den Uhrzeigersinn vom unteren Ende der Ellipse -Längsachse zeichnen
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 ();
};
Kubikbezier -Kurvenmethode zweiDiese Methode wird von der Antwort auf einen Beitrag in Stackoverflow mit hoher Genauigkeit geändert und ist auch eine Methode, die häufig zum Zeichnen von Ellipsen verwendet wird.
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Diese Methode erzeugt auch, wenn die Linienbreite breiter ist und die Ellipse schmeichelhaft ist
// Das Ende der langen Achse ist scharf und nicht glatt
// Diese Methode ist genauer als die vorherige Bessel -Methode, hat jedoch eine etwas weniger effiziente Methode
Funktion Bezierellipse2 (CTX, X, Y, A, B)
{
var k = .5522848,
OX = A * K, // Horizontaler Kontrollpunktpunktausgleich
oy = b * k; // vertikaler Kontrollpunkt -Offset
ctx.beginPath ();
// vier Kubikkurven im Uhrzeigersinn aus dem linken Endpunkt der Ellipse zeichnen
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 ();
};
GittermethodeDiese Methode kann Ellipsen basierend auf den Eigenschaften von Leinwand zeichnen, um Pixel zu bedienen und grundlegende Algorithmen in Grafiken zu verwenden. Zum Beispiel der Ellipse -Algorithmus zum Mittelpunkt Zeichnen usw.
Ein Beispiel ist ein Blog -Beitrag von Doudou, einem Gartenfreund, HTML5 -Leinwandverbesserungsklasse (I) - Rastergrafik (1) Mittelpunkt und Kreisalgorithmus. Diese Methode ist relativ primitiv, flexibel, effizient und genau, aber es ist komplizierter, eine nützliche Funktion zum Zeichnen von Ellipsen zu realisieren. Wenn sich beispielsweise die Linienbreite ändert, wird der Algorithmus komplizierter. Obwohl es sich um einen Algorithmus zum Zeichnen von Kreisen handelt, ähnelt der Algorithmus zum Zeichnen von Ellipsen ihm, sodass Sie sich im Folgenden darauf verweisen können.
Demo
Im Folgenden finden Sie mehrere Demonstrationen des Zeichnens von Ellipsefunktionen zusätzlich zur Rastermethode. Der Demonstrationscode lautet wie folgt:
<div id = "canvaswrap" style = "Hintergrund: #ffff; Breite: 600px; Höhe: 600px; Grenze: 1px solid schwarz;"> </div>
<script type = "text/javaScript"> // <! [cdata [
var canvas,
Kontext;
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.AppendChild (Leinwand);
Funktion execdraw ()
{
// Lösen Sie das Problem der Linienbreite weniger als oder gleich 1 in Chrome
context.lineWidth = 1.1;
context.strokestyle = "schwarz"
Paramellipse (Kontext, 130, 80, 50, 50); //Kreis
Paramellipse (Kontext, 130, 80, 100, 20); // Ellipes
Evencompellipse (Kontext, 130, 200, 50, 50); //Kreis
Evencompellipse (Kontext, 130, 200, 100, 20); // Ellipe
Bezierellipse1 (Kontext 470, 80, 50, 50); //Kreis
Bezierellipse1 (Kontext 470, 80, 100, 20); // Ellipe
Bezierellipse2 (Kontext 470, 200, 50, 50); //Kreis
Bezierellipse2 (Kontext 470, 200, 100, 20); // Ellipe
// Ähnlichkeitserkennung (Überlappungsgrad)
Paramellipse (Kontext 300, 450, 250, 50);
context.strokestyle = "gelb";
Bezierellipse1 (Kontext 300, 450, 250, 50);
context.strokestyle = "blau";
Bezierellipse2 (Kontext 300, 450, 250, 50);
};
Funktion clearCavnas ()
{
context.clearRect (0, 0, 600, 600);
};
//]]> </script>
<p>
<button onclick = "execdraw ();" Typ = "Button"> Ausführen </button>
<button onclick = "clearcanvas ();" Typ = "Button"> Reinigen </button>
</p>
Beachten Sie, dass ein Browser, der HTML5-fähige Leinwand unterstützt, zum erfolgreichen Code erfolgreich ausführt.
Es war das erste Mal, dass ich einen Blog schrieb, und es war nicht einfach den ganzen Tag! Die dunkle Hautvorlage im Blog Park zeigt den eingefügten Code nicht gut an. Ich habe große Mühe gegeben, das Codeformat zu erhalten!