Canvas как нарисовать квадрат
Перейти к содержимому

Canvas как нарисовать квадрат

  • автор:

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

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

let canvas = document.querySelector('canvas'); let ctx = canvas.getContext('2d');

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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() рисует прямую линию от текущей точки до указанной точки.

Указанная точка становится текущей. От неё можно нарисовать ещё одну прямую. И таким образом можно создать сложную линию. Если нужно её прервать и начать новую линию, то используется метод 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 — плоские (по умолчанию)

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

ctx.lineCap = 'round';

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

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

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

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() и нарисовать по контуру линии. Только цвет и стиль линий будет одинаковый. То же относится и к закрашенным фигурам.

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

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 третьей базовой точки

ctx.beginPath(); ctx.moveTo(10, 190); ctx.quadraticCurveTo(200, 250, 230, 190); ctx.stroke();

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

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

Коприрование материалов сайта возможно только с согласия администрации

2017 — 2023 © basecourse.ru Все права защищены

Canvas как нарисовать квадрат

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

Для создания нового пути надо вызвать метод beginPath() , а после завершения пути вызывается метод closePath() :

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.beginPath(); // здесь инструкции по созданию фигур context.closePath();

Между вызовами методов beginPath() и closePath() находятся методы, непосредственно создающие различные участки пути.

Методы moveTo() и lineTo()

Для начала рисования пути нам надо зафиксировать начальную точку этого пути. Это можно сделать с помощью метода moveTo() , который имеет следующее определение:

moveTo(x, y)

Метод перемещает нас на точку с координатами x и y.

Метод lineTo() рисует линию. Он имеет похожее определение:

lineTo(x, y)

Метод рисует линию от текущей позиции до точки с координатами x и y.

Теперь нарисуем ряд линий:

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.beginPath(); context.moveTo(30, 20); context.lineTo(100, 80); context.lineTo(150, 30); context.closePath();

Здесь мы устанавливаем начало пути в точку (30, 20), затем от нее рисуем линию до точки (100, 80) и далее рисуем еще одну линию до точки (150, 30).

Хотя мы нарисовали несколько линий, пока мы их не увидим, потому что их надо отобразить на экране. Для отображения пути надо использовать метод stroke() :

    Canvas в HTML5   Ваш браузер не поддерживает Canvas    

Рисование линий на canvas в HTML5

Хотя мы нарисовали все две линии, но по факту мы увидим три линии, которые оформляют треугольник. Дело в том, что вызов метода context.closePath() завершает путь, соединяя последнюю точку с первой. И в результате образуется замкнутый контур.

Если нам не надо замыкание пути, то мы можем удалить вызов метода context.closePath() :

Метод rect

Метод rect() создает прямоугольник. Он имеет следующее определение:

rect(x, y, width, height)

Где x и y — это координаты верхнего левого угла прямоугольника относительно canvas, а width и height — соответственно ширина и высота прямоугольника. Нарисуем, к примеру, следующий прямоугольник:

    Canvas в HTML5   Ваш браузер не поддерживает Canvas    

Рисование прямоугольника на canvas в HTML5

Стоит отметить, что такой же прямоугольник мы могли бы создать из линий:

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.beginPath(); context.moveTo(30, 20); context.lineTo(130, 20); context.lineTo(130, 110); context.lineTo(30, 110); context.closePath(); context.strokeStyle = "red"; context.stroke();

Метод fill()

Метод fill() заполняет цветом все внутреннее пространство нарисованного пути:

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.beginPath(); context.rect(30, 20, 100, 90); context.closePath(); context.strokeStyle = "red"; context.fillStyle = "blue"; context.fill(); context.stroke();

С помощью свойства fillStyle опять же можно задать цвет заполнения фигуры. В данном случае это синий цвет.

Закрашивание фигур на canvas в HTML5

Метод clip()

Метод clip() позволяет вырезать из canvas определенную область, а все, что вне этой области, будет игнорироваться при последующей отрисовке.

Для понимания этого метода сначала нарисуем два прямоугольника:

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); // рисуем первый красный прямоугольник context.beginPath(); context.moveTo(30, 20); context.lineTo(130, 20); context.lineTo(130, 110); context.lineTo(30, 110); context.closePath(); context.strokeStyle = "red"; context.stroke(); // рисуем второй зеленый прямоугольник context.beginPath(); context.rect(10, 50, 180, 70); context.closePath(); context.strokeStyle = "green"; context.stroke();

