базовый курс

ГРУППА КУРСА

Прямоугольники и другие фигуры в Canvas

Перед тем, как рисовать фигуры в Canvas, нужно создать холст и установить для него контекст. О том, как это делать, рассказывалось в предыдущей теме. А здесь я просто напишу код:

HTML код:

+
8
<canvas width="500" height="300"></canvas>

JavaScript:

10
11
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

Установка цвета

Все фигуры в Canvas делятся на два типа:

  1. Закрашенные фигуры
  2. Линии

Для каждого типа цвет устанавливается отдельно. Когда Вы выбрали цвет для какого-то типа, то все фигуры этого типа будут создаваться с таким цветом. Пока Вы не установите другой цвет. Свойство fillStyle содержит цвет для закрашенных фигур, а strokeStyle для линий. Цвет устанавливается любым из способов, существующих в CSS. В том числе, можно использовать систему RGBA и создать прозрачный цвет. Только не забывайте, что значениями этих свойств являются строки. Установим цвет для фигур:

13
14
ctx.fillStyle = '#F0F0F0'; //для линий
ctx.strokeStyle = 'rgba(255,10,38,0.9)'; //для закрашенных фигур

Прямоугольники в Canvas

Для рисования прямоугольников и всех остальных фигур применяются координаты в пикселях. Точкой отсчёта является левый верхний угол холста.

Метод fillRect() рисует закрашенный прямоугольник.

fillRect (X, Y, ширина, высота)

Параметры:

X - координата X левого края прямоугольника

Y - координата Y верхнего края прямоугольника

ширина - ширина прямоугольника

высота - высота прямоугольника

Метод strokeRect() добавляет в Canvas прямоугольник в виде линий. Параметры такие же. Для примера нарисуем прямоугольник во весь холст, чтобы были видны его размеры. И добавим ещё один прямоугольник. Фигуры будут иметь цвета, которые мы установили ранее.

16
17
ctx.fillRect(0, 0, 699, 399);
ctx.strokeRect(10, 60, 70, 100);

Должна получиться такая картинка:

canvas прямоугольник

Фигура может выйти за границы холста. К ошибке это не приведёт, но часть фигуры не будет отображаться.

Контуры

Остальные фигуры в Canvas рисуются с помощью контуров. Это делается так:

  1. Вызываем метод beginPath(), который создаёт новый контур.
  2. С помощью различных методов контекста рисуем сам контур.
  3. Если нужно замкнуть контур, то есть, соединить начальную и конечную точку, то используем метод closePath(). Это может потребоваться только для линий. А у замкнутых фигур контур всегда замыкается, даже если это не сделать.
  4. Вызываем один из методов - либо stroke(), либо fill(), которые рисуют фигуру по контуру. stroke() рисует линию, а fill() заполняет контур.

Контур не отображается на рисунке. Он становится виден, когда по нему нарисована фигура.

Метод lineTo() рисует прямую линию от текущей точки до указанной точки.

lineTo (X, Y)

Указанная точка становится текущей. От неё можно нарисовать ещё одну прямую. И таким образом можно создать сложную линию. Если нужно её прервать и начать новую линию, то используется метод moveTo(), который задаёт новую текущую точку. Все линии остаются частью одного контура. При создании нового контура нужно использовать метод moveTo() для указания начальной точки, от которой начинается контур.

Добавим на рисунок линии:

19
20
21
22
23
24
25
26
27
ctx.strokeStyle = '#0000FF';
ctx.beginPath();
ctx.moveTo(20, 10);
ctx.lineTo(70, 50);
ctx.lineTo(120, 10);
ctx.lineTo(170, 50);
ctx.moveTo(200, 10);
ctx.lineTo(230, 10);
ctx.stroke();

Результат получится такой:

canvas прямоугольник

Замыкать контур не требовалось, поэтому метод closePath() не использован.

Теперь нарисуем закрашенный треугольник.

29
30
31
32
33
34
ctx.fillStyle = '#309053';
ctx.beginPath();
ctx.moveTo(285, 5);
ctx.lineTo(320, 70);
ctx.lineTo(250, 70);
ctx.fill();

Должно выглядеть так:

canvas фигуры

Обратите внимание, нарисовано только две линии. Третья появилась при замыкании контура. Мы ничего не делали для этого. Контур замыкается при заливке.

Стиль линий

Есть несколько свойств, определяуюих стиль линий. Значения этих свойств нужно указывать до того, как линия нарисована. То есть, до метода stroke(). Ширину линий устанавливает свойство lineWidth Значением является число, указывающее ширину в пикселях. Пример:

36
37
38
39
40
41
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(340, 20);
ctx.lineTo(430, 40);
ctx.lineTo(340, 70);
ctx.stroke();

Результат:

 фигуры canvas

Ширину менее 2 пикселей не всегда возможно сделать. Вместо уменьшения ширины линия может становиться прозрачной. Особенно это проявляется на горизонтальных и вертикальных линиях. Для дуги ширина 1 пиксель выглядит нормально. Можно указывать дробные значения.

