Canvas в HTML5 не дает непосредственно метод рисования эллипсов. Ниже приводится краткое изложение нескольких методов рисования. Различные методы имеют свои собственные преимущества и недостатки и выбираются в соответствии с ситуацией. Параметры каждого метода одинаковы:
Контекст - это объект 2D рисования Canvas,
x - горизонтальная координата центра эллипса.
y - вертикальная координата центра эллипса.
А - длина горизонтальной полуо оси эллипса.
b-длина вертикальной полуо осевой эллипса.
Метод уравнения параметровЭтот метод использует параметрические уравнения эллипса для рисования эллипса
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// параметры x и y функции являются центром эллипса; A и B-горизонтальная полуо осевая эллипса, соответственно
// длина вертикальной полуо осевой не может быть 0 в то же время
// Недостаток этого метода состоит в том, что когда Linwidth шире и эллипс лестно
// Основная ось конец внутреннего эллипса острый, не гладкий и имеет низкую эффективность
Функция Paramellipse (контекст, x, y, a, b)
{
// макс - это больше основных значений оси a и b
// Я увеличивает 1/макс для каждого цикла, что указывает на увеличение степени
// это сделает путь (дугу), нарисованный в каждой петле близко к 1 пикселю
var step = (a> b)? 1 / A: 1 / B;
context.beginpath ();
context.moveto (x + a, y); // рисовать из левой конечной точки эллипса
для (var i = 0; i <2 * math.pi; i += step)
{
// Уравнение параметра - x = a * cos (i), y = b * sin (i),
// параметр I, указывающий на степень (радиан)
context.lineto (x + a * math.cos (i), y + b * math.sin (i));
}
context.closepath ();
Context.Stroke ();
};
Метод равномерного сжатияЭтот метод использует принцип равномерного сжатия в математике, чтобы равномерно сжать круг в эллипс, который теоретически может получить стандартный эллипс. У следующего кода будут проблемы с непоследовательной шириной строки. Решение состоит в том, чтобы увидеть комментарии Саймонлеуна на 5 -м этаже.
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// метод состоит
// масштабирование в направлении горизонтальной или вертикальной оси (даже сжатие)
// Край эллипса, нарисованного в этом методе, становится толще, поскольку край ближе к концу основной оси, а ширина линии конца основной оси нормально
// Чем ближе крайний край к незначительной оси, чем плоская и тоньше эллипс, и даже возникает прерывание. Это результат масштаба.
// Этот недостаток иногда является преимуществом, например, при выражении трехмерного эффекта кольца (планетарный ореол)
// для случая, когда параметры A или B равен 0, этот метод не применим
Функция evencompellipse (контекст, x, y, a, b)
{
context.save ();
// Выберите больший из A и B в качестве параметра RADIUS метода ARC
var r = (a> b)? A: B;
var cationiox = a / r; // коэффициент масштабирования горизонтальной оси
var ratioy = b / r; // коэффициент масштабирования оси размером
Context.Scale (COTIOD, RATIOY); // масштабирование (даже сжатие)
context.beginpath ();
// нарисовать против часовой стрелки с левого конца эллипса
context.moveto ((x + a) / cutiox, y / ratioy);
context.arc (x / cothiox, y / utioy, r, 0, 2 * math.pi);
context.closepath ();
Context.Stroke ();
context.restore ();
};
Кубический метод кривой Bezier OneКубический рисунок кривой безера эллипса является приближением, когда на самом деле рисует, и теоретически это также является приближением. Однако из -за его высокой эффективности он часто используется для рисования эллипсов в компьютерной векторной графике, но я не очень ясно относится к конкретной теории. Приближение заключается в выборе положений двух контрольных точек. Положение контрольной точки этого метода была получена мной, и точность в порядке.
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Этот метод также будет создавать, когда ширина линии шире, а эллипс более плоский.
// длинный конец оси острый и не гладкий
функция Bezierellipse1 (контекст, x, y, a, b)
{
// Ключ - это настройка двух элементов управления в Beziercurveto
//0,5 и 0,6 являются двумя ключевыми коэффициентами (полученными для экспериментов в этой функции)
var ox = 0,5 * a,
Ой = 0,6 * б;
context.save ();
Context.translate (x, y);
context.beginpath ();
// Нарисуйте против часовой стрелки из нижнего конца продольной оси эллипса
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 ();
};
Кубический метод кривой Bezier дваЭтот метод изменяется с ответа на пост в Stackoverflow, с высокой точностью, а также является методом, обычно используемым для рисования эллипсов.
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Этот метод также будет создавать, когда ширина линии шире и эллипс лестно
//, длинная конец оси острый и не гладкий
// Этот метод более точен, чем предыдущий метод Бесселя, но имеет немного менее эффективный метод
Функция Bezierellipse2 (CTX, X, Y, A, B)
{
var k = .5522848,
ox = a * k, // Смещение горизонтальной контрольной точки
oy = b * k; // Смещение вертикальной контрольной точки
ctx.beginpath ();
// нарисовать четыре кубических кривых Безера по часовой стрелке из левой конечной точки эллипса
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 ();
};
Метод решеткиЭтот метод может рисовать эллипсы на основе характеристик холста, способного управлять пикселями и использовать основные алгоритмы в графике. Например, алгоритм эллипса в средней точке и т. Д.
Одним из примеров является сообщение в блоге Doudou, друга сада, класса улучшения Canvas HTML5 (I) - Растровая графика (1) Алгоритм средней точки и круга. Этот метод является относительно примитивным, гибким, эффективным и точным, но более сложно реализовать полезную функцию для рисования эллипсов. Например, когда ширина линии меняется, алгоритм становится более сложным. Хотя это алгоритм для рисования кругов, алгоритм для рисования эллипсов похож на него, поэтому вы можете обратиться к нему ниже.
Демо
Ниже приведены несколько демонстраций рисования функций эллипса в дополнение к растровому методу. Демонстрационный код выглядит следующим образом:
<div id = "canvaswrap" style = "fanogy: #ffff; ширина: 600px; высота: 600px; граница: 1px solid black;"> </div>
<script type = "text/javascript"> // <! [CDATA [
вар холст,
контекст;
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 (холст);
функция execdraw ()
{
// решить проблему ширины линии меньше или равен 1 в хром
Context.linewidth = 1,1;
context.strokestyle = "черный"
Paramellipse (контекст, 130, 80, 50, 50); //Круг
Paramellipse (контекст, 130, 80, 100, 20); // Ellipes
Evencompellipse (контекст, 130, 200, 50, 50); //Круг
Evencompellipse (контекст, 130, 200, 100, 20); // ellipe
Bezierellipse1 (контекст, 470, 80, 50, 50); //Круг
Bezierellipse1 (контекст, 470, 80, 100, 20); // ellipe
Bezierellipse2 (контекст, 470, 200, 50, 50); //Круг
Bezierellipse2 (контекст, 470, 200, 100, 20); // ellipe
// обнаружение сходства (степень совпадения)
Paramellipse (контекст, 300, 450, 250, 50);
context.strokestyle = "желтый";
Bezierellipse1 (контекст, 300, 450, 250, 50);
context.strokestyle = "Blue";
Bezierellipse2 (контекст, 300, 450, 250, 50);
};
Функция clearcavnas ()
{
context.clearrect (0, 0, 600, 600);
};
//]]> </script>
<p>
<button onclick = "execdraw ();" type = "button"> execute </button>
<button onclick = "clearCanvas ();" type = "button"> Clean </button>
</p>
Обратите внимание, что для успешного запуска кода требуется браузер, который поддерживает Canvas с поддержкой HTML5.
Это был первый раз, когда я написал блог, и это было нелегко сделать это весь день! Шаблон темной кожи в парке блога плохо показывает вставленный код. Я приложил большие усилия, чтобы получить формат кода!