Теперь применим метод clip() для ограничения области рисования только первым прямоугольником:

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); // рисуем первый красный прямоугольник context.beginPath(); context.moveTo(30, 20); context.lineTo(130, 20); context.lineTo(130, 110); context.lineTo(30, 110); context.closePath(); context.strokeStyle = "red"; context.stroke(); context.clip(); // рисуем второй зеленый прямоугольник context.beginPath(); context.rect(10, 50, 180, 70); context.closePath(); context.strokeStyle = "green"; context.stroke();

clip на canvas в HTML5

Поскольку вызов метода clip() идет после первого прямоугольника, то из второго прямоугольника будет нарисована только та часть, которая попадает в первый прямоугольник.

Метод arc()

Метод arc() добавляет к пути участок окружности или арку. Он имеет следующее определение:

arc(x, y, radius, startAngle, endAngle, anticlockwise)

Здесь используются следующие параметры:

  • x и y : x- и y-координаты, в которых начинается арка
  • radius : радиус окружности, по которой создается арка
  • startAngle и endAngle : начальный и конечный угол, которые усекают окржность до арки. В качестве единици измерения для углов применяются радианы. Например, полная окружность — это 2π радиан. Если, к примеру, нам надо нарисовать полный круг, то для параметра endAngle можно указать значение 2π. В JavaScript эту веричину можно получить с помощью выражения Math.PI * 2 .
  • anticlockwise : направление движения по окружности при отсечении ее части, ограниченной начальным и конечным углом. При значении true направление против часовой стрелки, а при значении false — по часовой стрелке.
    Canvas в HTML5   Ваш браузер не поддерживает Canvas    

Рисование кругов на canvas в HTML5

Последний параметр anticlockwise играет важную роль, так как определяет движение по окружности, и в случае изменения true на false и наоборот, мы можем получить совершенно разные фигуры:

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.strokeStyle = "red"; context.beginPath(); context.moveTo(80, 90); context.arc(80, 90, 50, 0, Math.PI/2, false); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(240, 90); context.arc(240, 90, 50, 0, Math.PI/2, true); context.closePath(); context.stroke();

Метод arcTo()

Метод arcTo() также рисует дугу. Он имеет следующее определение:

arcTo(x1, y1, x2, y2, radius)

Где x1 и y1 — координаты первой контрольной точки, x2 и y2 — координаты второй контрольной точки, а radius — радиус дуги.

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.strokeStyle = "red"; context.beginPath(); context.moveTo(0, 150); context.arcTo(0, 0, 150, 0, 140) context.closePath(); context.stroke();

Здесь мы перемещаемся вначале на точку (0, 150), и от этой точки до первой контрольной точки (0, 0) будет проходить первая касательная. Далее от первой контрольной точки (0, 0) до второй (150, 0) будет проходить вторая касательная. Эти две касательные оформляют дугу, а 140 служит радиусом окружности, на которой усекается дуга.

Метод quadraticCurveTo()

Метод quadraticCurveTo() создает квадратичную кривую. Он имеет следующее определение:

quadraticCurveTo(x1, y1, x2, y2)

Где x1 и y1 — координаты первой опорной точки, а x2 и y2 — координаты второй опорной точки.

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.strokeStyle = "red"; context.beginPath(); context.moveTo(20, 90); context.quadraticCurveTo(130, 0, 280, 90) context.closePath(); context.stroke();

Квадратичная кривая Безье на canvas в HTML5

Метод bezierCurveTo(). Кривая Безье

Метод bezierCurveTo() рисует кривую Безье. Он имеет следующее определение:

bezierCurveTo(x1, y1, x2, y2, x3, y3)

Где x1 и y1 — координаты первой опорной точки, x2 и y2 — координаты второй опорной точки, а x3 и y3 — координаты третьей опорной точки.

var canvas = document.getElementById("myCanvas"), context = canvas.getContext("2d"); context.strokeStyle = "red"; context.beginPath(); context.moveTo(30, 100); context.bezierCurveTo(110, 0, 190, 200, 270, 100); context.closePath(); context.stroke();

Кривая Безье на canvas в HTML5

Комплексные фигуры