Свойство lineCap определяет внешний вид краёв линий. Может иметь значения:

butt - плоские (по умолчанию)

round - круглые

square - квадратные

Укажем это свойство при рисовании широкой линии:

37
ctx.lineCap = 'round';

Результат:

Учитывайте, что круглые и квадратные края занимают место на рисунке и увеличивают длину линии.

Свойство lineJoin устанавливает внешний вид угла между двумя линиями. Значения:

miter - острый (по умолчанию)

round - круглый

bevel - срезанный

Пример:

38
ctx.lineJoin = 'round';

Результат:

В этой теме уже рассматривалось рисование прямоугольников. Существует ещё метод rect(), который также добавляет прямоугольник в Canvas. Его отличие в том, что он создаёт контур, по которому далее нужно нарисовать фигуру.

Дуги

Метод arc() рисует дугу определённого радиуса. В том числе, она может нарисовать круг.

arc (X, Y, радиус, начальный угол, конечный угол, направление)

Параметры:

X - координата X центра

Y - координата Y центра

радиус - радиус в пикселях

начальный угол - угол в радианах, от которого начинается дуга Отсчёт производится от самой правой точки окружности

конечный угол - угол в радианах, до которого доходит дуга

направление - направление дуги. false - по часовой стрелке, true - против часовой. По умолчанию установлено false

Начальный и конечный углы указываются так:

Число пи в JavaScript можно получить с помощью свойства Math.PI.

Чтобы нарисовать полный круг, начальный угол можно указать 0, а конечный 2 пи.

Добавим на рисунок окружность.

45
46
47
48
49
ctx.strokeStyle = '#5F0070';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(160, 120, 50, 0, 2*Math.PI);
ctx.stroke();

Результат:

Не обязательно для каждой дуги создавать свой контур. Внутри одного контура можно создать несколько дуг и несколько прямых линий. А потом применить метод arc() и нарисовать по контуру линии. Только цвет и стиль линий будет одинаковый. То же относится и к закрашенным фигурам.

Нарисуем закрашенную фигуру в виде половины круга:

51
52
53
54
ctx.fillStyle = '#B50F20';
ctx.beginPath();
ctx.arc(300, 150, 50, 0.5*Math.PI, 1.5*Math.PI, true);
ctx.fill();

Результат:

Попробуйте нарисовать дуги другой формы.

Метод arcTo() рисует дугу по двум касательным окружности. Касательные формируются по предыдущей точке контура и двум контрольным точкам

arcTo (X1, Y1, X2, Y2, радиус)

Параметры:

X1 - координата X первой контрольной точки

Y1 - координата Y первой контрольной точки

X2 - координата X второй контрольной точки

Y2 - координата Y второй контрольной точки

радиус - радиус дуги

Касательные для дуги определяются так:

Первая касательная проводится через предыдущую точку контура и контрольную точку 1. Предыдущая точка контура - это точка, до которой дошло рисование контура перед созданием дуги. Если контур начинается с дуги, то перед этим нужно использовать метод moveTo() и таким образом создать предыдущую точку.

Вторая касательная проводится через контрольную точку 1 и контрольную точку 2.

По этим двум касательным проходит дуга. Пример:

58
59
60
61
62
ctx.beginPath();
ctx.moveTo(400, 200);
ctx.arcTo(400, 150, 450, 150, 50);
ctx.closePath();
ctx.stroke();

Результат:

Кривые Безье

Кривая Безье - это линия, созданная по специальным базовым точкам. Она начинается на первой базовой точке и заканчивается на последней базовой точке. То есть, первая и последняя точки находятся на линии. А вот остальные, промежуточные точки часто находятся вне линии. Они "оттягивают" линию на себя, и происходит плавное искривление линии. Кривые Безье рассчитываются по математическим формулам. Но при создании изображений это не имеет значения. Для нас важно, что они позволяют рисовать плавные линии сложной формы.

Метод quadraticCurveTo() рисует квадратичную кривую Безье. "Квадратичная" означает, что она рисуется по трём точкам. Первая - это предыдущая точка контура. И ещё две точки указываются в параметрах. Если предыдущей точки контура нет, её нужно создать с помощью метода MoveTo().

quadraticCurveTo (X2, Y2, X3, Y3)

Параметры:

X2 - координата X второй базовой точки

Y2 - координата Y второй базовой точки

X3 - координата X третьей базовой точки

Y3 - координата Y третьей базовой точки

Пример:

62
63
64
65
ctx.beginPath();
ctx.moveTo(10, 190);
ctx.quadraticCurveTo(200, 250, 230, 190);
ctx.stroke();

Результат:

Метод bezierCurveTo() рисует кубическую кривую Безье. Она создаётся по четырём точкам. Первой точкой также является предыдущая точка контура. Соответственно, в параметрах указывается три точки. Пример:

67
68
69
70
ctx.beginPath();
ctx.moveTo(250, 300);
ctx.bezierCurveTo(300, 230, 350, 370, 400, 300);
ctx.stroke();

Результат: