El lienzo en HTML5 no proporciona directamente un método para dibujar elipses. El siguiente es un resumen de varios métodos de dibujo. Varios métodos tienen sus propias ventajas y desventajas, y se seleccionan de acuerdo con la situación. Los parámetros de cada método son los mismos:
El contexto es el objeto de entorno de dibujo 2D de lienzo,
X es la coordenada horizontal del centro de la elipse.
y es la coordenada vertical del centro de la elipse.
A es la longitud del medio eje horizontal de la elipse.
B es la longitud del medio eje vertical de la elipse.
Método de ecuación de parámetrosEste método utiliza las ecuaciones paramétricas de la elipse para dibujar una elipse
// -----------------------------------------------------------------------------------------------
// Los parámetros x e y de la función son el centro de la elipse; A y B son el medio eje horizontal de la elipse, respectivamente
// La longitud del medio eje vertical no puede ser 0 al mismo tiempo
// La desventaja de este método es que cuando el ancho de Linwidth es más amplio y la elipse es halagadora
// El extremo del eje principal de la elipse interna es agudo, no suave y tiene baja eficiencia
función paramellipse (context, x, y, a, b)
{
// Max es el mayor de los valores principales del eje A y B
// Aumento 1/max para cada ciclo, lo que indica el aumento en el grado
// Esto hará que la ruta (arco) se dibuje en cada bucle cerca de 1 píxel
var paso = (a> b)? 1 / A: 1 / B;
context.beginPath ();
context.moveto (x + a, y); // dibujar desde el punto final izquierdo de la elipse
para (var i = 0; i <2 * math.pi; i += step)
{
// La ecuación del parámetro es x = a * cos (i), y = b * sin (i),
// El parámetro es I, que indica el grado (radian)
context.lineto (x + a * math.cos (i), y + b * math.sin (i));
}
context.ClosePath ();
context.stroke ();
};
Método de compresión uniformeEste método utiliza el principio de compresión uniforme en matemáticas para comprimir uniformemente el círculo en una elipse, que teóricamente puede obtener una elipse estándar. El siguiente código tendrá problemas con anchos de línea inconsistentes. La solución es ver los comentarios de Simonleung en el quinto piso.
// -----------------------------------------------------------------------------------------------
// El método es dibujar el círculo usando el método de arco y combinar la escala para
// Escala en la dirección del eje horizontal o vertical (incluso compresión)
// El borde de la elipse dibujada en este método se vuelve más grueso a medida que el borde está más cerca del final del eje principal, y el ancho de línea del extremo del eje principal es normal
// cuanto más cerca esté el borde del eje menor, el más plano y más delgado es la elipse, e incluso se causa la interrupción. Este es el resultado de la escala.
// Esta desventaja es a veces una ventaja, como cuando se expresa el efecto tridimensional del anillo (halo planetario)
// Para el caso donde los parámetros A o B son 0, este método no es aplicable
función evencomPellipse (contexto, x, y, a, b)
{
context.save ();
// Seleccione el más grande de A y B como el parámetro RADIUS del método ARC
var r = (a> b)? A: B;
var ratiox = a / r; // relación de escala del eje horizontal
var ratioy = b / r; // relación de escala del eje dimensional
context.scale (Ratiox, Ratioy); // Escala (incluso compresión)
context.beginPath ();
// dibujar en sentido antihorario desde el extremo izquierdo de la elipse
context.moveto ((x + a) / ratiox, y / ratoy);
context.arc (x / ratiox, y / ratioy, r, 0, 2 * math.pi);
context.ClosePath ();
context.stroke ();
context.restore ();
};
Método de la curva de Bezier cúbico unoEl dibujo de la curva de Bezier cúbica de una elipse es una aproximación al dibujar, y en teoría también es una aproximación. Sin embargo, debido a su alta eficiencia, a menudo se usa para dibujar elipses en gráficos vectoriales de la computadora, pero no tengo mucho claro sobre la teoría específica. La aproximación se encuentra en la selección de las posiciones de los dos puntos de control. La posición del punto de control de este método fue obtenida por mí mismo y la precisión está bien.
// -----------------------------------------------------------------------------------------------
// Este método también producirá cuando el ancho de línea sea más amplio y la elipse es más plana.
// El extremo del eje largo es agudo y no suave
función Bezierellipse1 (contexto, x, y, a, b)
{
// La clave es la configuración de dos puntos de control en Beziercurveto
//0.5 y 0.6 son dos coeficientes clave (obtenidos para la experimentación en esta función)
var ox = 0.5 * a,
oy = 0.6 * b;
context.save ();
context.translate (x, y);
context.beginPath ();
// Dibuje en sentido antihorario desde el extremo inferior del eje longitudinal de elipse
context.moveto (0, b);
context.beziercurveto (buey, 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étodo de la curva de Bezier cúbico dosEste método se cambia de la respuesta a una publicación en StackOverflow, con alta precisión y también es un método comúnmente utilizado para dibujar elipses.
// -----------------------------------------------------------------------------------------------
// Este método también producirá cuando el ancho de línea sea más amplio y la elipse es halagadora
//, el extremo del eje largo es agudo y no suave
// Este método es más preciso que el método Bessel anterior, pero tiene un método un poco menos eficiente
Función Bezierellipse2 (CTX, X, Y, A, B)
{
var k = .5522848,
ox = a * k, // desplazamiento del punto de control horizontal
oy = b * k; // desplazamiento del punto de control vertical
ctx.beginpath ();
// Dibuja cuatro curvas bezier cúbicas en sentido horario desde el punto de extremo izquierdo de la elipse
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étodo de rejillaEste método puede dibujar elipses en función de las características del lienzo que pueden operar píxeles y usar algoritmos básicos en gráficos. Por ejemplo, el algoritmo de elipse de dibujo de punto medio, etc.
Un ejemplo es una publicación de blog de Dudou, un amigo de jardín, clase de mejora de lienzo HTML5 (I) - gráficos de trama (1) Algoritmo de punto medio y círculo. Este método es relativamente primitivo, flexible, eficiente y preciso, pero es más complicado realizar una función útil para dibujar elipses. Por ejemplo, cuando cambia el ancho de línea, el algoritmo se vuelve más complicado. Aunque es un algoritmo para dibujar círculos, el algoritmo para dibujar elipses es similar a él, por lo que puede consultarlo a continuación.
Manifestación
Las siguientes son varias demostraciones de dibujos de funciones de elipse además del método ráster. El código de demostración es el siguiente:
<div id = "Canvaswrap" style = "Fondo: #ffff; ancho: 600px; altura: 600px; borde: 1px sólido negro;"> </div>
<script type = "text/javaScript"> // <! [Cdata [
Var Canvas,
contexto;
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 (lienzo);
función execdraw ()
{
// Resolver el problema del ancho de línea menor o igual a 1 en Chrome
context.linewidth = 1.1;
context.strokestyle = "negro"
Paramellipse (contexto, 130, 80, 50, 50); //Círculo
Paramellipse (contexto, 130, 80, 100, 20); // ellipes
EvencomPellipse (contexto, 130, 200, 50, 50); //Círculo
EvencomPellipse (contexto, 130, 200, 100, 20); // ellipe
Bezierellipse1 (contexto, 470, 80, 50, 50); //Círculo
Bezierellipse1 (contexto, 470, 80, 100, 20); // ellipe
Bezierellipse2 (contexto, 470, 200, 50, 50); //Círculo
Bezierellipse2 (contexto, 470, 200, 100, 20); // ellipe
// Detección de similitud (grado de superposición)
Paramellipse (contexto, 300, 450, 250, 50);
context.StrokeStyle = "amarillo";
Bezierellipse1 (contexto, 300, 450, 250, 50);
context.strokestyle = "azul";
Bezierellipse2 (contexto, 300, 450, 250, 50);
};
función ClearCavnas ()
{
context.clearrect (0, 0, 600, 600);
};
//]]> </script>
<p>
<Button onClick = "ExecDraw ();" type = "botón"> ejecutar </boton>
<Button onClick = "ClearCanvas ();" type = "Button"> Clean </Button>
</p>
Tenga en cuenta que para ejecutar el código con éxito, se requiere un navegador que admita el lienzo habilitado para HTML5.
Era la primera vez que escribí un blog, ¡y no fue fácil hacerlo todo el día! La plantilla de piel oscura en el Blog Park no muestra bien el código insertado. ¡Me he esforzado mucho para obtener el formato de código!