Объединим несколько фигур вместе и нарисуем более сложную двухмерную сцену:

    Canvas в HTML5   Ваш браузер не поддерживает Canvas    

Рисование фигур с помощью canvas

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

Сетка

Перед тем, как мы начнём рисовать, нам нужно поговорить о сетке canvas или координатной плоскости. Наш HTML каркас из предыдущей страницы включал в себя элемент canvas 150 пикселей в ширину и 150 пикселей в высоту. Справа можно увидеть этот canvas с сеткой, накладываемой по умолчанию. Обычно 1 единица на сетке соответствует 1 пикселю на canvas. Начало координат этой сетки расположено в верхнем левом углу в координате (0,0 ) . Все элементы размещены относительно этого начала. Таким образом, положение верхнего левого угла синего квадрата составляет х пикселей слева и у пикселей сверху, на координате (х, у) . Позже в этом уроке мы увидим, как можно перевести начало координат в другое место, вращать сетку и даже масштабировать её, но сейчас мы будем придерживаться настроек сетки по умолчанию.

Рисование прямоугольников

Сначала рассмотрим прямоугольник. Ниже представлены три функции рисования прямоугольников в canvas:

Рисование заполненного прямоугольника.

Рисование прямоугольного контура.

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

Каждая из приведённых функций принимает несколько параметров:

  • x, y устанавливают положение верхнего левого угла прямоугольника в canvas (относительно начала координат);
  • width (ширина) и height (высота) определяют размеры прямоугольника.

Ниже приведена функция draw(), использующая эти три функции.

Пример создания прямоугольных фигур

html> body onload="draw();"> canvas id="canvas" width="150" height="150">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); ctx.fillRect(25, 25, 100, 100); ctx.clearRect(45, 45, 60, 60); ctx.strokeRect(50, 50, 50, 50); > > 

Этот пример изображён ниже.

Функция fillRect() рисует большой чёрный квадрат со стороной 100 px. Функция clearRect() вырезает квадрат 60х60 из центра, а функция strokeRect() создаёт прямоугольный контур 50х50 пикселей внутри очищенного квадрата.

На следующей странице мы рассмотрим две альтернативы методу clearRect(), и также увидим, как можно изменять цвет и стиль контура отображаемых фигур.

В отличие от функций создания контуров, которые будут рассмотрены в следующем разделе, все три функции создания прямоугольника сразу же отображаются на canvas.

Рисование контуров (path)

Остальные примитивные фигуры создаются контурами. Контур — это набор точек, которые, соединяясь в отрезки линий, могут образовывать различные фигуры, изогнутые или нет, разной ширины и разного цвета. Контур (или субконтур) может быть закрытым.

Создание фигур используя контуры происходит в несколько важных шагов:

  1. Сначала вы создаёте контур.
  2. Затем, используя команды рисования, рисуете контур.
  3. Потом закрываете контур.
  4. Созданный контур вы можете обвести или залить для его отображения.

Здесь приведены функции, которые можно использовать в описанных шагах:

Создаёт новый контур. После создания используется в дальнейшем командами рисования при построении контуров.

Методы для установки различных контуров объекта.

Закрывает контур, так что будущие команды рисования вновь направлены контекст.

Рисует фигуру с внешней обводкой.

Рисует фигуру с заливкой внутренней области.

Первый шаг создания контура заключается в вызове функции beginPath() . Внутри содержатся контуры в виде набора суб-контуров (линии, дуги и др.), которые вместе образуют форму фигуры. Каждый вызов этого метода очищает набор, и мы можем начинать рисовать новые фигуры.

Примечание: если текущий контур пуст (например, как после вызова beginPath() или на вновь созданном canvas), первой командой построения контура всегда является функция moveTo() . Поэтому мы всегда можем установить начальную позицию рисования контура после перезагрузки.

Вторым шагом является вызов методов, определяемых видом контура, который нужно нарисовать. Их мы рассмотрим позднее.

Третий и необязательный шаг — это вызов closePath() . Этот метод пытается закрыть фигуру, рисуя прямую линию из текущей точки в начальную. Если фигура была уже закрыта или является просто точкой, то функция ничего не делает.

Примечание: Когда вы вызываете fill() , то каждая открытая фигура закрывается автоматически, так что вы можете не использовать closePath() . Это обстоятельство не имеет место в случае вызова stroke() .

