aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/api/canvas_api/tutorial/drawing_shapes
diff options
context:
space:
mode:
authorFlorian Merz <me@fiji-flo.de>2021-02-11 14:51:05 +0100
committerFlorian Merz <me@fiji-flo.de>2021-02-11 14:51:05 +0100
commitc058fa0fb22dc40ef0225b21a97578cddd0aaffa (patch)
treedf20f8b4c724b61cb9c34cdb450a7ac77d690bd0 /files/ru/web/api/canvas_api/tutorial/drawing_shapes
parent8260a606c143e6b55a467edf017a56bdcd6cba7e (diff)
downloadtranslated-content-c058fa0fb22dc40ef0225b21a97578cddd0aaffa.tar.gz
translated-content-c058fa0fb22dc40ef0225b21a97578cddd0aaffa.tar.bz2
translated-content-c058fa0fb22dc40ef0225b21a97578cddd0aaffa.zip
unslug ru: move
Diffstat (limited to 'files/ru/web/api/canvas_api/tutorial/drawing_shapes')
-rw-r--r--files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html582
1 files changed, 582 insertions, 0 deletions
diff --git a/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html b/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html
new file mode 100644
index 0000000000..f6ca6c23ef
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html
@@ -0,0 +1,582 @@
+---
+title: Рисование фигур с помощью canvas
+slug: Web/API/Canvas_API/Tutorial/Рисование_фигур
+translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}</div>
+
+<div class="summary">
+<p>Теперь, установив наше <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_usage">окружение canvas</a>, мы можем погрузиться в детали того, как рисовать в canvas. К концу этой статьи, Вы научитесь рисовать прямоугольники, треугольники, линии, дуги и кривые, при условии что Вы хорошо знакомы с основными геометрическими фигурами. Работа с путями весьма важна, когда рисуете объекты на canvas и мы увидим как это может быть сделано.</p>
+</div>
+
+<h2 id="Сетка">Сетка</h2>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/224/Canvas_default_grid.png" style="float: right; height: 220px; width: 220px;">Перед тем, как мы начнем рисовать, нам нужно поговорить о сетке canvas или <strong>координатной плоскости</strong>. Наш HTML каркас из предыдущей страницы включал в себя элемент canvas 150 пикселей в ширину и 150 пикселей в высоту. Справа можно увидеть этот canvas <span class="short_text" id="result_box" lang="ru"><span class="hps">с сеткой</span><span>, накладываемой по умолчанию</span></span>. <span id="result_box" lang="ru"><span class="hps">Обычно 1 единица</span> <span class="hps">на сетке соответствует</span> <span class="hps">1 пикселю на</span></span> canvas. <span id="result_box" lang="ru"><span>Начало координат этой сетки</span> <span class="hps">расположено</span> <em><span class="hps">в верхнем левом</span> <span class="hps">углу</span></em> <span class="hps">в</span> <span class="atn hps">координате <code><em>(</em></code></span><span><code><em>0,0 )</em></code>.</span></span> <span id="result_box" lang="ru"><span class="hps">Все</span> <span class="hps">элементы размещены</span> <span class="hps">относительно</span> <span class="hps">этого</span> <span class="hps">начала</span><span>. </span><span class="hps">Так</span>им образом, <span class="hps">положение верхнего</span> <span class="hps">левого угла</span> <span class="hps">синего квадрата составляет</span> <code><em><span class="hps">х</span></em></code> <span class="hps">пикселей слева</span><span class="hps"> и</span> <code><em><span class="hps">у</span></em></code> <span class="hps">пикселей</span> <span class="hps">сверху,</span> <span class="hps">на</span> <span class="hps">координате <code><em>(х</em></code></span><span><code><em>, у)</em></code>.</span></span> <span id="result_box" lang="ru"><span class="hps">Позже в</span> <span class="hps">этом уроке мы</span> <span class="hps">увидим, как</span> <span class="hps">можно</span> <span class="hps">перевести</span> <span class="hps">начало координат</span> <span class="hps">в другое место</span><span>,</span> <span class="hps">вращать сетку</span> <span class="hps">и даже</span> <span class="hps">масштабировать ее</span><span>, но сейчас</span> <span class="hps">мы будем придерживаться</span> <span class="hps">настроек сетки по умолчанию.</span></span></p>
+
+<h2 id="Рисование_прямоугольников">Рисование прямоугольников</h2>
+
+<p>В отличие от {{Glossary("SVG")}}, {{HTMLElement("canvas")}} поддерживает только одну примитивную фигуру: прямоугольник. Все другие фигуры должны быть созданы комбинацией одного или большего количества контуров (paths), набором точек, соединенных в линии. К счастью в ассортименте рисования контуров у нас есть  функции, которые делают возможным составление очень сложных фигур.</p>
+
+<p>Сначала рассмотрим прямоугольник. Ниже представлены три функции рисования прямоугольников в canvas:</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}</dt>
+ <dd>Рисование заполненного прямоугольника.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}</dt>
+ <dd>Рисование прямоугольного контура.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}</dt>
+ <dd>Очистка  прямоугольной области, делая содержимое совершенно прозрачным.</dd>
+</dl>
+
+<p>Каждая из приведенных функций принимает несколько параметров: </p>
+
+<ul>
+ <li><em>x</em>, <font face="Consolas, Liberation Mono, Courier, monospace"><em>y</em></font> устанавливают положение верхнего левого угла прямоугольника в canvas (относительно начала координат);</li>
+ <li><code><em>width</em></code>(ширина) и <code><em><em>height</em></em></code>(высота) определяют размеры прямоугольника.</li>
+</ul>
+
+<p>Ниже приведена функция draw(), использующая эти три функции.</p>
+
+<h3 id="Пример_создания_прямоугольных_фигур">Пример создания прямоугольных фигур</h3>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+   &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js notranslate">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);
+ }
+}</pre>
+
+<p>Этот пример изображен ниже.</p>
+
+<p>{{EmbedLiveSample("Пример_создания_прямоугольных_фигур", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}</p>
+
+<p>Функция fillRect() рисует большой чёрный квадрат со стороной 100 px. Функция clearRect() вырезает квадрат 60х60 из центра, а функция strokeRect() создает прямоугольный контур 50х50 пикселей внутри очищенного квадрата.</p>
+
+<p>На следующей странице мы рассмотрим две альтернативы методу clearRect(), и также увидим, как можно изменять цвет и стиль контура отображаемых фигур.</p>
+
+<p>В отличие от функций создания контуров, которые будут рассмотрены в следующем разделе, все три функции создания прямоугольника сразу же отображаются на canvas.</p>
+
+<h2 id="Рисование_контуров_path">Рисование контуров (path)</h2>
+
+<p>Остальные примитивные фигуры создаются <em>контурами</em>. Контур - это набор точек, которые, соединяясь в отрезки линий, могут образовывать различные фигуры, изогнутые или нет, разной ширины и разного цвета. Контур (или субконтур) может быть закрытым.</p>
+
+<p>Создание фигур используя контуры происходит в несколько важных шагов:</p>
+
+<ol>
+ <li>Сначала вы создаете контур.</li>
+ <li>Затем, используя <a href="/en-US/docs/Web/API/CanvasRenderingContext2D#Paths">команды рисования</a>, рисуете контур.</li>
+ <li>Потом закрываете контур.</li>
+ <li>Созданный контур вы можете обвести или залить для его отображения.</li>
+</ol>
+
+<p>Здесь приведены функции, которые можно использовать в описанных шагах:</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}</dt>
+ <dd>Создает новый контур. После создания используется в дальнейшем командами рисования при построении контуров.</dd>
+ <dt><a href="/en-US/docs/Web/API/CanvasRenderingContext2D#Paths">Path методы</a></dt>
+ <dd>Методы для установки различных контуров объекта.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}</dt>
+ <dd><span id="result_box" lang="ru"><span class="hps">Закрывает контур</span><span>, так что</span> <span class="hps">будущие</span> <span class="hps">команды рисования</span> <span class="hps">вновь</span> <span class="hps">направлены</span> <span class="hps">контекст</span><span>.</span></span></dd>
+ <dt>{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}</dt>
+ <dd>Рисует фигуру с внешней обводкой.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.fill", "fill()")}}</dt>
+ <dd>Рисует фигуру с заливкой внутренней области.</dd>
+</dl>
+
+<p>Первый шаг создания контура заключается в вызове функции <strong><code>beginPath()</code></strong>. Внутри содержатся контуры в виде набора суб-контуров (линии, дуги и др.), которые вместе образуют форму фигуры. Каждый вызов этого метода очищает набор, и мы можем начинать рисовать новые фигуры.</p>
+
+<div class="note"><strong>Note:</strong>  если текущий контур пуст (например, как после вызова <code>beginPath() </code>или на вновь созданном canvas), первой командой построения контура всегда является функция  <strong><code>moveTo()</code></strong>. Поэтому мы всегда можем установить начальную позицию рисования контура после перезагрузки.</div>
+
+<p>Вторым шагом является вызов методов, определяемых видом контура, который нужно нарисовать. Их мы рассмотрим позднее.</p>
+
+<p>Третий и необязательный шаг - это вызов <strong><code>closePath()</code></strong>. Этот метод пытается закрыть фигуру, рисуя прямую линию из текущей точки в начальную. Если фигура была уже закрыта или является просто точкой, то функция ничего не делает.</p>
+
+<div class="note"><strong>Note:</strong> Когда вы вызываете <strong><code>fill()</code></strong>, то каждая открытая фигура закрывается автоматически, так что вы можете не использовать <code>closePath()</code>. Это обстоятельство не имеет место в случае вызова <code>stroke()</code>.</div>
+
+<h3 id="Рисование_треугольника">Рисование треугольника</h3>
+
+<p>Например, код для рисования треугольника будет выглядеть как-то так:</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+   &lt;canvas id="canvas" width="100" height="100"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js notranslate">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();
+ }
+}
+</pre>
+
+<p>Результат выглядит так:</p>
+
+<p>{{EmbedLiveSample("Рисование_треугольника", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}</p>
+
+<h3 id="Передвижение_пера">Передвижение пера</h3>
+
+<p>Одна очень полезная функция, которая ничего не рисует, но связана по смыслу с вышеописанными функциями  - это <strong><code>moveTo()</code></strong>. Вы можете представить это как отрыв (подъем) пера от бумаги и его перемещение в другое место.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}</dt>
+ <dd>Перемещает перо в точку с координатами x и y.</dd>
+</dl>
+
+<p>При инициализации canvas или при вызове <code>beginPath()</code>, вы захотите использовать функцию <code>moveTo()</code> для перемещения в точку начала рисования. Можно использовать <code>moveTo()</code> и для рисования несвязанного(незакрытого) контура. Посмотрите на смайлик ниже.</p>
+
+<p>Вы можете проверить это сами, используя участок кода ниже. Просто вставьте в функцию <code>draw()</code>, рассмотренную ранее.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+ &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js;highlight:[8,10,12] notranslate">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();
+ }
+}
+</pre>
+
+<p>Результат этого ниже:</p>
+
+<p>{{EmbedLiveSample("Передвижение_пера", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}</p>
+
+<p>Если вы захотите увидеть соединные линии, то можете удалить вызов <code>moveTo()</code>.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Подробнее о функции <code>arc()</code>,посмотрите {{anch("Дуги")}} .</p>
+</div>
+
+<h3 id="Линии">Линии</h3>
+
+<p>Для рисования прямых линий используйте метод <code>lineTo()</code>.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}</dt>
+ <dd>Рисует линию с текущей позиции до позиции, определенной <code>x и y</code>.</dd>
+</dl>
+
+<p><span id="result_box" lang="ru"><span class="hps">Этот метод принимает</span> <span class="hps">два аргумента</span> </span><code><em>x</em><span lang="ru"><span class="hps"> и </span></span><em>y</em></code><span lang="ru"><span>, которые являются</span> <span class="hps">координатами конечной</span> <span class="hps">точки линии</span><span>.</span></span> <span id="result_box" lang="ru"><span>Начальная точка зависит</span> <span class="hps">от</span> <span class="hps">ранее</span> <span class="hps">нарисованных путей, причём</span> <span class="hps">конечная точка</span> <span class="hps">предыдущего пути является</span> начальной <span class="hps">точкой следующего</span> <span class="hps">и т. д.</span> <span class="hps">Начальная точка также</span> <span class="hps">может быть изменена</span> <span class="hps">с помощью метода</span></span> <code>moveTo()</code>.</p>
+
+<p>Пример ниже рисует два треугольника, один закрашенный и другой обведен контуром.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+   &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js;highlight[9,10,16,17] notranslate">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();
+ }
+}
+</pre>
+
+<p><span id="result_box" lang="ru"><span class="hps">Отрисовка начинается с вызова</span> </span><code>beginPath()</code><span lang="ru"><span>, чтобы начать</span> <span class="hps">рисовать путь новой фигуры</span><span>.</span></span> <span id="result_box" lang="ru"><span class="hps">Затем мы используем</span> <span class="hps">метод</span> </span><code>moveTo()</code><span lang="ru"><span>, чтобы переместить</span> <span class="hps">начальную точку</span> <span class="hps">в нужное положение</span><span>.</span> <span class="hps">Ниже</span> <span class="hps">рисуются две линии</span><span>, которые образуют две</span> <span class="hps">стороны треугольника</span><span>.</span></span></p>
+
+<p>{{EmbedLiveSample("Линии", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}</p>
+
+<p><span id="result_box" lang="ru"><span class="hps">Вы заметите</span> <span class="hps">разницу между</span> <span class="hps">закрашенным</span> <span class="hps">и обведенным контуром</span> <span class="hps">треугольниками.</span> <span class="hps">Это, </span><span class="hps">как упоминалось выше</span><span>,</span> <span class="hps">из-за</span> того, что <span class="hps">фигуры</span> <span class="hps">автоматически закрываются</span><span>, когда</span> <span class="hps">путь</span> <span class="hps">заполнен (т. е. закрашен)</span><span>, но</span> <span class="hps">не тогда, когда</span> <span class="hps">он очерчен (т. е. обведен контуром)</span><span>.</span></span> <span id="result_box" lang="ru"><span class="hps">Если бы мы</span> <span class="hps">не учли</span> </span><code>closePath()</code><span lang="ru"> <span class="hps">для</span> очерченного <span class="hps">треугольника</span><span>,</span> тогда <span class="hps">только две линии</span> <span class="hps">были бы</span> <span class="hps">нарисованы,</span> <span class="hps">а не</span> <span class="hps">весь треугольник</span><span>.</span></span></p>
+
+<h3 id="Дуги">Дуги</h3>
+
+<p>Для рисования дуг и окружностей, используем методы arc() и arcTo().</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}</dt>
+ <dd>Рисуем дугу с центром в точке <code><em>(x,y)</em></code> радиусом <code><em>radius</em></code>, начиная с угла <em><code>startAngle </code>и заканчивая в </em><em><code>endAngle </code>в направлении против часовой стрелки <code>anticlockwise</code></em><code> </code>(по умолчанию по ходу движения часовой стрелки).</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}</dt>
+ <dd>Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.</dd>
+</dl>
+
+<p>Рассмотрим детальнее метод <em>arc()</em>, который имеет пять параметров: <em><code>x</code></em> и <em><code>y</code></em> — это координаты центра окружности, в которой должна быть нарисована дуга. <em><code>radius</code></em> — не требует пояснений. Углы <code>startAngle</code> и <code>endAngle</code> определяют начальную и конечную точки дуги в радианах вдоль кривой окружности. Отсчет происходит от оси x. Параметр <code>anticlockwise</code> — логическое значение, которое, если <code>true</code>, то рисование дуги совершается против хода часовой стрелки; иначе рисование происходит по ходу часовой стрелки.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Углы в функции arc() измеряют в радианах, не в градусах. Для перевода градусов в радианы вы можете использовать JavaScript-выражение: <code>radians = (Math.PI/180)*degrees</code>.</p>
+</div>
+
+<p>Следующий пример немного сложнее, чем мы рассматривали ранее. Здесь нарисованы 12 различных дуг с разными углами и заливками.</p>
+
+<p>Два <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for"><code>for</code> цикла</a> размещают дуги по столбцам и строкам. Для каждой дуги, мы начинаем новый контур, вызывая <em><code>beginPath()</code></em>. В этом коде каждый параметр дуги для большей ясности задан в виде переменной, но вам не обязательно делать так в реальных проектах.</p>
+
+<p>Координаты <code>x</code> и <code>y</code>  должны быть достаточно ясны. <code>radius</code> and <code>startAngle</code> — фиксированы. <code>endAngle</code> начинается со 180 градусов (полуокружность) в первой колонке и, увеличиваясь с шагом 90 градусов, достигает кульминации полноценной окружностью в последнем столбце.</p>
+
+<p>Установка параметра <code>clockwise</code> определяет результат; в первой и третьей строках рисование дуг происходит по часовой стрелке, а во второй и четвертой - против часовой стрелки. Благодаря if-условию верхняя половина дуг образуется с контуром, (обводкой), а нижняя половина дуг - с заливкой.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Этот пример требует немного большего холста (canvas), чем другие на этой странице: 150 x 200 pixels.</p>
+</div>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+   &lt;canvas id="canvas" width="150" height="200"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js;highlight[16] notranslate">function draw() {
+ var canvas = document.getElementById('canvas');
+ if (canvas.getContext){
+ var ctx = canvas.getContext('2d');
+
+ for(var i=0;i&lt;4;i++){
+ for(var j=0;j&lt;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&gt;1){
+ ctx.fill();
+ } else {
+ ctx.stroke();
+ }
+ }
+ }
+ }
+}
+</pre>
+
+<p>{{EmbedLiveSample("Дуги", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}</p>
+
+<h3 id="Безье_и_квадратичные_кривые">Безье и квадратичные кривые</h3>
+
+<p>Следующим типом доступных контуров являются  <a class="external" href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve" rel="external" title="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">кривые Безье</a>, и к тому же доступны в кубическом и квадратичном вариантах. Обычно они используются при рисовании сложных составных фигур.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}</dt>
+ <dd>Рисуется квадратичная кривая Безье с текущей позиции пера в конечную точку с координатами <code>x</code> и <code>y</code>, используя контрольную точку с координатами <code>cp1x</code> и <code>cp1y</code>.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}</dt>
+ <dd>Рисуется кубическая кривая Безье с текущей позиции пера в конечную точку с координатами <code>x</code> и <code>y</code>, используя две контрольные точки с координатами (<code>cp1x</code>, <code>cp1y</code>) и (cp2x, cp2y).</dd>
+</dl>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/223/Canvas_curves.png" style="float: right; height: 190px; width: 190px;">Различие между ними можно увидеть на рисунке, изображенном справа. Квадратичная кривая Безье имеет стартовую и конечную точки (синие точки) и всего одну контрольную точку (красная точка), в то время как кубическая кривая Безье использует две контрольные точки.</p>
+
+<p>Параметры <code>x</code> и <code>y</code> в этих двух методах являются координатами конечной точки. <code>cp1x</code> и <code>cp1y</code> — координаты первой контрольной точки, а <code>cp2x</code> и <code>cp2y</code> — координаты второй контрольной точки.</p>
+
+<p>Использование квадратичных или кубических кривых Безье может быть  спорным выходом, так как в отличие от приложений векторной графики типа Adobe Illustrator, мы не имеем полной видимой обратной связи с тем, что мы делаем. Этот факт делает довольно сложным процесс рисования сложных фигур. В следующем примере мы нарисуем совсем простую составную фигуру, но, если у вас есть время и ещё больше терпения, можно создать более сложные составные фигуры.</p>
+
+<p>В этом примере нет ничего слишком тяжелого. В обоих случаях мы видим последовательность кривых, рисуя которые, в результате получим составную фигуру.</p>
+
+<h4 id="Квадратичные_кривые_Безье">Квадратичные кривые Безье</h4>
+
+<p>В этом примере многократно используются квадратичные кривые Безье для рисования речевой выноски.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+ &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js;highlight[9,10,11,12,13,14] notranslate">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();
+ }
+}
+</pre>
+
+<p>{{EmbedLiveSample("Квадратичные_кривые_Безье", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}</p>
+
+<h4 id="Кубические_кривые_Безье">Кубические кривые Безье</h4>
+
+<p>В этом примере нарисовано сердце с использованием кубических кривых Безье.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+ &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js;highlight[9,10,11,12,13,14] notranslate">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();
+ }
+}
+</pre>
+
+<p>{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}</p>
+
+<h3 id="Прямоугольники">Прямоугольники</h3>
+
+<p>Все эти методы мы видели в  {{anch("Рисование прямоугольников")}}, которые рисуют прямоугольники сразу в canvas, так же есть метод <code>rect()</code>, который не отображает, а только добавляет контур рисования (path) заданного прямоугольника к последнему открытому контуру.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}</dt>
+ <dd><br>
+ Добавляет в path прямоугольник, верхний левый угол которого указан с помощью (x, y) с вашими width и height</dd>
+ <dt></dt>
+</dl>
+
+<p>Когда этот метод вызван, автоматически вызывается метод moveTo() с параметрами (x, y). Другими словами, позиция курсора устанавливается в начало добавленного прямоугольника.</p>
+
+<h3 id="Создание_комбинаций">Создание комбинаций</h3>
+
+<p>До сих пор, в каждом примере использовался только один тип функции контуров для каждой фигуры.<br>
+ Однако, нет никаких ограничений на количество или типы контуров, которые вы можете использовать для создания фигур. Давайте в этом примере объединим все вышеперечисленные  функции контуров, чтобы создать набор очень известных игровых персонажей.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+   &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js notranslate">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&lt;8;i++){
+ ctx.fillRect(51+i*16,35,4,4);
+ }
+
+ for(i=0;i&lt;6;i++){
+ ctx.fillRect(115,51+i*16,4,4);
+ }
+
+ for(i=0;i&lt;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.lineTo(x,y+height-radius);
+ ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
+ ctx.lineTo(x+width-radius,y+height);
+ ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
+ ctx.lineTo(x+width,y+radius);
+ ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
+ ctx.lineTo(x+radius,y);
+ ctx.quadraticCurveTo(x,y,x,y+radius);
+ ctx.stroke();
+}
+</pre>
+
+<p>Конечное изображение выглядит так:</p>
+
+<p>{{EmbedLiveSample("Создание_комбинаций", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}</p>
+
+<p>Мы не будем подробно останавливаться на том, так как это на самом деле удивительно просто. Наиболее важные вещи, которые следует отметить, это использование свойства <code>fillStyle</code> в контексте рисования и использование функции утилиты (в данном случае <code>roundedRect()</code>). Использование функций утилиты для битов чертежа часто может быть очень полезным и сократить количество необходимого кода, а также его сложность.</p>
+
+<p>Позже, в этом уроке, мы еще раз рассмотрим <code>fillStyle</code>, но более подробно. Здесь же мы используем его для изменения цвета заливки путей вместо цвета по умолчанию от черного до белого, а затем обратно.</p>
+
+<h2 id="Path2D_объекты">Path2D объекты</h2>
+
+<p>Как мы видели в последнем примере, есть серия путей и команд для рисования объектов на вашем холсте. Чтобы упростить код и повысить производительность, объект {{domxref("Path2D")}}, доступный в последних версиях браузеров, позволяет вам кэшировать или записывать эти команды рисования. Вы можете быстро запускать свои пути.<br>
+ Давайте посмотрим, как мы можем построить объект <code>Path2D</code> :</p>
+
+<dl>
+ <dt>{{domxref("Path2D.Path2D", "Path2D()")}}</dt>
+ <dd>Конструктор <code><strong>Path2D()</strong></code> возвращает вновь созданный объект <code>Path2D</code>  необязательно с другим путем в качестве аргумента (создает копию) или необязательно со строкой, состоящей из данных пути <a href="/en-US/docs/Web/SVG/Tutorial/Paths">SVG path</a> .</dd>
+</dl>
+
+<pre class="brush: js notranslate">new Path2D(); // пустой path объект
+new Path2D(path); // копирование из другого path
+new Path2D(d); // path из SVG</pre>
+
+<p>Все  <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#Paths">методы path</a> , такие как  <code>moveTo</code>,  <code>rect</code>,  <code>arc</code>, или <code>quadraticCurveTo</code>,  итп, которые мы уже знаем, доступны для объектов <code>Path2D</code></p>
+
+<p>API <code>Path2D</code> также добавляет способ комбинирования путей с использованием метода <code>addPath</code>. Это может быть полезно, если вы хотите, например, создавать объекты из нескольких компонентов.</p>
+
+<dl>
+ <dt>{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}</dt>
+ <dd>Добавляет путь к текущему пути с необязательной матрицей преобразования.</dd>
+</dl>
+
+<h3 id="Path2D_пример">Path2D пример</h3>
+
+<p>В этом примере мы создаем прямоугольник и круг. Оба они сохраняются как объект <code>Path2D</code>, поэтому они доступны для последующего использования. С новым API <code>Path2D</code> несколько методов были обновлены, чтобы при необходимости принять объект <code>Path2D</code> для использования вместо текущего пути. Здесь <code>stroke</code> и <code>fill</code> используются с аргументом пути, например, для рисования обоих объектов на холст.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+ &lt;canvas id="canvas" width="130" height="100"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js;highlight[6,9] notranslate">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);
+ }
+}
+</pre>
+
+<p>{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}</p>
+
+<h3 id="Использование_SVG_путей">Использование SVG путей</h3>
+
+<p>Еще одна мощная функция нового Canvas <code>Path2D</code> API использует данные пути SVG, <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths">SVG path data</a>, для инициализации путей на вашем холсте. Это может позволить вам передавать данные пути и повторно использовать их как в SVG, так и в холсте.</p>
+
+<p>Путь перемещается в точку (<code>M10 10</code>), а затем горизонтально перемещается на 80 пунктов вправо (<code>h 80</code>), затем на 80 пунктов вниз (<code>v 80</code>), затем на 80 пунктов влево (<code>h -80</code>), а затем обратно на start (<code>z</code>). <br>
+ Этот пример можно увидеть на странице  <a href="/en-US/docs/Web/API/Path2D.Path2D#Using_SVG_paths"><code>Path2D</code> constructor</a>.</p>
+
+<pre class="brush: js; notranslate">var p = new Path2D("M10 10 h 80 v 80 h -80 Z");</pre>
+
+<div>{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}</div>