Рисование треугольника

Например, код для рисования треугольника будет выглядеть как-то так:

html> body onload="draw();"> canvas id="canvas" width="100" height="100">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(75, 50); ctx.lineTo(100, 75); ctx.lineTo(100, 25); ctx.fill(); > > 

Результат выглядит так:

Передвижение пера

Одна очень полезная функция, которая ничего не рисует, но связана по смыслу с вышеописанными функциями — это moveTo() . Вы можете представить это как отрыв (подъем) пера от бумаги и его перемещение в другое место.

Перемещает перо в точку с координатами x и y.

При инициализации canvas или при вызове beginPath() , вы захотите использовать функцию moveTo() для перемещения в точку начала рисования. Можно использовать moveTo() и для рисования несвязанного(незакрытого) контура. Посмотрите на смайлик ниже.

Вы можете проверить это сами, используя участок кода ниже. Просто вставьте в функцию draw() , рассмотренную ранее.

html> body onload="draw();"> canvas id="canvas" width="150" height="150">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Внешняя окружность ctx.moveTo(110, 75); ctx.arc(75, 75, 35, 0, Math.PI, false); // рот (по часовой стрелке) ctx.moveTo(65, 65); ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // Левый глаз ctx.moveTo(95, 65); ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // Правый глаз ctx.stroke(); > > 

Результат этого ниже:

Если вы захотите увидеть соединение линии, то можете удалить вызов moveTo() .

Примечание: Подробнее о функции arc() ,посмотрите Дуги .

Линии

Для рисования прямых линий используйте метод lineTo() .

Рисует линию с текущей позиции до позиции, определённой x и y .

Этот метод принимает два аргумента x и y , которые являются координатами конечной точки линии. Начальная точка зависит от ранее нарисованных путей, причём конечная точка предыдущего пути является начальной точкой следующего и т. д. Начальная точка также может быть изменена с помощью метода moveTo() .

Пример ниже рисует два треугольника, один закрашенный и другой обведён контуром.

html> body onload="draw();"> canvas id="canvas" width="150" height="150">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); // Filled triangle ctx.beginPath(); ctx.moveTo(25, 25); ctx.lineTo(105, 25); ctx.lineTo(25, 105); ctx.fill(); // Stroked triangle ctx.beginPath(); ctx.moveTo(125, 125); ctx.lineTo(125, 45); ctx.lineTo(45, 125); ctx.closePath(); ctx.stroke(); > > 

Отрисовка начинается с вызова beginPath() , чтобы начать рисовать путь новой фигуры. Затем мы используем метод moveTo() , чтобы переместить начальную точку в нужное положение. Ниже рисуются две линии, которые образуют две стороны треугольника.

Вы заметите разницу между закрашенным и обведённым контуром треугольниками. Это, как упоминалось выше, из-за того, что фигуры автоматически закрываются, когда путь заполнен (т. е. закрашен), но не тогда, когда он очерчен (т. е. обведён контуром). Если бы мы не учли closePath() для очерченного треугольника, тогда только две линии были бы нарисованы, а не весь треугольник.

Дуги

Для рисования дуг и окружностей, используем методы arc() и arcTo().

Рисуем дугу с центром в точке (x,y) радиусом radius , начиная с угла startAngle и заканчивая в endAngle в направлении против часовой стрелки anticlockwise (по умолчанию по ходу движения часовой стрелки).

Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.

Рассмотрим детальнее метод arc(), который имеет пять параметров: x и y — это координаты центра окружности, в которой должна быть нарисована дуга. radius — не требует пояснений. Углы startAngle и endAngle определяют начальную и конечную точки дуги в радианах вдоль кривой окружности. Отсчёт происходит от оси x. Параметр anticlockwise — логическое значение, которое, если true , то рисование дуги совершается против хода часовой стрелки; иначе рисование происходит по ходу часовой стрелки.

Примечание: Углы в функции arc() измеряют в радианах, не в градусах. Для перевода градусов в радианы вы можете использовать JavaScript-выражение: radians = (Math.PI/180)*degrees .

Следующий пример немного сложнее, чем мы рассматривали ранее. Здесь нарисованы 12 различных дуг с разными углами и заливками.

Два for цикла размещают дуги по столбцам и строкам. Для каждой дуги, мы начинаем новый контур, вызывая beginPath() . В этом коде каждый параметр дуги для большей ясности задан в виде переменной, но вам не обязательно делать так в реальных проектах.

Координаты x и y должны быть достаточно ясны. radius and startAngle — фиксированы. endAngle начинается со 180 градусов (полуокружность) в первой колонке и, увеличиваясь с шагом 90 градусов, достигает кульминации полноценной окружностью в последнем столбце.

Установка параметра clockwise определяет результат; в первой и третьей строках рисование дуг происходит по часовой стрелке, а во второй и четвёртой — против часовой стрелки. Благодаря if-условию верхняя половина дуг образуется с контуром, (обводкой), а нижняя половина дуг — с заливкой.

Примечание: Этот пример требует немного большего холста (canvas), чем другие на этой странице: 150 x 200 pixels.

html> body onload="draw();"> canvas id="canvas" width="150" height="200">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); for (var i = 0; i  4; i++)  for (var j = 0; j  3; j++)  ctx.beginPath(); var x = 25 + j * 50; // x coordinate var y = 25 + i * 50; // y coordinate var radius = 20; // Arc radius var startAngle = 0; // Starting point on circle var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle var anticlockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise); if (i > 1)  ctx.fill(); > else  ctx.stroke(); > > > > > 

Безье и квадратичные кривые

Следующим типом доступных контуров являются кривые Безье, и к тому же доступны в кубическом и квадратичном вариантах. Обычно они используются при рисовании сложных составных фигур.

Рисуется квадратичная кривая Безье с текущей позиции пера в конечную точку с координатами x и y , используя контрольную точку с координатами cp1x и cp1y .

Рисуется кубическая кривая Безье с текущей позиции пера в конечную точку с координатами x и y , используя две контрольные точки с координатами ( cp1x , cp1y ) и (cp2x, cp2y).

Различие между ними можно увидеть на рисунке, изображённом справа. Квадратичная кривая Безье имеет стартовую и конечную точки (синие точки) и всего одну контрольную точку (красная точка), в то время как кубическая кривая Безье использует две контрольные точки.

Параметры x и y в этих двух методах являются координатами конечной точки. cp1x и cp1y — координаты первой контрольной точки, а cp2x и cp2y — координаты второй контрольной точки.

Использование квадратичных или кубических кривых Безье может быть спорным выходом, так как в отличие от приложений векторной графики типа Adobe Illustrator, мы не имеем полной видимой обратной связи с тем, что мы делаем. Этот факт делает довольно сложным процесс рисования сложных фигур. В следующем примере мы нарисуем совсем простую составную фигуру, но, если у вас есть время и ещё больше терпения, можно создать более сложные составные фигуры.

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

Квадратичные кривые Безье

В этом примере многократно используются квадратичные кривые Безье для рисования речевой выноски.

html> body onload="draw();"> canvas id="canvas" width="150" height="150">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); // Quadratric curves example ctx.beginPath(); ctx.moveTo(75, 25); ctx.quadraticCurveTo(25, 25, 25, 62.5); ctx.quadraticCurveTo(25, 100, 50, 100); ctx.quadraticCurveTo(50, 120, 30, 125); ctx.quadraticCurveTo(60, 120, 65, 100); ctx.quadraticCurveTo(125, 100, 125, 62.5); ctx.quadraticCurveTo(125, 25, 75, 25); ctx.stroke(); > > 
Кубические кривые Безье

В этом примере нарисовано сердце с использованием кубических кривых Безье.

html> body onload="draw();"> canvas id="canvas" width="150" height="150">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); // Cubic curves example ctx.beginPath(); ctx.moveTo(75, 40); ctx.bezierCurveTo(75, 37, 70, 25, 50, 25); ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5); ctx.bezierCurveTo(20, 80, 40, 102, 75, 120); ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5); ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25); ctx.bezierCurveTo(85, 25, 75, 37, 75, 40); ctx.fill(); > > 

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

Все эти методы мы видели в Рисование прямоугольников, которые рисуют прямоугольники сразу в canvas, так же есть метод rect() , который не отображает, а только добавляет контур рисования (path) заданного прямоугольника к последнему открытому контуру.

Добавляет в path прямоугольник, верхний левый угол которого указан с помощью (x, y) с вашими width и height

Когда этот метод вызван, автоматически вызывается метод moveTo() с параметрами (x, y). Другими словами, позиция курсора устанавливается в начало добавленного прямоугольника.

Создание комбинаций

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

html> body onload="draw();"> canvas id="canvas" width="150" height="150">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); roundedRect(ctx, 12, 12, 150, 150, 15); roundedRect(ctx, 19, 19, 150, 150, 9); roundedRect(ctx, 53, 53, 49, 33, 10); roundedRect(ctx, 53, 119, 49, 16, 6); roundedRect(ctx, 135, 53, 49, 33, 10); roundedRect(ctx, 135, 119, 25, 49, 10); ctx.beginPath(); ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false); ctx.lineTo(31, 37); ctx.fill(); for (var i = 0; i  8; i++)  ctx.fillRect(51 + i * 16, 35, 4, 4); > for (i = 0; i  6; i++)  ctx.fillRect(115, 51 + i * 16, 4, 4); > for (i = 0; i  8; i++)  ctx.fillRect(51 + i * 16, 99, 4, 4); > ctx.beginPath(); ctx.moveTo(83, 116); ctx.lineTo(83, 102); ctx.bezierCurveTo(83, 94, 89, 88, 97, 88); ctx.bezierCurveTo(105, 88, 111, 94, 111, 102); ctx.lineTo(111, 116); ctx.lineTo(106.333, 111.333); ctx.lineTo(101.666, 116); ctx.lineTo(97, 111.333); ctx.lineTo(92.333, 116); ctx.lineTo(87.666, 111.333); ctx.lineTo(83, 116); ctx.fill(); ctx.fillStyle = "white"; ctx.beginPath(); ctx.moveTo(91, 96); ctx.bezierCurveTo(88, 96, 87, 99, 87, 101); ctx.bezierCurveTo(87, 103, 88, 106, 91, 106); ctx.bezierCurveTo(94, 106, 95, 103, 95, 101); ctx.bezierCurveTo(95, 99, 94, 96, 91, 96); ctx.moveTo(103, 96); ctx.bezierCurveTo(100, 96, 99, 99, 99, 101); ctx.bezierCurveTo(99, 103, 100, 106, 103, 106); ctx.bezierCurveTo(106, 106, 107, 103, 107, 101); ctx.bezierCurveTo(107, 99, 106, 96, 103, 96); ctx.fill(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(101, 102, 2, 0, Math.PI * 2, true); ctx.fill(); ctx.beginPath(); ctx.arc(89, 102, 2, 0, Math.PI * 2, true); ctx.fill(); > > // A utility function to draw a rectangle with rounded corners. function roundedRect(ctx, x, y, width, height, radius)  ctx.beginPath(); ctx.moveTo(x, y + radius); ctx.arcTo(x, y + height, x + radius, y + height, radius); ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius); ctx.arcTo(x + width, y, x + width - radius, y, radius); ctx.arcTo(x, y, x, y + radius, radius); ctx.stroke(); > 

Конечное изображение выглядит так:

Мы не будем подробно останавливаться на том, так как это на самом деле удивительно просто. Наиболее важные вещи, которые следует отметить, это использование свойства fillStyle в контексте рисования и использование функции утилиты (в данном случае roundedRect() ). Использование функций утилиты для битов чертежа часто может быть очень полезным и сократить количество необходимого кода, а также его сложность.

Позже, в этом уроке, мы ещё раз рассмотрим fillStyle , но более подробно. Здесь же мы используем его для изменения цвета заливки путей вместо цвета по умолчанию от чёрного до белого, а затем обратно.

Path2D объекты

Как мы видели в последнем примере, есть серия путей и команд для рисования объектов на вашем холсте. Чтобы упростить код и повысить производительность, объект Path2D (en-US), доступный в последних версиях браузеров, позволяет вам кешировать или записывать эти команды рисования. Вы можете быстро запускать свои пути. Давайте посмотрим, как мы можем построить объект Path2D :

Конструктор Path2D() возвращает вновь созданный объект Path2D необязательно с другим путём в качестве аргумента (создаёт копию) или необязательно со строкой, состоящей из данных пути SVG path .

new Path2D(); // пустой path объект new Path2D(path); // копирование из другого path new Path2D(d); // path из SVG 

Все методы path , такие как moveTo , rect , arc , или quadraticCurveTo , и т.п, которые мы уже знаем, доступны для объектов Path2D

API Path2D также добавляет способ комбинирования путей с использованием метода addPath . Это может быть полезно, если вы хотите, например, создавать объекты из нескольких компонентов.

Добавляет путь к текущему пути с необязательной матрицей преобразования.

Path2D пример

В этом примере мы создаём прямоугольник и круг. Оба они сохраняются как объект Path2D , поэтому они доступны для последующего использования. С новым API Path2D несколько методов были обновлены, чтобы при необходимости принять объект Path2D для использования вместо текущего пути. Здесь stroke и fill используются с аргументом пути, например, для рисования обоих объектов на холст.

html> body onload="draw();"> canvas id="canvas" width="130" height="100">canvas> body> html> 
function draw()  var canvas = document.getElementById("canvas"); if (canvas.getContext)  var ctx = canvas.getContext("2d"); var rectangle = new Path2D(); rectangle.rect(10, 10, 50, 50); var circle = new Path2D(); circle.moveTo(125, 35); circle.arc(100, 35, 25, 0, 2 * Math.PI); ctx.stroke(rectangle); ctx.fill(circle); > > 

Использование SVG путей

Ещё одна мощная функция нового Canvas Path2D API использует данные пути SVG, SVG path data, для инициализации путей на вашем холсте. Это может позволить вам передавать данные пути и повторно использовать их как в SVG, так и в холсте.

Путь перемещается в точку ( M10 10 ), а затем горизонтально перемещается на 80 пунктов вправо ( h 80 ), затем на 80 пунктов вниз ( v 80 ), затем на 80 пунктов влево ( h -80 ), а затем обратно на start ( z ). Этот пример можно увидеть на странице Path2D constructor (en-US) .

var p = new Path2D("M10 10 h 80 v 80 h -80 Z"); 
  • « Предыдущая статья
  • Следующая статья »

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 3 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

Рисование в JavaScript (canvas)

В HTML5 есть тег canvas, который создаёт поле для рисования. На нём можно рисовать с помощью скриптов JavaScript. Разберём как это работает.

Подготовка поля для рисования

Сначала необходимо на странице прописать тег:

Теперь с помощью JavaScript надо обратиться к этому полю. Сначала получим ссылку на него через getElementById а затем создадим объект, в котором будет находиться так называемый «контекст», через методы которого будем рисовать:

   

Теперь обращаясь к методам в объекте ctx можно рисовать различные фигуры в пределах области canvas. Попробуем сделать это.

Рисование линий

Самая простая фигура для отрисовки — это линия. Попробуем выполнить следующий код:

ctx.moveTo(50, 100); ctx.lineTo(150, 100);

В результате получим такую линию:

   
  • Первая команда beginPath говорит о том, что надо приготовиться к рисованию.
  • Вторая команда moveTo(50, 50) говорит о том, куда JavaScript должен поставить свой карандаш, откуда начнётся рисование. В скобках задаётся горизонтальная и вертикальная координата в пикселях (от левого верхнего края canvas). В нашем случае это точка находится на расстоянии 100 пикселей от верхнего и левого края.
  • Третья команда lineTo(150, 50) говорит о том, куда JavaScript должен тянуть свой карандаш. В скобках задаётся горизонтальная и вертикальная координата в пикселях. В нашем случае это точка находится на расстоянии 100 пикселей от верхнего края и 150 от левого. То есть получится горизонтальная линия по центру canvas.
  • Последняя четвёртая команда stroke говорит, что надо закончить рисование.

Линия рисуется непрерывно, пока не выполнена команда stroke. Поэтому можно нарисовать фигуру, используя команду lineTo несколько раз подряд. Давайте сделаем это и нарисуем квадрат:

ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(150, 50); // линия вправо ctx.lineTo(150, 150); // линия вниз ctx.lineTo(50, 150); // линия влево ctx.closePath(); // смыкание начала и конца рисунка (левая стена) ctx.stroke(); 

Чтобы нарисовать квадрат, нужно нарисовать 4 линии. Но в примере кода мы заменили последний метод lineTo на closePath, которая рисует линию, автоматически вычисляя нужные координаты, чтобы сомкнуть её с началом рисунка. Таким образом чтобы нарисовать последнюю (левую) сторону квадрата мы использовали не lineTo(50, 50), а просто closePath().

Чтобы изменить цвет линии, используем метод strokeStyle, которому передадим нужный цвет в обычном CSS формате (название цвета, HEX или RGB форматы). Чтобы изменить толщину линии необходимо использовать метод lineWidth, которому необходимо задать толщину линии в пикселях. Оба этих значениия (цвет и толщина) должны быть заданы до вызова метода stroke (который стоит в последней строчке примера):

ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(150, 50); // линия вправо ctx.lineTo(150, 150); // линия вниз ctx.lineTo(50, 150); // линия влево ctx.closePath(); // смыкание начала и конца рисунка (левая стена) ctx.strokeStyle = '#1a2edb'; // тёмно-синий цвет ctx.lineWidth = 5; // толщина линии в 5px ctx.stroke(); 

Получится такой результат:

Заливка рисунка

Попробуем разукрасить полученный квадрат не чёрным цветом, а синим. Для этого надо использовать метод fill. Точно так же как и изменение цвета/толщины линий, этот метод должен быть вызван до вызова метода stroke (который стоит в последней строчке примера).

ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(150, 50); // линия вправо ctx.lineTo(150, 150); // линия вниз ctx.lineTo(50, 150); // линия влево ctx.closePath(); // смыкание начала и конца рисунка (левая стена) ctx.fill(); // закрашивание фигуры ctx.stroke(); 

Не обязательно, чтобы фигура была закончена и «закрыта». То есть можно не ставить closePath, а нарисовать три стороны и применить закрашивание fill, тогда всё равно закрасится именно нужная область:

Чтобы изменить цвет заливки, используем метод fillStyle, которому передадим нужный цвет в обычном CSS формате (название цвета, HEX или RGB):

ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(150, 50); // линия вправо ctx.lineTo(150, 150); // линия вниз ctx.lineTo(50, 150); // линия влево ctx.closePath(); // смыкание начала и конца рисунка (левая стена) ctx.fillStyle = '#1a2edb'; // тёмно-синий цвет ctx.fill(); ctx.stroke(); 

Получится такой синий квадрат:

Рисование окружностей

  • Горизонтальную координату центра окружности на canvas (в пикселях)
  • Вертикальную координату центра окружности на canvas (в пикселях)
  • Радиус окружности (в пикселях)
  • Начальный угол окружности (в радианах!)
  • Конечный угол окружности (в радианах!)
  • Рисовать по часовой стрелке или против (если против, то значение «false», а если по часовой то «true»). По умолчанию рисует против часовой
ctx.beginPath(); ctx.arc(100, 100, 50, 0, 2 * Math.PI); ctx.stroke(); 

Получится такой круг:

Изменять толщину линии можно с помощью известного метода lineWidth, а цвет с помощью strokeStyle. Давайте модифицируем предыдущий пример и попробуем нарисовать полуокружность с синим цветом линии и толщиной 5 пикселей:

ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI); ctx.strokeStyle = '#1a2edb'; // тёмно-синий цвет ctx.lineWidth = 5; // толщина линии в 5px ctx.stroke(); 

Получится такой синий полукруг:

Заливать круги можно с помощью известного метода fill, а задание цвета делается с помощью уже оговоренного метода fillStyle. Попробуем доработать предыдущий пример и нарисовать верхний полукруг, но залитый зелёным цветом:

ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI); ctx.strokeStyle = '#1a2edb'; // тёмно-синий цвет ctx.lineWidth = 5; // толщина линии в 5px ctx.stroke(); ctx.beginPath(); ctx.arc(100, 100, 30, Math.PI, 0); ctx.fillStyle = '#50c843'; // зелёный цвет ctx.fill(); ctx.stroke(); 

Получится два круга. Зелёный (с заливкой) маленький вверху и синий (без заливки) большой снизу:

Обратите внимание, что методы strokeStyle и lineWidth применились к объекту ctx, поэтому верхний полукруг тоже получил толщину линии в 5 пикселе и тёмно-синий цвет. Поэтому если хотите нарисовать несколько фигур на одном canvas, то сделайте несколько объектов: ctx1, ctx2, ctx3 и т.п. чтобы не переопределялись их свойства.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *