aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/api/canvas_api
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
commit074785cea106179cb3305637055ab0a009ca74f2 (patch)
treee6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/api/canvas_api
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/ru/web/api/canvas_api')
-rw-r--r--files/ru/web/api/canvas_api/a_basic_ray-caster/index.html46
-rw-r--r--files/ru/web/api/canvas_api/index.html161
-rw-r--r--files/ru/web/api/canvas_api/tutorial/advanced_animations/index.html376
-rw-r--r--files/ru/web/api/canvas_api/tutorial/basic_usage/index.html150
-rw-r--r--files/ru/web/api/canvas_api/tutorial/finale/index.html51
-rw-r--r--files/ru/web/api/canvas_api/tutorial/index.html58
-rw-r--r--files/ru/web/api/canvas_api/tutorial/optimizing_canvas/index.html120
-rw-r--r--files/ru/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.html267
-rw-r--r--files/ru/web/api/canvas_api/tutorial/transformations/index.html275
-rw-r--r--files/ru/web/api/canvas_api/tutorial/использование_изображений/index.html333
-rw-r--r--files/ru/web/api/canvas_api/tutorial/композиции/index.html108
-rw-r--r--files/ru/web/api/canvas_api/tutorial/основы_анимации/index.html308
-rw-r--r--files/ru/web/api/canvas_api/tutorial/применение_стилей_и_цветов/index.html726
-rw-r--r--files/ru/web/api/canvas_api/tutorial/рисование_текста/index.html166
-rw-r--r--files/ru/web/api/canvas_api/tutorial/рисование_фигур/index.html582
15 files changed, 3727 insertions, 0 deletions
diff --git a/files/ru/web/api/canvas_api/a_basic_ray-caster/index.html b/files/ru/web/api/canvas_api/a_basic_ray-caster/index.html
new file mode 100644
index 0000000000..72b21d9f5b
--- /dev/null
+++ b/files/ru/web/api/canvas_api/a_basic_ray-caster/index.html
@@ -0,0 +1,46 @@
+---
+title: базовый ray-caster
+slug: Web/API/Canvas_API/A_basic_ray-caster
+translation_of: Web/API/Canvas_API/A_basic_ray-caster
+---
+<p>{{CanvasSidebar}}</p>
+
+<p>В этой статье представлен интересный реальный пример использования элемента {{HTMLElement("canvas")}} для выполнения программного рендеринга 3D-среды с помощью Ray-casting.</p>
+
+<p>{{EmbedGHLiveSample("canvas-raycaster/index.html", 900, 300)}}</p>
+
+<p><strong><a href="http://mdn.github.io/canvas-raycaster/">Открыть в новом окне</a></strong></p>
+
+<h2 id="Why.3F" name="Why.3F">Зачем?</h2>
+
+<p>Я попробовал небольшой эксперимент, понимая, к моему восторгу, что стильный элемент <code>&lt;canvas&gt;</code> о котором я <a href="https://www.whatwg.org/specs/web-apps/current-work/#dynamic">читал</a>, поддерживается не только в Fierfox, но так же поддерживается последней версией Safari.</p>
+
+<p>Хорошие <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">обзор</a> и <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial">руководство</a> по canvas я нашел в MDN, но никто еще не писал об анимации, поэтому я решил попробовать базовый порт raycaster, над которым я работал некоторое время назад, и посмотреть, какую производительность мы можем ожидать от управляемого JavaScript-ом пиксельного буфера.</p>
+
+<h2 id="How.3F" name="How.3F">Как?</h2>
+
+<p>Основная идея заключается в использовании {{domxref("window.setInterval","setInterval()")}} с некоторой произвольной задержкой, соответствующей требуемой частоте кадров. После каждого интервала функция обновления будет перерисовывать холст, и отображать текущий вид. Я знаю, что мог бы начать с более простого примера, но я уверен, что руководство canvas <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations">доберется до этого</a>, и я хотел посмотреть, смогу ли я это сделать.</p>
+
+<p>Таким образом каждое обновление raycaster смотрит нажимали ли вы какие либо клавиши в последнее время, сохраняет расчеты и останавливается если вы бездествуете. Получив расчеты, холст очищается, земля и небо рисуются, положение камеры и/или ориентация обновляются, а лучи отбрасываются. Когда лучи попадают на стены, они отображают вертикальный кусок холста в цвете стены, на которую они попали, смешанный с более темной версией цвета в зависимости от расстояния до стены. Высота этого кусочка также моделируется расстоянием от камеры до стены и рисуется по центру линии горизонта.</p>
+
+<p>Код, который я получил, - это смесь глав raycaster из старой книги Андре Ламотетрикса о гуру программирования игр (ISBN: 0672305070) и  <a class="external" href="http://www.shinelife.co.uk/java-maze/">java raycaster</a>, которую я нашел в интернете, отфильтровал, переименовал, и внес все изменения, которые нужно было внести, чтобы все работало хорошо.</p>
+
+<h2 id="Results" name="Results">Результаты</h2>
+
+<p>Холст в Safari 2.0.1 выполнен на удивление хорошо. С коэффициентом блочности, увеличенным до отображения кусочка шириной 8 пикселей, я могу запустить окно 320 x 240 при 24 fps на моем Apple mini. Firefox 1.5 Beta 1 еще быстрее; я могу запускать 320 x 240 при 24 fps с 4 пиксельным кусочком. Не совсем новый член семейства програмного обеспечения ID, но довольно приличный, учитывая, что это полностью интерпретируемая среда, и мне не нужно было беспокоиться о выделении памяти или видеорежимах или кодировании внутренних процедур в ассемблере или чем-то еще. Код получился очень эффективным, он использует поиск по массиву предварительно вычисленных значений, но я не гуру оптимизации, поэтому все, вероятно, можно было бы написать быстрее.</p>
+
+<p>Кроме того, он оставляет желать лучшего с точки зрения попыток быть игровым движком—нет текстур стен, нет спрайтов, нет дверей, даже нет телепортов, чтобы добраться до другого уровня. Но я уверен, что все эти вещи могут быть добавлены, через некоторое время. Canvas API поддерживает пиксельное копирование изображений, поэтому текстуры могут быть добавлены. Я оставлю это для другой статьи, возможно, от другого человека. =)</p>
+
+<h2 id="The_RayCaster" name="The_RayCaster">ray-caster</h2>
+
+<p>Хорошие люди здесь вручную скопировали мои файлы, чтобы вы могли <a href="https://mdn.github.io/canvas-raycaster/">взглянуть</a>, и для вашего удобства я разместил содержимое отдельных файлов в виде списков кодов (см. ниже).</p>
+
+<p>Так что запустите Safari 1.3+ или Firefox 1.5+ или какой-нибудь другой браузер, который поддерживает элемент &lt;canvas&gt; и наслаждайтесь!</p>
+
+<p><small><a href="https://github.com/mdn/canvas-raycaster/blob/master/input.js">input.js</a> | <a href="https://github.com/mdn/canvas-raycaster/blob/master/Level.js">Level.js</a> | <a href="https://github.com/mdn/canvas-raycaster/blob/master/Player.js">Player.js</a> | <a href="https://github.com/mdn/canvas-raycaster/blob/master/index.html">RayCaster.html</a> | <a href="https://github.com/mdn/canvas-raycaster/blob/master/RayCaster.js">RayCaster.js</a> | <a href="https://github.com/mdn/canvas-raycaster/blob/master/trace.css">trace.css</a> | <a href="https://github.com/mdn/canvas-raycaster/blob/master/trace.js">trace.js</a> </small></p>
+
+<h2 id="See_also" name="See_also">Смотрите также</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/API/Canvas_API/Tutorial">Canvas руководство</a></li>
+</ul>
diff --git a/files/ru/web/api/canvas_api/index.html b/files/ru/web/api/canvas_api/index.html
new file mode 100644
index 0000000000..e3986f8d75
--- /dev/null
+++ b/files/ru/web/api/canvas_api/index.html
@@ -0,0 +1,161 @@
+---
+title: Canvas
+slug: Web/API/Canvas_API
+tags:
+ - API
+ - Canvas
+ - Обзор
+ - Справка
+translation_of: Web/API/Canvas_API
+---
+<div>{{CanvasSidebar}}</div>
+
+<p class="summary">Элемент {{HTMLElement("canvas")}}, добавленный в <a href="https://developer.mozilla.org/en-US/docs/HTML/HTML5">HTML5</a>, предназначен для создания графики с помощью <a href="/en-US/docs/JavaScript" title="JavaScript">JavaScript</a>. Например, его используют для рисования графиков, создания фотокомпозиций, анимаций и даже обработки и рендеринга видео в реальном времени.</p>
+
+<p><em>«</em>Canvas<em>»</em>  в переводе с английского означает <em>«</em>холст<em>»</em>.</p>
+
+<p>Приложения от Mozilla поддерживают <code>&lt;canvas&gt;</code> начиная с Gecko 1.8 (т.е. <a href="/en-US/docs/Firefox_1.5_for_developers" title="Firefox_1.5_for_developers">с Firefox 1.5</a>). Этот элемент первоначально был представлен Apple для OS X <a class="external" href="http://www.apple.com/macosx/features/dashboard/">Dashboard</a> и Safari. Internet Explorer поддерживает<code> &lt;canvas&gt;</code> начиная с 9 версии; для более ранних версий IE поддержку для &lt;canvas&gt; можно добавить с помощью скрипта из проекта Google's <a class="external" href="http://excanvas.sourceforge.net/">Explorer Canvas</a>. Google Chrome и Opera 9 также поддерживают <code>&lt;canvas&gt;</code>.</p>
+
+<p>Элемент <code>&lt;canvas&gt;</code> также используется технологией <a href="/en-US/docs/WebGL" title="WebGL">WebGL</a> для отрисовки аппаратно-ускоренной 3D-графики на вебстраницах.</p>
+
+<h2 id="Пример">Пример</h2>
+
+<p>Это простой пример использования {{domxref("CanvasRenderingContext2D.fillRect()")}} метода.</p>
+
+<h3 id="HTML">HTML</h3>
+
+<pre class="brush: html">&lt;canvas id="canvas"&gt;&lt;/canvas&gt;
+</pre>
+
+<h3 id="JavaScript">JavaScript</h3>
+
+<pre class="brush: js">var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+ctx.fillStyle = "green";
+ctx.fillRect(10, 10, 100, 100);
+</pre>
+
+<p>Отредактируйте код ниже, чтобы увидеть результат на холсте.</p>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html">&lt;canvas id="canvas" width="400" height="200" class="playable-canvas"&gt;&lt;/canvas&gt;
+&lt;div class="playable-buttons"&gt;
+  &lt;input id="edit" type="button" value="Edit" /&gt;
+  &lt;input id="reset" type="button" value="Reset" /&gt;
+&lt;/div&gt;
+&lt;textarea id="code" class="playable-code"&gt;
+ctx.fillStyle = "green";
+ctx.fillRect(10, 10, 100, 100);&lt;/textarea&gt;</pre>
+
+<pre class="brush: js">var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+var textarea = document.getElementById("code");
+var reset = document.getElementById("reset");
+var edit = document.getElementById("edit");
+var code = textarea.value;
+
+function drawCanvas() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ eval(textarea.value);
+}
+
+reset.addEventListener("click", function() {
+ textarea.value = code;
+ drawCanvas();
+});
+
+edit.addEventListener("click", function() {
+ textarea.focus();
+})
+
+textarea.addEventListener("input", drawCanvas);
+window.addEventListener("load", drawCanvas);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', 700, 360) }}</p>
+
+<h2 id="Справочные_материалы">Справочные материалы</h2>
+
+<div class="index">
+<ul>
+ <li>{{domxref("HTMLCanvasElement")}}</li>
+ <li>{{domxref("CanvasRenderingContext2D")}}</li>
+ <li>{{domxref("CanvasGradient")}}</li>
+ <li>{{domxref("CanvasPattern")}}</li>
+ <li>{{domxref("ImageBitmap")}}</li>
+ <li>{{domxref("ImageData")}}</li>
+ <li>{{domxref("TextMetrics")}}</li>
+ <li>{{domxref("Path2D")}} {{experimental_inline}}</li>
+</ul>
+</div>
+
+<p class="brush: js"><span id="result_box" lang="ru"><span>Интерфейсы, связанные с <code>WebGLRenderingContext</code>, ссылаются на </span></span><a href="/en-US/docs/Web/WebGL" title="/en-US/docs/Web/WebGL">WebGL</a>.</p>
+
+<h2 class="Documentation" id="Documentation" name="Documentation">Руководства</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Web/API/Canvas_API/Tutorial">Canvas tutorial</a></dt>
+ <dd>Подробный <span id="result_box" lang="ru"><span>учебник, охватывающий как основное использование <code>&lt;canvas&gt;</code>, так и его расширенные функции.</span></span></dd>
+ <dt><a href="/en-US/Add-ons/Code_snippets/Canvas">Фрагменты кода: Canvas</a></dt>
+ <dd><span id="result_box" lang="ru"><span>Некоторые фрагменты кода, ориентированные на разработчиков, с использованием <code>&lt;canvas&gt;</code>.</span></span></dd>
+ <dt><a href="/en-US/docs/Web/API/Canvas_API/A_basic_ray-caster">Demo: A basic ray-caster</a></dt>
+ <dd>Демо анимации трассировки-лучей используя canvas.</dd>
+ <dt><a href="/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas">Drawing DOM objects into a canvas</a></dt>
+ <dd>Как рисовать DOM контент, таких как HTML элементы, в canvas.</dd>
+ <dt><a href="/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas">Manipulating video using canvas</a></dt>
+ <dd>Объединяет {{HTMLElement("video")}} и {{HTMLElement("canvas")}} для манипулирования видео данных в реальном времени.</dd>
+</dl>
+
+<h2 class="Resources" id="Resources" name="Resources">Ресурсы</h2>
+
+<h3 id="Основное">Основное</h3>
+
+<ul>
+ <li><a href="http://joshondesign.com/p/books/canvasdeepdive/title.html">HTML5 Canvas Deep Dive</a></li>
+ <li><a href="http://bucephalus.org/text/CanvasHandbook/CanvasHandbook.html">Справочник по Canvas</a></li>
+</ul>
+
+<h3 class="Libraries" id="Libraries" name="Libraries">Библиотеки</h3>
+
+<ul>
+ <li><a href="http://fabricjs.com">Fabric.js</a> это canvas библиотека с открытым исходным кодом с возможностями SVG парсинга.</li>
+ <li><a href="https://github.com/ericdrowell/KineticJS">Kinetic.js</a> это canvas библиотека с открытым исходным кодом ориентированная на интерактивность для настольных и мобильных приложений.</li>
+ <li><a href="http://paperjs.org/">Paper.js</a> это программируемый фреймворк векторной графики с открытым исходным кодом который запускается на HTML5 Canvas.</li>
+ <li><a href="http://libcanvas.github.com/">libCanvas</a> это мощный и лёгкий canvas фреймворк.</li>
+ <li><a href="http://processingjs.org">Processing.js</a> является портом языка обработки визуализации.</li>
+ <li><a href="https://playcanvas.com/">PlayCanvas</a> игровой движок с открытым исходным кодом.</li>
+ <li><a href="http://www.pixijs.com/">Pixi.js</a> игровой движок с открытым исходным кодом.</li>
+ <li><a href="http://www.liquidx.net/plotkit/">PlotKit</a> библиотека создание графиков и графики.</li>
+ <li><a class="link-https" href="https://github.com/jeremyckahn/rekapi">Rekapi</a> API анимации для canvas.</li>
+ <li><a href="http://senchalabs.github.com/philogl/">PhiloGL</a> WebGL фреймворк для визуализации данных, для креативного написания кода и разработки игр.</li>
+ <li><a href="http://thejit.org/">JavaScript InfoVis Toolkit</a> создаёт интерактивные 2D Canvas визуализации данных для интернета.</li>
+</ul>
+
+<h2 id="Specifications" name="Specifications">Спецификации</h2>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Спецификация</th>
+ <th scope="col">Статус</th>
+ <th scope="col">Комментарий</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{SpecName('HTML WHATWG', "the-canvas-element.html", "Canvas")}}</td>
+ <td>{{Spec2('HTML WHATWG')}}</td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="См.также">См.также</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/WebGL">WebGL</a></li>
+</ul>
diff --git a/files/ru/web/api/canvas_api/tutorial/advanced_animations/index.html b/files/ru/web/api/canvas_api/tutorial/advanced_animations/index.html
new file mode 100644
index 0000000000..f9dc3f7a3e
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/advanced_animations/index.html
@@ -0,0 +1,376 @@
+---
+title: Расширенные анимации
+slug: Web/API/Canvas_API/Tutorial/Advanced_animations
+translation_of: Web/API/Canvas_API/Tutorial/Advanced_animations
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}</div>
+
+<div class="summary">
+<p><span class="notranslate">В предыдущей главе мы сделали несколько <a href="/ru/docs/Web/API/Canvas_API/Tutorial/Basic_animations">базовых анимаций</a> и узнали, как можно двигать вещи.</span> <span class="notranslate"> В этой части мы более подробно рассмотрим само движение и собираемся добавить некоторую физику, чтобы сделать наши анимации более продвинутыми.</span></p>
+</div>
+
+<h2 id="Рисование_мяча"><span class="notranslate">Рисование мяча</span></h2>
+
+<p><span class="notranslate">Мы собираемся использовать шар для наших анимационных исследований, поэтому давайте сначала нарисуем этот шар на </span><code> canvas</code><span class="notranslate">.</span> Нам нужен следующий код.</p>
+
+<pre class="brush: html">&lt;canvas id="canvas" width="600" height="300"&gt;&lt;/canvas&gt;
+</pre>
+
+<p><span class="notranslate">Как обычно, нам нужен контекст рисования.</span> Чтобы нарисовать шар, мы создадим объект <code>ball</code>, который содержит свойства и метод <code>draw()</code> , чтобы нарисовать его на <code>canvas</code>.</p>
+
+<pre class="brush: js">var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+var ball = {
+ x: 100,
+ y: 100,
+ radius: 25,
+ color: 'blue',
+ draw: function() {
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+ ctx.closePath();
+ ctx.fillStyle = this.color;
+ ctx.fill();
+ }
+};
+
+ball.draw();</pre>
+
+<p><span class="notranslate">Здесь нет ничего особенного, шар на самом деле представляет собой простой круг и рисуется с помощью метода</span> {{domxref("CanvasRenderingContext2D.arc()", "arc()")}}.</p>
+
+<h2 id="Добавление_скорости"><span class="notranslate">Добавление скорости</span></h2>
+
+<p>Теперь, когда у нас есть шар, мы готовы добавить базовую анимацию, как мы узнали из последней <a href="/ru/docs/Web/API/Canvas_API/Tutorial/Basic_animations">главы</a> этого урока. <span class="notranslate">Опять же,</span> {{domxref("window.requestAnimationFrame()")}} <span class="notranslate">помогает нам контролировать анимацию.</span> <span class="notranslate">Мяч перемещается, добавляя вектор скорости в положение.</span> <span class="notranslate">Для каждого кадра мы также</span> {{domxref("CanvasRenderingContext2D.clearRect", "очищаем", "", 1)}} <span class="notranslate"> холст, чтобы удалить старые круги из предыдущих кадров.</span></p>
+
+<pre class="brush: js; highlight:[8,9,24,25]">var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+var raf;
+
+var ball = {
+ x: 100,
+ y: 100,
+ vx: 5,
+ vy: 2,
+ radius: 25,
+ color: 'blue',
+ draw: function() {
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+ ctx.closePath();
+ ctx.fillStyle = this.color;
+ ctx.fill();
+ }
+};
+
+function draw() {
+ ctx.clearRect(0,0, canvas.width, canvas.height);
+ ball.draw();
+ ball.x += ball.vx;
+ ball.y += ball.vy;
+ raf = window.requestAnimationFrame(draw);
+}
+
+canvas.addEventListener('mouseover', function(e) {
+ raf = window.requestAnimationFrame(draw);
+});
+
+canvas.addEventListener('mouseout', function(e) {
+ window.cancelAnimationFrame(raf);
+});
+
+ball.draw();
+</pre>
+
+<h2 id="Границы"><span class="notranslate" style="background-color: #e6ecf9;">Границы</span></h2>
+
+<p><span class="notranslate">Без какого-либо граничного коллизионного тестирования наш мяч быстро выбегает из холста.</span> <span class="notranslate"> Нам нужно проверить, не находятся ли <code>x</code> и <code>y</code> положения шара вне размеров холста и не инвертируют направление векторов скорости.</span> <span class="notranslate"> Для этого мы добавим следующие проверки в метод <code>draw</code> :</span></p>
+
+<pre class="brush: js">if (ball.y + ball.vy &gt; canvas.height || ball.y + ball.vy &lt; 0) {
+  ball.vy = -ball.vy;
+}
+if (ball.x + ball.vx &gt; canvas.width || ball.x + ball.vx &lt; 0) {
+  ball.vx = -ball.vx;
+}</pre>
+
+<h3 id="Первое_демо"><span class="notranslate">Первое демо</span></h3>
+
+<p><span class="notranslate">Посмотрим, как он выглядит в действии.</span> <span class="notranslate"> Переместите мышь на холст, чтобы запустить анимацию.</span></p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;canvas id="canvas" style="border: 1px solid" width="600" height="300"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+var raf;
+
+var ball = {
+ x: 100,
+ y: 100,
+ vx: 5,
+ vy: 2,
+ radius: 25,
+ color: 'blue',
+ draw: function() {
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+ ctx.closePath();
+ ctx.fillStyle = this.color;
+ ctx.fill();
+ }
+};
+
+function draw() {
+ ctx.clearRect(0,0, canvas.width, canvas.height);
+ ball.draw();
+ ball.x += ball.vx;
+ ball.y += ball.vy;
+
+ if (ball.y + ball.vy &gt; canvas.height ||
+ ball.y + ball.vy &lt; 0) {
+ ball.vy = -ball.vy;
+ }
+ if (ball.x + ball.vx &gt; canvas.width ||
+ ball.x + ball.vx &lt; 0) {
+ ball.vx = -ball.vx;
+ }
+
+ raf = window.requestAnimationFrame(draw);
+}
+
+canvas.addEventListener('mouseover', function(e) {
+ raf = window.requestAnimationFrame(draw);
+});
+
+canvas.addEventListener('mouseout', function(e) {
+ window.cancelAnimationFrame(raf);
+});
+
+ball.draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("First_demo", "610", "310")}}</p>
+
+<h2 id="Ускорение">Ускорение</h2>
+
+<p>Чтобы сделать движение более реальным, вы можете играть со скоростью, нпример так:</p>
+
+<pre class="brush: js">ball.vy *= .99;
+ball.vy += .25;</pre>
+
+<p><span class="notranslate">Это замедляет вертикальную скорость каждого кадра, так что мяч будет просто отскакивать от пола в конце.</span></p>
+
+<div class="hidden">
+<h6 id="Second_demo">Second demo</h6>
+
+<pre class="brush: html">&lt;canvas id="canvas" style="border: 1px solid" width="600" height="300"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+var raf;
+
+var ball = {
+ x: 100,
+ y: 100,
+ vx: 5,
+ vy: 2,
+ radius: 25,
+ color: 'blue',
+ draw: function() {
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+ ctx.closePath();
+ ctx.fillStyle = this.color;
+ ctx.fill();
+ }
+};
+
+function draw() {
+ ctx.clearRect(0,0, canvas.width, canvas.height);
+ ball.draw();
+ ball.x += ball.vx;
+ ball.y += ball.vy;
+ ball.vy *= .99;
+ ball.vy += .25;
+
+ if (ball.y + ball.vy &gt; canvas.height ||
+ ball.y + ball.vy &lt; 0) {
+ ball.vy = -ball.vy;
+ }
+ if (ball.x + ball.vx &gt; canvas.width ||
+ ball.x + ball.vx &lt; 0) {
+ ball.vx = -ball.vx;
+ }
+
+ raf = window.requestAnimationFrame(draw);
+}
+
+canvas.addEventListener('mouseover', function(e) {
+ raf = window.requestAnimationFrame(draw);
+});
+
+canvas.addEventListener('mouseout', function(e) {
+ window.cancelAnimationFrame(raf);
+});
+
+ball.draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Second_demo", "610", "310")}}</p>
+
+<h2 id="Скользящий_эффект">Скользящий эффект</h2>
+
+<p>До сих пор мы использовали метод {{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}}, когда очищали предыдущий кадр. Если заменить этот метод на {{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}} с полу-прозрачным стилем, можно легко создать эффект скольжения.</p>
+
+<pre class="brush: js">ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
+ctx.fillRect(0, 0, canvas.width, canvas.height);</pre>
+
+<div class="hidden">
+<h6 id="Third_demo">Third demo</h6>
+
+<pre class="brush: html">&lt;canvas id="canvas" style="border: 1px solid" width="600" height="300"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+var raf;
+
+var ball = {
+ x: 100,
+ y: 100,
+ vx: 5,
+ vy: 2,
+ radius: 25,
+ color: 'blue',
+ draw: function() {
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+ ctx.closePath();
+ ctx.fillStyle = this.color;
+ ctx.fill();
+ }
+};
+
+function draw() {
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ ball.draw();
+ ball.x += ball.vx;
+ ball.y += ball.vy;
+ ball.vy *= .99;
+ ball.vy += .25;
+
+ if (ball.y + ball.vy &gt; canvas.height ||
+ ball.y + ball.vy &lt; 0) {
+ ball.vy = -ball.vy;
+ }
+ if (ball.x + ball.vx &gt; canvas.width ||
+ ball.x + ball.vx &lt; 0) {
+ ball.vx = -ball.vx;
+ }
+
+ raf = window.requestAnimationFrame(draw);
+}
+
+canvas.addEventListener('mouseover', function(e) {
+ raf = window.requestAnimationFrame(draw);
+});
+
+canvas.addEventListener('mouseout', function(e) {
+ window.cancelAnimationFrame(raf);
+});
+
+ball.draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Third_demo", "610", "310")}}</p>
+
+<h2 id="Добавление_управления_мышью"><span class="notranslate" style="background-color: #e6ecf9;">Добавление управления мышью</span></h2>
+
+<p>Чтобы получить некоторый контроль над мячом, мы можем заставить его следовать за нашей мышью, например, с помощью события<span class="notranslate"> <code><a href="https://translate.googleusercontent.com/translate_c?depth=1&amp;hl=ru&amp;rurl=translate.google.com&amp;sl=en&amp;sp=nmt4&amp;tl=ru&amp;u=https://developer.mozilla.org/en-US/docs/Web/Reference/Events/mousemove&amp;usg=ALkJrhhcJqJN-yKD36pH8RkWQhb3uewyBA">mousemove</a></code> .</span> <span class="notranslate"> Событие <code><a href="https://translate.googleusercontent.com/translate_c?depth=1&amp;hl=ru&amp;rurl=translate.google.com&amp;sl=en&amp;sp=nmt4&amp;tl=ru&amp;u=https://developer.mozilla.org/en-US/docs/Web/Events/click&amp;usg=ALkJrhi9Rqodjh09zJQ7RSZkVNVqMZ5zhw">click</a></code></span> отпускает мяч и позволяет ему снова прыгать</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;canvas id="canvas" style="border: 1px solid" width="600" height="300"&gt;&lt;/canvas&gt;</pre>
+</div>
+
+<pre class="brush: js">var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+var raf;
+var running = false;
+
+var ball = {
+ x: 100,
+ y: 100,
+ vx: 5,
+ vy: 1,
+ radius: 25,
+ color: 'blue',
+ draw: function() {
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+ ctx.closePath();
+ ctx.fillStyle = this.color;
+ ctx.fill();
+ }
+};
+
+function clear() {
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
+ ctx.fillRect(0,0,canvas.width,canvas.height);
+}
+
+function draw() {
+ clear();
+ ball.draw();
+ ball.x += ball.vx;
+ ball.y += ball.vy;
+
+ if (ball.y + ball.vy &gt; canvas.height || ball.y + ball.vy &lt; 0) {
+ ball.vy = -ball.vy;
+ }
+ if (ball.x + ball.vx &gt; canvas.width || ball.x + ball.vx &lt; 0) {
+ ball.vx = -ball.vx;
+ }
+
+ raf = window.requestAnimationFrame(draw);
+}
+
+canvas.addEventListener('mousemove', function(e) {
+ if (!running) {
+ clear();
+ ball.x = e.clientX;
+ ball.y = e.clientY;
+ ball.draw();
+ }
+});
+
+canvas.addEventListener('click', function(e) {
+ if (!running) {
+ raf = window.requestAnimationFrame(draw);
+ running = true;
+ }
+});
+
+canvas.addEventListener('mouseout', function(e) {
+ window.cancelAnimationFrame(raf);
+ running = false;
+});
+
+ball.draw();
+</pre>
+
+<p><span class="notranslate">Переместите шар с помощью мыши и отпустите его одним щелчком.</span></p>
+
+<p>{{EmbedLiveSample("Adding_mouse_control", "610", "310")}}</p>
+
+<h2 id="Breakout(арканоид)">Breakout(арканоид)</h2>
+
+<p>В этой короткой главе описаны некоторые приемы создания продвинутой анимации.  Как насчет того, что бы добавить доску, кирпичи и превратить это демо в игру Breakout(в Росси более известный клон этой игры - арканоид)? Посетите <a href="/en-US/docs/Games">Game development</a> чтобы узнать больше об играх.</p>
+
+<h2 id="Смотрите_так_же">Смотрите так же</h2>
+
+<ul>
+ <li>{{domxref("window.requestAnimationFrame()")}}</li>
+ <li><a href="/en-US/docs/Games/Techniques/Efficient_animation_for_web_games">Efficient animation for web games</a></li>
+</ul>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/basic_usage/index.html b/files/ru/web/api/canvas_api/tutorial/basic_usage/index.html
new file mode 100644
index 0000000000..3c32d75985
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/basic_usage/index.html
@@ -0,0 +1,150 @@
+---
+title: Базовое использование Canvas
+slug: Web/API/Canvas_API/Tutorial/Basic_usage
+tags:
+ - Canvas
+translation_of: Web/API/Canvas_API/Tutorial/Basic_usage
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}</div>
+
+<p class="summary">Давайте начнем этот урок с изучения элемента {{HTMLElement("canvas")}} как такового. В конце этой страницы Вы узнаете как устанавливать canvas 2D context и нарисуете первый пример в вашем браузере.</p>
+
+<h2 id="Элемент_&lt;canvas>">Элемент <code>&lt;canvas&gt;</code></h2>
+
+<pre class="brush: html notranslate">&lt;canvas id="tutorial" width="150" height="150"&gt;&lt;/canvas&gt;
+</pre>
+
+<p>Он выглядит как элемент <code>&lt;img&gt;</code>, но его отличие в том, что он не имеет атрибутов <code>src</code> и <code>alt</code>. Элемент <code>&lt;canvas&gt;</code> имеет только два атрибута - <strong>ширину</strong> и <strong>высоту</strong>. Оба они не обязательны и могут быть выставлены с использованием свойств <a href="/en-US/docs/DOM" rel="internal" title="en/DOM">DOM</a>. Если атрибуты высоты и ширины не установлены, canvas будет по умолчанию шириной <strong>300 пикселей</strong> и в высоту <strong>150 пикселей</strong>. Вы так же можете выставить размеры произвольно в <a href="/en-US/docs/Web/CSS" rel="internal" title="en/CSS">CSS</a>, но во время рендеринга изображение будет масштабироваться в соответствии с его размером и ориентацией.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Если вид вашего изображения кажется вам искаженным, попробуйте указать атрибуты ширины и высоты в явном виде в атрибутах &lt;canvas&gt; , а не с помощью CSS.</p>
+</div>
+
+<p>Атрибут id не специфичен для элемента <code>&lt;canvas&gt;,</code> но он может быть применен по умолчанию в атрибутах HTML, так как он может быть использован (почти) для любого элемента HTML (так же как класс). Это всегда отличная идея использовать <code>id</code>, так как это позволяет намного проще идентифицировать наш элемент в сценарии.</p>
+
+<p>Элемент <code>&lt;canvas&gt;</code> может быть стилизован также, как любое изображение (margin, border, background, и т. д.). Эти правила, как бы то ни было, фактически не влияют на отрисовку в canvas. Мы увидим как это сделано позже в этом руководстве. Когда стили не указаны, canvas будет по умолчанию абсолютно прозрачным.</p>
+
+<div id="section_2">
+<h3 id="Запасное_содержимое">Запасное содержимое</h3>
+
+<p>Из-за того, что старые браузеры (в особенности, версии Internet Explorer раннее чем 9) не поддерживают элемент {{HTMLElement("canvas")}}, Вам следует предоставить запасное содержимое для отображения этими браузерами.</p>
+
+<p>Это очень просто: мы всего лишь предоставляем альтернативное содержимое внутри элемента <code>&lt;canvas&gt;</code>. Браузеры, которые не поддерживают <code>&lt;canvas&gt;</code> проигнорируют container и отобразят запасное содержимое этого тега. Браузеры, которые поддерживают <code>&lt;canvas&gt;</code> проигнорируют запасное содержимое, и просто нормально отобразят canvas.</p>
+
+<p>Например, мы можем предоставить текстовое описание содержимого canvas или предоставить статичное изображение динамически отображаемого содержимого. Это может выглядеть как-то так:</p>
+
+<pre class="brush: html notranslate">&lt;canvas id="stockGraph" width="150" height="150"&gt;
+ current stock price: $3.15 +0.15
+&lt;/canvas&gt;
+
+&lt;canvas id="clock" width="150" height="150"&gt;
+ &lt;img src="images/clock.png" width="150" height="150" alt=""/&gt;
+&lt;/canvas&gt;
+</pre>
+
+<p>Сообщать пользователю о том, что его браузер не поддерживает canvas не поможет тем, кто не может прочесть содержимое тега canvas, к примеру. Предоставление полезной информации в дополнительном canvas <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility">делает этот тег более доступным для широкого использования.</a></p>
+
+<h3 id="Требуется_тег_&lt;canvas>"><span class="short_text" id="result_box" lang="ru"><span class="hps">Требуется</span> <span class="hps">тег </span></span><code>&lt;/canvas&gt;</code></h3>
+
+<p>В отличии от элемента {{HTMLElement("img")}}, элемент {{HTMLElement("canvas")}}  <strong>требует</strong> закрывающийся тег (<code>&lt;/canvas&gt;</code>). Если этот тег не предоставлен, остаток документа будет считаться запасным контентом и не будет отображен.</p>
+
+<p>Если запасной контент не нужен, простой  <code>&lt;canvas id="foo" ...&gt;&lt;/canvas&gt;</code> полностью совместим со всеми браузерами, что поддерживают canvas.</p>
+
+<h2 id="Рендеринг_содержимого_контекста">Рендеринг содержимого (контекста)</h2>
+
+<p>Элемент {{HTMLElement("canvas")}} в документе создается с фиксированным размером элемента для рисования, который может иметь один или несколько контекстов для рендеринга, создавая и манипулируя содержимым для показа. В данном руководстве мы сфокусируемся на 2D рендеринге. Другие контексты могут предоставлять разные типы рендеринга, к примеру WebGl использует 3D контекст основанный на <a href="http://www.khronos.org/opengles/">OpenGL ES</a>.</p>
+
+<p>Холст изначально пустой и прозрачный. Первым делом скрипт получает доступ к контексту и отрисовывает его. Элемент {{HTMLElement("canvas")}} имеет <a href="/en-US/docs/Web/API/HTMLCanvasElement#Method">метод</a> <code>getContext()</code>, используется для получения контекста визуализации и ее функции рисования. <code>getContext()</code> принимает один параметр, тип контекста. Для 2D графики, которая охвачена этим руководством будем использвать метку "2d".</p>
+
+<pre class="brush: js notranslate">var canvas = document.getElementById('tutorial');
+var ctx = canvas.getContext('2d');
+</pre>
+
+<p>В первой строке скрипта мы получаем узел нашего холста {{HTMLElement("canvas")}}, далее с помощью  {{domxref("document.getContext()")}} метода мы присваиваем ему контекст. Имея узел элемента , вы всегда можете получить для рисования контекст при помощи метода <code>getContext()</code>.</p>
+
+<div id="section_5">
+<h2 id="Проверка_поддержки">Проверка поддержки</h2>
+
+<p>Ранее уже упоминалось, что в браузерах, которые не поддерживают {{HTMLElement("canvas")}} отображается запасное содержимое. Но помимо этого, определить, поддерживает ли браузер <code>canvas</code>, можно прямо из кода, проверив наличие метода <code>getContext()</code>. Код с запасным содержимым, который мы приводили Выше, становится следующим:</p>
+
+<pre class="brush: js notranslate">var canvas = document.getElementById('tutorial');
+
+if (canvas.getContext){
+ var ctx = canvas.getContext('2d');
+ // drawing code here
+} else {
+ // canvas-unsupported code here
+}
+</pre>
+</div>
+</div>
+
+<h2 id="Скелет_шаблона">Скелет шаблона</h2>
+
+<p>Здесь минимальный шаблон, который мы будем использовать как начальную точку для дальнейших примеров.</p>
+
+<div class="blockIndicator note">
+<p><strong>Примечание:</strong> вставка скрипта внутрь HTML не является хорошей практикой. Мы делаем это здесь, чтобы сделать пример короче.</p>
+</div>
+
+<pre class="notranslate"><code>&lt;!DOCTYPE html&gt;</code>
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;title&gt;Canvas tutorial&lt;/title&gt;
+ &lt;script type="text/javascript"&gt;
+ function draw(){
+ var canvas = document.getElementById('tutorial');
+ if (canvas.getContext){
+ var ctx = canvas.getContext('2d');
+ }
+ }
+ &lt;/script&gt;
+ &lt;style type="text/css"&gt;
+ canvas { border: 1px solid black; }
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body onload="draw();"&gt;
+ &lt;canvas id="tutorial" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>Скрипт вызывает функцию draw(), которая выполнится, когда страница закончит загрузку. Это делается путем события {{event("load")}} в документе. Эта функция может быть вызвана как единожды, так и с помощью данных методов {{domxref("window.setTimeout()")}}, {{domxref("window.setInterval()")}}, или любым другим обработчиком события, когда страница будет загружена.</p>
+
+<p>Вот как шаблон будет выглядеть в действии.</p>
+
+<p>{{EmbedLiveSample("Скелет_шаблона", 160, 160)}}</p>
+
+<h2 id="Простой_пример">Простой пример</h2>
+
+<p>Для начала, давайте посмотрим на простой пример, который рисует два пересекающихся прямоугольника, один из которых имеет прозрачность alpha. Мы изучим, как это работает более детально в последующих примерах.</p>
+
+<pre class="notranslate"><code>&lt;!DOCTYPE html&gt;</code>
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;script type="application/javascript"&gt;
+ function draw() {
+ var canvas = document.getElementById("canvas");
+ if (canvas.getContext) {
+ var ctx = canvas.getContext("2d");
+
+ ctx.fillStyle = "rgb(200,0,0)";
+ ctx.fillRect (10, 10, 55, 50);
+
+ ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
+ ctx.fillRect (30, 30, 55, 50);
+ }
+ }
+ &lt;/script&gt;
+ &lt;/head&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>
+
+<p>Этот пример выглядит так:</p>
+
+<p>{{EmbedLiveSample("Простой_пример", 160, 160, "https://mdn.mozillademos.org/files/228/canvas_ex1.png")}}</p>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/finale/index.html b/files/ru/web/api/canvas_api/tutorial/finale/index.html
new file mode 100644
index 0000000000..63187795bd
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/finale/index.html
@@ -0,0 +1,51 @@
+---
+title: Finale
+slug: Web/API/Canvas_API/Tutorial/Finale
+translation_of: Web/API/Canvas_API/Tutorial/Finale
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Optimizing_canvas")}}</div>
+
+<div class="summary">
+<p>Поздравляем! Вы завершили <a href="/en-US/docs/Web/API/Canvas_API/Tutorial">Canvas tutorial</a>! Эти знания помогут вам создавать великолепную 2d графику в сети.</p>
+</div>
+
+<h2 id="Больше_примеров_и_учебных_материалов">Больше примеров и учебных материалов</h2>
+
+<p>Различные демки и дополнительные разъяснеия о canvas расположены на этих сайтах:</p>
+
+<dl>
+ <dt><a href="http://codepen.io/search?q=canvas">Codepen.io</a></dt>
+ <dd>Песочница для фронтенд разработчика и редактор кода в браузере.</dd>
+ <dt><a href="http://www.canvasdemos.com/">Canvasdemos.com</a></dt>
+ <dd>Приложения, игры, инструменты и учебные пособия для HTML5 canvas элементов.</dd>
+ <dt><a href="http://www.html5canvastutorials.com/">HTML5CanvasTutorials</a></dt>
+ <dd>Примеры для большинтсва canvas APIs.</dd>
+ <dt><a href="http://creativejs.com/2011/08/31-days-of-canvas-tutorials/">31 days of Canvas tutorials</a></dt>
+ <dd>Прекрасное введение в разработку графики на JavaScript.</dd>
+ <dt><a href="/en-US/docs/Games">Game development</a></dt>
+ <dd>Игры - одна из наболее популярных  действий на компьютере. Постоянно появляются новые технологии, делающих возможным разработку более лучших и мощных игр, чем те, которые могли быть созданы стандартными средствами веб браузеров.</dd>
+</dl>
+
+<h2 id="Другие_Web_API">Другие Web API</h2>
+
+<p>Эти APIs могут быть полезны  в дальнейшей работе с canvas и графикой:</p>
+
+<dl>
+ <dt><a href="/en-US/docs/Web/WebGL">WebGL</a></dt>
+ <dd>API для отображения интерактивной 3D графики.</dd>
+ <dt><a href="/en-US/docs/Web/SVG">SVG</a></dt>
+ <dd>Масштабируемая Векторная Графика (Scalable Vector Graphics) позволяет описывать картинки в виде набора векторов (линий) и  форм, позволяюших плавно изменять размер вне зависимости от размера в котором они нарисованы.</dd>
+ <dt><a href="/en-US/docs/Web/API/Web_Audio_API">Web Audio</a></dt>
+ <dd>Web Audio API представляет мощную и универсальную систему контроля аудио в сети, позволяющая разработчикам получить аудио ресурсы, добавлять эффекты аудио, создавать аудио визуализацию,  применять пространственные эффекты (такие как сдвиг) и многое другое.</dd>
+</dl>
+
+<h2 id="Вопросы">Вопросы</h2>
+
+<dl>
+ <dt><a href="http://stackoverflow.com/questions/tagged/canvas">Stackoverflow</a></dt>
+ <dd>Вопросы с тегом "canvas".</dd>
+ <dt><a href="/en-US/docs/MDN">Comments about this tutorial – the MDN documentation community</a></dt>
+ <dd>Если у вас остались вопросы об этом учебнике или вы хотите поблагодарить нас, не стесняйтесь обращаться к нам!</dd>
+</dl>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Optimizing_canvas")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/index.html b/files/ru/web/api/canvas_api/tutorial/index.html
new file mode 100644
index 0000000000..8409367956
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/index.html
@@ -0,0 +1,58 @@
+---
+title: Руководство по Canvas
+slug: Web/API/Canvas_API/Tutorial
+tags:
+ - Canvas
+ - Graphics
+translation_of: Web/API/Canvas_API/Tutorial
+---
+<p><a href="/ru/docs/Web/API/Canvas_API"><img alt="" src="https://mdn.mozillademos.org/files/257/Canvas_tut_examples.jpg" style="float: right; height: 450px; width: 200px;"></a>{{CanvasSidebar}}</p>
+
+<p class="summary"><a href="/ru/docs/Web/HTML/Element/canvas" title="HTML/Canvas"><strong><code>&lt;canvas&gt;</code></strong></a> — это <a href="Web/HTML" title="HTML">HTML</a> элемент, использующийся для рисования графики средствами языков программирования (обычно это <a href="Словарь/JavaScript">JavaScript</a>). Он может, к примеру, использоваться для рисования графов, создания коллажей или простой (<a href="/en-US/docs/Web/API/Canvas_API/A_basic_ray-caster" title="A_Basic_RayCaster">и не очень</a>) анимации.<br>
+ Изображения в правой части статьи являются примерами использования <code><a href="/ru/docs/Web/HTML/Element/canvas">&lt;canvas&gt;</a>.</code><br>
+ Примеры их создания приводятся в этой статье. </p>
+
+<p>В этом руководстве описываются основы использования элемента <code>&lt;canvas&gt;</code> для рисования 2D-графики. Приведенные примеры дадут вам понимание того, что вы можете сделать с помощью &lt;canvas&gt;, а использованные в статье фрагменты кода помогут в создании собственных проектов.</p>
+
+<p><code>Впервые &lt;canvas&gt;</code> использовался компанией Apple для создания <a href="https://ru.wikipedia.org/wiki/Dashboard">Mac OS X Dashboard</a>, а затем был реализован в Web-браузерах. На сегодняшний день все основные браузеры поддерживют работу с &lt;canvas&gt;. Тег <code>&lt;canvas&gt;</code> часть спецификации <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/">WhatWG Web applications 1.0</a> также известной как HTML5.</p>
+
+<h2 id="Before_you_start" name="Before_you_start">Прежде чем начать</h2>
+
+<p>Работа с элементом <strong><code>&lt;canvas&gt;</code></strong> довольно проста, но потребует от вас базовых знаний <a href="ru/docs/HTML" title="HTML">HTML</a> и <a href="JavaScript" title="JavaScript">JavaScript</a>. Следует предупредить о том, что элемент <code>&lt;<strong>canvas&gt;</strong></code> не работает в некоторых старых браузерах, но поддерживается большинством современных браузеров. Стандартный размер <strong><code>&lt;canvas&gt;</code></strong>  300px × 150px (ширина × высота), однако эти размеры могут быть изменены при помощи HTML-атрибутов <code>height</code> и <code>width</code>. Для рисования графики <strong><code>&lt;canvas&gt;</code></strong> мы будем использовать <code>javascript context object</code>,  который создает графику динамически.</p>
+
+<h2 id="In_this_tutorial" name="In_this_tutorial">В этом руководстве</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Basic_usage" title="Canvas_tutorial/Basic_usage">Базовое использование</a></li>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Drawing_shapes" title="Canvas_tutorial/Drawing_shapes">Рисование форм</a></li>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images" title="Canvas_tutorial/Using_images">Использование изображений</a></li>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors" title="Canvas_tutorial/Applying_styles_and_colors">Применение стилей и цветов</a></li>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations" title="Canvas_tutorial/Transformations">Трансформации</a></li>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Compositing" title="Canvas_tutorial/Compositing">Композирование и обрезка</a></li>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Basic_animations" title="Canvas_tutorial/Basic_animations">Базовое анимирование</a></li>
+ <li><a href="/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas" title="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas">Оптимизация canvas</a></li>
+</ul>
+
+<h2 id="See_also" name="See_also">Смотрите Также</h2>
+
+<ul>
+ <li><a href="/en-US/docs/HTML/Canvas" title="HTML/Canvas">Canvas topic page</a></li>
+ <li><a href="/en-US/docs/HTML/Canvas/Drawing_Graphics_with_Canvas" title="Drawing_Graphics_with_Canvas">Drawing Graphics with Canvas</a></li>
+ <li><a href="/en-US/docs/tag/Canvas_examples" title="tag/Canvas_examples">Canvas examples</a></li>
+ <li><a class="external" href="http://html5tutorial.com" title="http://html5tutorial.com">HTML5 Tutorial</a></li>
+ <li><a href="/en-US/docs/Drawing_text_using_a_canvas" title="Drawing_text_using_a_canvas">Drawing Text Using a Canvas</a></li>
+ <li><a class="external" href="http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/HTML-canvas-guide/AddingText/AddingText.html#//apple_ref/doc/uid/TP40010542-CH6-SW4" title="Adding Text to Canvas">Adding Text to Canvas</a></li>
+ <li><a class="external" href="http://canvimation.github.com/" title="http://canvimation.github.com/">Canvas Drawing and Animation Application</a></li>
+ <li><a class="external" href="http://billmill.org/static/canvastutorial/" title="http://billmill.org/static/canvastutorial/">Interactive canvas tutorial</a></li>
+ <li><a class="external" href="http://www.html5canvastutorials.com/" title="http://www.html5canvastutorials.com/">HTML5CanvasTutorials</a></li>
+ <li><a class="external" href="http://html5tutorial.com/how-to-draw-n-grade-bezier-curve-with-canvas-api" title="http://html5tutorial.com/how-to-draw-n-grade-bezier-curve-with-canvas-api">How to draw N grade Bézier curves with the Canvas API</a></li>
+ <li><a href="http://www.w3.org/TR/2dcontext/" title="http://www.w3.org/TR/2dcontext/">W3C Standard</a></li>
+</ul>
+
+<h2 id="Примечание_для_помощников">Примечание для помощников</h2>
+
+<p>Из-за досадной технической ошибки, которая произошла 17 июня 2013 года, мы утеряли историю по этому руководству, в том числе атрибуции ко всем прошлым, участвовавшие в его создании. Мы приносим извинения за это, и надеемся, что вы простите нас за этот несчастный случай. </p>
+
+<div>
+<div>{{ Next("Web/API/Canvas_API/Tutorial/Basic_usage") }}</div>
+</div>
diff --git a/files/ru/web/api/canvas_api/tutorial/optimizing_canvas/index.html b/files/ru/web/api/canvas_api/tutorial/optimizing_canvas/index.html
new file mode 100644
index 0000000000..40a83917e8
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/optimizing_canvas/index.html
@@ -0,0 +1,120 @@
+---
+title: Оптимизация canvas
+slug: Web/API/Canvas_API/Tutorial/Optimizing_canvas
+tags:
+ - Canvas
+ - Graphics
+ - HTML
+ - HTML5
+ - Tutorial
+ - Оптимизация
+ - Урок
+ - Холст
+translation_of: Web/API/Canvas_API/Tutorial/Optimizing_canvas
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}</div>
+
+<div class="summary">
+<p>Элемент {{HTMLElement ("canvas")}} является одним из наиболее широко используемых инструментов для рендеринга 2D-графики в Интернете. Однако когда веб-сайты и приложения используют Canvas API на пределе его возможностей, производительность начинает снижаться. В этой статье приводятся предложения по оптимизации использования элемента canvas для обеспечения хорошей работы графики.</p>
+</div>
+
+<h2 id="Советы_по_производительности">Советы по производительности</h2>
+
+<p>Ниже приведен сборник советов по улучшению производительности canvas.</p>
+
+<h3 id="Предварительно_отрисуйте_похожие_примитивы_или_повторяющиеся_объекты_на_offscreen_canvas">Предварительно отрисуйте похожие примитивы или повторяющиеся объекты на offscreen canvas</h3>
+
+<p>Если вы повторяете одни и те же операции рисования в каждом кадре анимации, рассмотрите возможность их выгрузки на offscreen canvas. Затем вы можете визуализировать закадровое изображение на свой основной canvas так часто, как это необходимо, без необходимости повторять шаги, необходимые для его генерации.</p>
+
+<pre class="brush: js">myCanvas.offscreenCanvas = document.createElement('canvas');
+myCanvas.offscreenCanvas.width = myCanvas.width;
+myCanvas.offscreenCanvas.height = myCanvas.height;
+
+myCanvas.getContext('2d').drawImage(myCanvas.offScreenCanvas, 0, 0);
+</pre>
+
+<h3 id="Избегайте_координат_с_плавающей_точкой_и_используйте_вместо_них_целые_числа">Избегайте координат с плавающей точкой и используйте вместо них целые числа</h3>
+
+<p>Субпиксельный рендеринг происходит при рендеринге объектов на canvas без целых значений.</p>
+
+<pre class="brush: js">ctx.drawImage(myImage, 0.3, 0.5);
+</pre>
+
+<p>Это заставляет браузер выполнять дополнительные вычисления для создания эффекта сглаживания. Чтобы избежать этого, обязательно округлите все координаты, используемые в вызовах {{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}, например, с помощью {{jsxref("Math.floor()")}}.</p>
+
+<h3 id="Не_масштабируйте_изображения_в_drawImage">Не масштабируйте изображения в <code>drawImage</code></h3>
+
+<p>При загрузке кэшируйте изображения разных размеров на offscreen canvas, а не постоянно масштабируйте их в {{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}.</p>
+
+<h3 id="Используйте_несколько_слоев_canvas_для_сложных_сцен">Используйте несколько слоев canvas для сложных сцен</h3>
+
+<p>Вы можете обнаружить, что некоторые объекты в вашем приложении нужно часто перемещать или менять, в то время как другие остаются относительно статичными. Возможной оптимизацией в этой ситуации является наложение ваших элементов с использованием нескольких элементов <code>&lt;canvas&gt;</code>.</p>
+
+<p>Например, допустим, у вас есть игра с пользовательским интерфейсом наверху, геймплеем в середине и статическим фоном внизу. В этом случае вы можете разбить свою игру на три слоя <code>&lt;canvas&gt;</code>. Пользовательский интерфейс будет меняться только при изменении пользователем, слой с игровым процессом будет меняться с каждым новым кадром, а фон останется в основном неизменным.</p>
+
+<pre class="brush: html">&lt;div id="stage"&gt;
+ &lt;canvas id="ui-layer" width="480" height="320"&gt;&lt;/canvas&gt;
+ &lt;canvas id="game-layer" width="480" height="320"&gt;&lt;/canvas&gt;
+ &lt;canvas id="background-layer" width="480" height="320"&gt;&lt;/canvas&gt;
+&lt;/div&gt;
+
+&lt;style&gt;
+ #stage {
+ width: 480px;
+ height: 320px;
+ position: relative;
+ border: 2px solid black;
+ }
+
+ canvas { position: absolute; }
+ #ui-layer { z-index: 3; }
+ #game-layer { z-index: 2; }
+ #background-layer { z-index: 1; }
+&lt;/style&gt;
+</pre>
+
+<h3 id="Используйте_простой_CSS_для_больших_фоновых_изображений">Используйте простой CSS для больших фоновых изображений</h3>
+
+<p>Если у вас есть статическое фоновое изображение, вы можете нарисовать его на простом элементе {{HTMLElement("div")}}, используя свойство CSS {{cssxref("background")}}, и расположить его под canvas. Это сведет на нет необходимость рендеринга фона на canvas на каждом тике.</p>
+
+<h3 id="Масштабирование_холста_с_использованием_CSS-преобразований">Масштабирование холста с использованием CSS-преобразований</h3>
+
+<p><a href="/en-US/docs/Web/Guide/CSS/Using_CSS_transforms">CSS-преобразования</a> быстрее, поскольку они используют графический процессор. В идеале, не стоит не масштабировать canvas, или можно использовать меньший canvas и увеличивать его при необходимости, но не уменьшать.</p>
+
+<pre class="brush: js">var scaleX = window.innerWidth / canvas.width;
+var scaleY = window.innerHeight / canvas.height;
+
+var scaleToFit = Math.min(scaleX, scaleY);
+var scaleToCover = Math.max(scaleX, scaleY);
+
+stage.style.transformOrigin = '0 0'; //scale from top left
+stage.style.transform = 'scale(' + scaleToFit + ')';
+</pre>
+
+<h3 id="Отключите_прозрачность">Отключите прозрачность</h3>
+
+<p>Если ваше приложение использует canvas и не нуждается в прозрачном фоне, установите для параметра <code>alpha</code>значение <code>false</code> при создании контекста рисования с помощью {{domxref("HTMLCanvasElement.getContext()")}}. Эта информация может использоваться браузером для оптимизации рендеринга.</p>
+
+<pre class="brush: js">var ctx = canvas.getContext('2d', { alpha: false });</pre>
+
+<h3 id="Другие_советы">Другие советы</h3>
+
+<ul>
+ <li>Объединяйте запросы к canvas. Например, рисуйте одну ломанную линию вместо нескольких отдельных линий.</li>
+ <li>Избегайте ненужных изменений состояния canvas.</li>
+ <li>Отображайте только изменения экрана, а не заново перерисовывайте.</li>
+ <li>По возможности избегайте свойства {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}}.</li>
+ <li>Избегайте <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text">рендеринга текста</a>, когда это возможно.</li>
+ <li>Попробуйте разные способы очистки canvas (({{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}, или {{domxref("CanvasRenderingContext2D.fillRect", "fillRect()")}}, или изменение размера canvas).</li>
+ <li>С анимациями используйте {{domxref("window.requestAnimationFrame()")}} вместо {{domxref("window.setInterval()")}}.</li>
+ <li>Будьте осторожны с тяжелыми физическими библиотеками.</li>
+</ul>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li><a href="http://www.html5rocks.com/en/tutorials/canvas/performance/#toc-ref">Improving HTML5 Canvas Performance – HTML5 Rocks</a></li>
+ <li><a href="https://hacks.mozilla.org/2013/05/optimizing-your-javascript-game-for-firefox-os/">Optimizing your JavaScript game for Firefox OS – Mozilla Hacks</a></li>
+</ul>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.html b/files/ru/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.html
new file mode 100644
index 0000000000..8b8653a9b3
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.html
@@ -0,0 +1,267 @@
+---
+title: Пиксельная манипуляция с холстом
+slug: Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas
+tags:
+ - Графика
+ - Промежуточный
+ - Руководство
+ - Холст
+translation_of: Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}</div>
+
+<div class="summary">
+<p>До сих пор мы не смотрели на фактические пиксели нашего объекта canvas (далее "холст"). С объектом <code>ImageData</code> вы можете напрямую читать и писать массив данных для управления пиксельными данными. Мы также рассмотрим, как можно сгладить сглаживание изображения (сглаживание) и как сохранить изображения с вашего холста.</p>
+</div>
+
+<h2 id="Объект_ImageData">Объект <code>ImageData</code></h2>
+
+<p>Объект {{domxref ("ImageData")}} представляет базовые пиксельные данные области объекта холста. Он содержит следующие атрибуты только для чтения:</p>
+
+<dl>
+ <dt><code>width</code></dt>
+ <dd>Ширина изображения в пикселях.</dd>
+ <dt><code>height</code></dt>
+ <dd>Высота изображения в пикселях.</dd>
+ <dt><code>data</code></dt>
+ <dd>A {{jsxref ("Uint8ClampedArray")}} представляет собой одномерный массив, содержащий данные в порядке RGBA, с целыми значениями от <code>0</code> до <code>255</code> (в комплекте).</dd>
+</dl>
+
+<p>Свойство <code>data</code> возвращает {{jsxref ("Uint8ClampedArray")}}, к которому можно получить доступ, чтобы посмотреть на необработанные пиксельные данные; каждый пиксель представлен четырьмя однобайтовыми значениями (красный, зеленый, синий и альфа в этом порядке, то есть формат «RGBA»). Каждый компонент цвета представлен целым числом от 0 до 255. Каждому компоненту присваивается последовательный индекс внутри массива, причем красный компонент верхнего левого пикселя находится в индексе 0 внутри массива. Затем пиксели идут слева направо, затем вниз, по всему массиву.</p>
+
+<p>{{Jsxref ("Uint8ClampedArray")}} содержит высоту × ширину × 4 байта данных, значения индекса варьируются от 0 до (высота × ширина × 4) -1.</p>
+
+<p>Например, чтобы прочитать значение синего компонента из пикселя в столбце 200, строка 50 на изображении, вы должны сделать следующее:</p>
+
+<pre class="brush: js">blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];</pre>
+
+<p>Вы можете получить доступ к размеру массива пикселей в байтах, прочитав атрибут <code>Uint8ClampedArray.length</code>:</p>
+
+<pre class="brush: js">var numBytes = imageData.data.length;
+</pre>
+
+<h2 id="Создание_объекта_ImageData">Создание объекта <code>ImageData</code></h2>
+
+<p>Чтобы создать новый пустой объект <code>ImageData</code> , вы должны использовать метод {{domxref ("CanvasRenderingContext2D.createImageData", "createImageData ()")}}. Существуют две версии метода <code>createImageData()</code> :</p>
+
+<pre class="brush: js">var myImageData = ctx.createImageData(width, height);</pre>
+
+<p>Это создает новый объект <code>ImageData</code> с указанными параметрами. Все пиксели заданы прозрачным черным.</p>
+
+<p>Вы также можете создать новый объект <code>ImageData</code> ImageData с теми же размерами, что и объект, заданный <code>anotherImageData</code> . Все пиксели нового объекта установлены на прозрачный черный. <strong>Это не копирует данные изображения!</strong></p>
+
+<pre class="brush: js">var myImageData = ctx.createImageData(anotherImageData);</pre>
+
+<h2 id="Получение_пиксельных_данных_для_контекста">Получение пиксельных данных для контекста</h2>
+
+<p>Чтобы получить объект <code>ImageData</code> , содержащий копию пиксельных данных для контекста холста, вы можете использовать метод <code>getImageData()</code> :</p>
+
+<pre class="brush: js">var myImageData = ctx.getImageData(left, top, width, height);</pre>
+
+<p>Этот метод возвращает объект <code>ImageData</code> , представляющий пиксельные данные для области холста, углы которого представлены точками (<code>left</code> , <code>top</code>), (<code>left+width</code> , <code>top</code>), (<code>left</code> , <code>top+height</code>) и (<code>left+width</code> , <code>top+height</code>). Координаты задаются в единицах пространства координат холста.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Любые пиксели за пределами холста возвращаются как прозрачный черный цвет в результирующий объект <code>ImageData</code> .</p>
+</div>
+
+<p>Этот метод также показан в статье <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas">Manipulating video using canvas</a>.</p>
+
+<h3 id="Выбор_цвета">Выбор цвета</h3>
+
+<p>В этом примере мы используем метод <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData">getImageData() </a> для отображения цвета под курсором мыши. Для этого нам нужна текущая позиция мыши с <code>layerX</code> и <code>layerY</code>, затем мы просматриваем пиксельные данные в этой позиции в массиве пикселей, который предоставляет нам <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData">getImageData() </a> . Наконец, мы используем данные массива для установки цвета фона и текста <code>&lt;div&gt;</code> для отображения цвета.</p>
+
+<div class="hidden">
+<pre class="brush: html;">&lt;canvas id="canvas" width="300" height="227" style="float:left"&gt;&lt;/canvas&gt;
+&lt;div id="color" style="width:200px;height:50px;float:left"&gt;&lt;/div&gt;
+</pre>
+</div>
+
+<pre class="brush: js;">var img = new Image();
+img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+img.onload = function() {
+ ctx.drawImage(img, 0, 0);
+ img.style.display = 'none';
+};
+var color = document.getElementById('color');
+function pick(event) {
+ var x = event.layerX;
+ var y = event.layerY;
+ var pixel = ctx.getImageData(x, y, 1, 1);
+ var data = pixel.data;
+ var rgba = 'rgba(' + data[0] + ', ' + data[1] +
+ ', ' + data[2] + ', ' + (data[3] / 255) + ')';
+ color.style.background = rgba;
+ color.textContent = rgba;
+}
+canvas.addEventListener('mousemove', pick);
+</pre>
+
+<p>{{ EmbedLiveSample('A_color_picker', 610, 240) }}</p>
+
+<h2 id="Отображение_пиксельных_данных_в_контекст">Отображение пиксельных данных в контекст</h2>
+
+<p>Вы можете использовать метод <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData">putImageData()</a> для рисования пиксельных данных в контексте:</p>
+
+<pre class="brush: js">ctx.putImageData(myImageData, dx, dy);
+</pre>
+
+<p>Параметры <code>dx</code>и <code>dy</code>указывают координаты устройства в контексте, в котором будет отображаться верхний левый угол пиксельных данных, которые вы хотите нарисовать.</p>
+
+<p>Например, чтобы нарисовать все изображение, представленное <code>myImageData</code>, в верхнем левом углу контекста, вы можете просто сделать следующее:</p>
+
+<pre class="brush: js">ctx.putImageData(myImageData, 0, 0);
+</pre>
+
+<h3 id="Оттенки_серого_цвета_и_инвертирование_цветов">Оттенки серого цвета и инвертирование цветов</h3>
+
+<p>В этом примере мы перебираем все пиксели для изменения их значений, а затем помещаем модифицированный массив пикселей обратно в canvas с помощью <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData">putImageData()</a>. Функция инвертирования просто вычитает каждый цвет из максимального значения 255. Функция оттенков серого просто использует среднее значение красного, зеленого и синего. Вы также можете использовать средневзвешенное значение, заданное формулой <code>x = 0.299r + 0.587g + 0.114b</code>, например. Для дополнительной информации см. <a href="http://en.wikipedia.org/wiki/Grayscale">Grayscale</a> в Википедии.</p>
+
+<div class="hidden">
+<pre class="brush: html;">&lt;canvas id="canvas" width="300" height="227"&gt;&lt;/canvas&gt;
+&lt;div&gt;
+ &lt;input id="grayscalebtn" value="Grayscale" type="button"&gt;
+ &lt;input id="invertbtn" value="Invert" type="button"&gt;
+&lt;/div&gt;
+</pre>
+</div>
+
+<pre class="brush: js">var img = new Image();
+img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
+img.onload = function() {
+ draw(this);
+};
+
+function draw(img) {
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(img, 0, 0);
+ img.style.display = 'none';
+ var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ var data = imageData.data;
+
+ var invert = function() {
+ for (var i = 0; i &lt; data.length; i += 4) {
+ data[i] = 255 - data[i]; // red
+ data[i + 1] = 255 - data[i + 1]; // green
+ data[i + 2] = 255 - data[i + 2]; // blue
+ }
+ ctx.putImageData(imageData, 0, 0);
+ };
+
+ var grayscale = function() {
+ for (var i = 0; i &lt; data.length; i += 4) {
+ var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
+ data[i] = avg; // red
+ data[i + 1] = avg; // green
+ data[i + 2] = avg; // blue
+ }
+ ctx.putImageData(imageData, 0, 0);
+ };
+
+ var invertbtn = document.getElementById('invertbtn');
+ invertbtn.addEventListener('click', invert);
+ var grayscalebtn = document.getElementById('grayscalebtn');
+ grayscalebtn.addEventListener('click', grayscale);
+}
+</pre>
+
+<p>{{ EmbedLiveSample('Grayscaling_and_inverting_colors', 330, 270) }}</p>
+
+<h2 id="Масштабирование_и_сглаживание">Масштабирование и сглаживание</h2>
+
+<p>С помощью метода                                                             {{domxref ("CanvasRenderingContext2D.drawImage", "drawImage ()")}}, второго холста и свойства {{domxref ("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} мы способны увеличить изображение и посмотреть его более детально.</p>
+
+<p>Мы получаем положение мыши и обрезаем изображение на 5 пикселей левее и выше и на 5 пикселей правее и ниже положения мыши. Затем мы копируем его на другой холст и изменяем размер изображения до размера, который мы хотим. При масштабировании мы изменяем холст с исходного размера 10×10 пикселей до 200×200.</p>
+
+<pre class="brush: js">zoomctx.drawImage(canvas,
+ Math.abs(x - 5), Math.abs(y - 5),
+ 10, 10, 0, 0, 200, 200);</pre>
+
+<p>Поскольку по умолчанию включено сглаживание, мы можем захотеть отключить сглаживание, чтобы увидеть четкие пиксели. Вы можете переключить флажок, чтобы увидеть эффект свойства <code>imageSmoothingEnabled</code> (которому нужны префиксы для разных браузеров).</p>
+
+<h6 class="hidden" id="Zoom_example">Zoom example</h6>
+
+<div class="hidden">
+<pre class="brush: html;">&lt;canvas id="canvas" width="300" height="227"&gt;&lt;/canvas&gt;
+&lt;canvas id="zoom" width="300" height="227"&gt;&lt;/canvas&gt;
+&lt;div&gt;
+&lt;label for="smoothbtn"&gt;
+  &lt;input type="checkbox" name="smoothbtn" checked="checked" id="smoothbtn"&gt;
+  Enable image smoothing
+&lt;/label&gt;
+&lt;/div&gt;
+</pre>
+</div>
+
+<pre class="brush: js">var img = new Image();
+img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
+img.onload = function() {
+ draw(this);
+};
+
+function draw(img) {
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(img, 0, 0);
+ img.style.display = 'none';
+ var zoomctx = document.getElementById('zoom').getContext('2d');
+
+ var smoothbtn = document.getElementById('smoothbtn');
+ var toggleSmoothing = function(event) {
+ zoomctx.imageSmoothingEnabled = this.checked;
+ zoomctx.mozImageSmoothingEnabled = this.checked;
+ zoomctx.webkitImageSmoothingEnabled = this.checked;
+ zoomctx.msImageSmoothingEnabled = this.checked;
+ };
+ smoothbtn.addEventListener('change', toggleSmoothing);
+
+ var zoom = function(event) {
+ var x = event.layerX;
+ var y = event.layerY;
+ zoomctx.drawImage(canvas,
+ Math.abs(x - 5),
+ Math.abs(y - 5),
+ 10, 10,
+ 0, 0,
+ 200, 200);
+ };
+
+ canvas.addEventListener('mousemove', zoom);
+}</pre>
+
+<p>{{ EmbedLiveSample('Zoom_example', 620, 490) }}</p>
+
+<h2 id="Сохранение_изображений">Сохранение изображений</h2>
+
+<p>{{Domxref ("HTMLCanvasElement")}} предоставляет метод <code>toDataURL()</code>, который полезен при сохранении изображений. Он возвращает <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs">data URI</a>, содержащий представление изображения в формате, заданном параметром <code>type</code> (по умолчанию используется в <a class="external external-icon" href="https://en.wikipedia.org/wiki/Portable_Network_Graphics">PNG</a> ). Возвращаемое изображение имеет разрешение 96 точек на дюйм.</p>
+
+<dl>
+ <dt><strong>Примечание:</strong> </dt>
+ <dd>Имейте в виду, что если холст содержит пиксели, полученные из другого {{Glossary ("origin")}} без использования CORS, холст будет <strong>испорчен</strong>, и его содержимое больше не будет считываться и сохраняться. Смотрите {{SectionOnPage ("/en-US/docs/Web/HTML/CORS_enabled_image", "Безопасность и испорченные холсты")}}</dd>
+ <dt></dt>
+ <dt>{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/png')")}}</dt>
+ <dd>Настройки по умолчанию. Создает изображение в формате PNG.</dd>
+ <dt>{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/jpeg', quality)")}}</dt>
+ <dd>Создает изображение в формате JPG. Дополнительно вы можете задать параметр "качество" (quality) в диапазоне от 0 до 1, причем единица задает лучшее качество и 0 -  почти не распознаваемый, но небольшой по размеру файл.</dd>
+</dl>
+
+<p>После того как вы создали URI данные из своего холста, вы можете использовать его как источник любого {{HTMLElement ("image")}} или поместить его в гиперссылку с <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download">download attribute</a>, чтобы сохранить его на диске, например.</p>
+
+<p>Вы также можете создать {{domxref ("Blob")}} из холста.</p>
+
+<dl>
+ <dt>{{domxref("HTMLCanvasElement.toBlob", "canvas.toBlob(callback, type, encoderOptions)")}}</dt>
+ <dd>Создает объект <code>Blob</code>, представляющий изображение, содержащееся в холсте.</dd>
+</dl>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li>{{domxref("ImageData")}}</li>
+ <li><a href="/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas">Manipulating video using canvas</a></li>
+ <li><a href="https://codepo8.github.io/canvas-images-and-pixels/">Canvas, images and pixels – by Christian Heilmann</a></li>
+</ul>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/transformations/index.html b/files/ru/web/api/canvas_api/tutorial/transformations/index.html
new file mode 100644
index 0000000000..0f871d6909
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/transformations/index.html
@@ -0,0 +1,275 @@
+---
+title: Transformations
+slug: Web/API/Canvas_API/Tutorial/Transformations
+translation_of: Web/API/Canvas_API/Tutorial/Transformations
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}</div>
+
+<div class="summary"><span class="notranslate">Ранее в этом уроке мы узнали о</span> <span class="notranslate" style="background-color: #e6ecf9;"> <a href="https://translate.googleusercontent.com/translate_c?act=url&amp;depth=1&amp;hl=ru&amp;ie=UTF8&amp;prev=_t&amp;rurl=translate.google.com&amp;sl=en&amp;sp=nmt4&amp;tl=ru&amp;u=https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes&amp;usg=ALkJrhiuWce927wE2920fN95Jlcrf1HyUg">сетке холста</a></span> <span class="notranslate">и <strong>координатном пространстве</strong> .</span> <span class="notranslate"> До сих пор мы использовали только сетку по умолчанию и изменили размер всего холста для наших нужд.</span> При преобразованиях существуют более мощные способы изменения исходных координат в различные положение, поворот сетки и даже масштабирование.</div>
+
+<h2 id="Saving_and_restoring_state" name="Saving_and_restoring_state"><span class="notranslate" style="background-color: #e6ecf9;">Сохранение и восстановление состояния</span></h2>
+
+<p><span class="notranslate">Прежде чем перейти к методам преобразования, давайте рассмотрим два других метода, которые необходимы, когда вы начинаете создавать все более сложные рисунки.</span></p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.save", "save()")}}</dt>
+ <dd><span class="notranslate">Сохраняет все состояние холста.</span></dd>
+ <dt>{{domxref("CanvasRenderingContext2D.restore", "restore()")}}</dt>
+ <dd><span class="notranslate">Восстанавливает последнее сохраненное состояние холста.</span></dd>
+</dl>
+
+<p>Состояние холста сохраняется в стеке. Каждый раз, когда вызывается метод <code>save()</code>, текущее состояние отрисовки записывается в стек. Состояние отрисовки содержит:</p>
+
+<ul>
+ <li>Трансформации, которые были применены (например, <code>translate</code>, <code>rotate</code> and <code>scale</code> – см. ниже).</li>
+ <li>Текущее значение следующих атрибутов: {{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle")}}, {{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle")}}, {{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha")}}, {{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth")}}, {{domxref("CanvasRenderingContext2D.lineCap", "lineCap")}}, {{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin")}}, {{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit")}}, {{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset")}}, {{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX")}}, {{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY")}}, {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}}, {{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor")}}, {{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation")}}, {{domxref("CanvasRenderingContext2D.font", "font")}}, {{domxref("CanvasRenderingContext2D.textAlign", "textAlign")}}, {{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline")}}, {{domxref("CanvasRenderingContext2D.direction", "direction")}}, {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}}.</li>
+ <li>Текущее значение границ вырезанного холста (<a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing#Clipping_paths">clipping path</a>), которые будут рассматриваться в следующем разделе.</li>
+</ul>
+
+<p>Вы можете вызывать метод <code>save()</code> столько раз, сколько захотите. В то же время, при вызове метода <code>restore()</code> последнее сохранённое состояние будет считано из стека, и все сохранённые настройки будут восстановлены.</p>
+
+<h3 id="A_save_and_restore_canvas_state_example" name="A_save_and_restore_canvas_state_example">Пример <font face="consolas, Liberation Mono, courier, monospace">сохранения и восстановления</font> состояния холста</h3>
+
+<p>Здесь показано, как функционирует сохранение в стек состояния отрисовки на примере последовательной отрисовки набора прямоугольников.</p>
+
+<pre class="brush: js; highlight:[5,10,15,18] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ ctx.fillRect(0, 0, 150, 150); // рисуем прямоугольник с настройками по умолчанию
+ ctx.save(); // сохраняем состояние
+
+ ctx.fillStyle = '#09F'; // вносим изменения в настройки
+ ctx.fillRect(15, 15, 120, 120); // рисуем прямоугольник с новыми настройками
+ ctx.save(); // сохраняем состояние
+
+ ctx.fillStyle = '#FFF'; // вносим изменения в настройки
+ ctx.globalAlpha = 0.5;
+ ctx.fillRect(30, 30, 90, 90); // рисуем прямоугольник с новыми настройками
+
+ ctx.restore(); // возвращаемся к предыдущим настройкам
+ ctx.fillRect(45, 45, 60, 60); // рисуем прямоугольник с восстановленными настройками
+
+ ctx.restore(); // возвращаемся к начальным настройкам
+ ctx.fillRect(60, 60, 30, 30); // рисуем прямоугольник с изначальными настройками
+}</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>Сначала рисуется большой прямоугольник с настройками по умолчанию. Затем мы сохраняем состояние холста, после чего изменяем цвет заливки. Затем рисуем второй синий прямоугольник меньшего размера и опять сохраняем состояние. Снова изменяем какие-то настройки и рисуем третий полупрозрачный белый прямоугольник.</p>
+
+<p>До сих пор наши действия ничем не отличались от тех, что мы делали в предыдущем разделе. Однако, как только мы сделали первый вызов <code>restore(),</code> последнее сохранённое состояние отрисовки было восстановлено из стека, вернув все сохранённые настройки. Если бы мы не сохранили предыдущее состояние, используя <code>save()</code>, нам бы пришлось менять цвет заливки и настройки прозрачности вручную для возврата к предыдущему состоянию. Для каких-нибудь двух простых свойств это, может быть, сделать не так сложно. Но если таких своиств гораздо больше, это чревато очень быстрым разрастанием кода.</p>
+
+<p>Когда второй вызов <code>restore()</code> сделан, изначальное состояние (то самое, которое было сделано перед первым вызовом <code>save</code>) восстанавливается и последний нарисованный прямоугольник внось становится чёрным.</p>
+
+<p>{{EmbedLiveSample("A_save_and_restore_canvas_state_example", "180", "180", "https://mdn.mozillademos.org/files/249/Canvas_savestate.png")}}</p>
+
+<h2 id="Translating" name="Translating">Трансляция (смещение)</h2>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/234/Canvas_grid_translate.png" style="float: right;">Первый метод для трасформирования холста <code>translate()</code>. Он используется для перемещения холста в любую точку нашей сетки.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.translate", "translate(x, y)")}}</dt>
+ <dd>Перемещение холста на сетке. <code>x</code> и <code>y</code> - смещение по горизонтали и вертикали соответственно.</dd>
+</dl>
+
+<p>Неплохая идея - сохранять <code>canvas state</code> перед использованием любых трансформаций. Обычно удобнее использовать метод <code>restore</code>, чем выполнять обратные преобразования, чтобы вернуться к начальному состоянию. <span class="tlid-translation translation" lang="ru"><span title="">Кроме того, если вы выполняете преобразования внутри цикла не используя </span></span><code>save</code><span class="tlid-translation translation" lang="ru"><span title=""> и </span></span><code>restore</code><span class="tlid-translation translation" lang="ru"><span title="">, вы рискуете потерять часть рисунка, потому что он был нарисован за пределами края холста.</span></span></p>
+
+<h3 id="A_translate_example" name="A_translate_example">Пример использования <code>translate</code></h3>
+
+<p><span class="tlid-translation translation" lang="ru"><span title="">Этот пример демонстрирует некоторые преимущества</span></span> при использовании смещения холста. Без использования метода <code>translate()</code> все прямоугольники будут отрисованы в одинаковой позиции (0,0). Метод <code>translate()</code> дает возможность размещения прямоугольника в любой позиции без изменения параметров функции <code>fillRect()</code>. Это может дать некоторое упрощение для понимания и использования.</p>
+
+<p>Внутри функции <code>draw()</code> мы вызываем <code>fillRect()</code> девять раз, используя два цикла <code>for</code>. Каждый раз мы сохраняем состояние холста, смещаем его, рисуем прямоугольник, а затем восстанавливаем исходное состояние. Заметьте, что <code>fillRect()</code> всегда использует одни и те же параметры, а изменение позиции фигуры осуществляется с помощью <code>translate()</code>.</p>
+
+<pre class="brush: js; highlight:[7] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ for (var i = 0; i &lt; 3; i++) {
+ for (var j = 0; j &lt; 3; j++) {
+ ctx.save();
+ ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)';
+ ctx.translate(10 + j * 50, 10 + i * 50);
+ ctx.fillRect(0, 0, 25, 25);
+ ctx.restore();
+ }
+ }
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_translate_example", "160", "160", "https://mdn.mozillademos.org/files/9857/translate.png")}}</p>
+
+<h2 id="Rotating" name="Rotating">Поворот</h2>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/233/Canvas_grid_rotate.png" style="float: right;">Второй метод трансформации <code>rotate()</code>. Он используется для поворота нашего холста.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.rotate", "rotate(angle)")}}</dt>
+ <dd>Поворачивает наш холст по часовой стрелке вокруг начальной точки на угол <code>anglе</code> в радианах.</dd>
+</dl>
+
+<p>Центр поворота - всегда начало координат. Для изменения координат центра мы должны сместить холст, используя метод <code>translate()</code>.</p>
+
+<h3 id="A_rotate_example" name="A_rotate_example">Пример использования<code>rotate</code></h3>
+
+<p>В этом примере мы сначала используем <code>rotate()</code> для поворота прямоугольника относительно начала координат, а затем, используя <code>translate()</code> совместно с <code>rotate()</code> поворачиваем прямоугольник относительно его центра.</p>
+
+<div class="note">
+<p><strong>Памятка</strong>: Углы измеряются в радианах, а не в градусах. Для преобразования единиц используйте следующую формулу: <code>radians = (Math.PI/180)*degrees</code>.</p>
+</div>
+
+<pre class="brush: js; highlight:[9, 23] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // left rectangles, rotate from canvas origin
+ ctx.save();
+ // blue rect
+ ctx.fillStyle = '#0095DD';
+ ctx.fillRect(30, 30, 100, 100);
+ ctx.rotate((Math.PI / 180) * 25);
+ // grey rect
+ ctx.fillStyle = '#4D4E53';
+ ctx.fillRect(30, 30, 100, 100);
+ ctx.restore();
+
+ // right rectangles, rotate from rectangle center
+ // draw blue rect
+ ctx.fillStyle = '#0095DD';
+ ctx.fillRect(150, 30, 100, 100);
+
+ ctx.translate(200, 80); // translate to rectangle center
+ // x = x + 0.5 * width
+ // y = y + 0.5 * height
+ ctx.rotate((Math.PI / 180) * 25); // rotate
+ ctx.translate(-200, -80); // translate back
+
+ // draw grey rect
+ ctx.fillStyle = '#4D4E53';
+ ctx.fillRect(150, 30, 100, 100);
+}
+</pre>
+
+<p>Для поворота прямоугольника относительно его центра мы сначала смещаем начало координат, выполняем поворот, а затем выполняем обратное смещение к точке 0,0, и наконец рисуем прямоугольник.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="300" height="200"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_rotate_example", "310", "210", "https://mdn.mozillademos.org/files/9859/rotate.png")}}</p>
+
+<h2 id="Scaling" name="Scaling">Масштабирование</h2>
+
+<p>Следующий метод трансформации холста - scaling. Он используется для растяжения, сжатия и отражения координатной сетки. Он может использоваться для отрисовки растянутых или сжатых по осям фигур и изображений.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.scale", "scale(x, y)")}}</dt>
+ <dd>Масштабирует координатную сетку холста по горизонтали и вертикали. Оба параметра - вещественные числа. Значения меньше 1.0 уменьшают, а больше 1.0 увеличивают масштаб сетки. Значение 1.0 не изменяет его.</dd>
+</dl>
+
+<p>Используя отрицательные значения вы можете зеркально отразить направление осей. Например, используя <code>translate(0,canvas.height); scale(1,-1);</code> вы получите хорошо известную декартову систему координат с началом в верхнем левом углу.</p>
+
+<p>По умолчанию единица координатной сетки точно соответствует одному пикселю. Если же вы, например, зададите масштабный коэффициент 0.5, то единица сетки будет равна половине пикселя, и нарисованная фигура будет иметь размер в два раза меньше оригинала. Наоборот, если задать масштабный коэффициент 2.0, единица сетки будет соответствовать двум пикселям, а нарисованная фигура станет в два раза больше.</p>
+
+<h3 id="A_scale_example" name="A_scale_example">Пример использования <code>scale</code></h3>
+
+<p>В этом примере мы нарисуем прямоугольники, используя разные масштабные коэффициенты.</p>
+
+<pre class="brush: js; highlight:[6,11] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // рисуем масштабированный прямоугольник.
+ ctx.save();
+ ctx.scale(10, 3);
+ ctx.fillRect(1, 10, 10, 10);
+ ctx.restore();
+
+ // размещаем текст, отраженный по горизонтали
+ ctx.scale(-1, 1);
+ ctx.font = '48px serif';
+ ctx.fillText('MDN', -135, 120);
+}
+
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_scale_example", "160", "160", "https://mdn.mozillademos.org/files/9861/scale.png")}}</p>
+
+<h2 id="Transforms" name="Transforms">Матричное преобразование</h2>
+
+<p>В заключении рассмотрим метод, который вызывает изменения в соответствии с матрицей преобразования.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.transform", "transform(a, b, c, d, e, f)")}}</dt>
+ <dd>Накладывает матрицу преобразования, заданную параметрами, на текущую матрицу. Матрица преобразования задается следующим образом: <math><semantics><mrow><mo>[</mo><mtable columnalign="center center center" rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd><mtd><mi>c</mi></mtd><mtd><mi>e</mi></mtd></mtr><mtr><mtd><mi>b</mi></mtd><mtd><mi>d</mi></mtd><mtd><mi>f</mi></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable><mo>]</mo></mrow><annotation encoding="TeX">\left[ \begin{array}{ccc} a &amp; c &amp; e \\ b &amp; d &amp; f \\ 0 &amp; 0 &amp; 1 \end{array} \right]</annotation></semantics></math></dd>
+</dl>
+
+<dl>
+ <dd>If any of the arguments are <code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity">Infinity</a></code> the transformation matrix must be marked as infinite instead of the method throwing an exception.</dd>
+</dl>
+
+<p>Параметры функции:</p>
+
+<dl>
+ <dt><code>a (m11)</code></dt>
+ <dd>Horizontal scaling.</dd>
+ <dt><em><code>b (m12)</code></em></dt>
+ <dd>Horizontal skewing.</dd>
+ <dt><code>c (m21)</code></dt>
+ <dd>Vertical skewing.</dd>
+ <dt><code>d (m22)</code></dt>
+ <dd>Vertical scaling.</dd>
+ <dt><code>e (dx)</code></dt>
+ <dd>Horizontal moving.</dd>
+ <dt><code>f (dy)</code></dt>
+ <dd>Vertical moving.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.setTransform", "setTransform(a, b, c, d, e, f)")}}</dt>
+ <dd>Сбрасывает текущую матрицу преобразования, а затем вызывает<code>transform()</code> в соответствии с аргументами.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.resetTransform", "resetTransform()")}}</dt>
+ <dd>Сбрасывает текущую матрицу преобразования к значению по умолчанию. Аналогично вызову <code>ctx.setTransform(1, 0, 0, 1, 0, 0);</code></dd>
+</dl>
+
+<h3 id="Пример_использования_transform_и_setTransform">Пример использования <code>transform</code> и <code>setTransform</code></h3>
+
+<pre class="brush: js; highlight:[12,15] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ var sin = Math.sin(Math.PI / 6);
+ var cos = Math.cos(Math.PI / 6);
+ ctx.translate(100, 100);
+ var c = 0;
+ for (var i = 0; i &lt;= 12; i++) {
+ c = Math.floor(255 / 12 * i);
+ ctx.fillStyle = 'rgb(' + c + ', ' + c + ', ' + c + ')';
+ ctx.fillRect(0, 0, 100, 10);
+ ctx.transform(cos, sin, -sin, cos, 0, 0);
+ }
+
+ ctx.setTransform(-1, 0, 0, 1, 100, 100);
+ ctx.fillStyle = 'rgba(255, 128, 255, 0.5)';
+ ctx.fillRect(0, 50, 100, 100);
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="200" height="250"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Example_for_transform_and_setTransform", "230", "280", "https://mdn.mozillademos.org/files/255/Canvas_transform.png")}}</p>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/использование_изображений/index.html b/files/ru/web/api/canvas_api/tutorial/использование_изображений/index.html
new file mode 100644
index 0000000000..3ce4b8384e
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/использование_изображений/index.html
@@ -0,0 +1,333 @@
+---
+title: Использование изображений
+slug: Web/API/Canvas_API/Tutorial/Использование_изображений
+tags:
+ - Графика
+translation_of: Web/API/Canvas_API/Tutorial/Using_images
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Трансформации")}}</div>
+
+<div class="summary">
+<p>До сих пор мы создавали наши собственные фигуры и применяли стили к ним. Одна из самых впечатляющих функций {{HTMLElement("canvas")}} это возможность использования изображений. Они могут быть использованы для динамического композитинга фото или как фоны графиков, для спрайтов в играх, и так далее. Внешние изображения могут быть использованы в любых поддерживаемых браузером форматах, таких как PNG, GIF, или JPEG. Вы можете даже использовать изображение, произведенное другими canvas элементами на той же странице как источник!</p>
+</div>
+
+<p>Импортирование изображений в canvas в основном состоит из 2 этапов:</p>
+
+<ol>
+ <li>Дав ссылку на {{domxref("HTMLImageElement")}} объект или для другого canvas элемента как источник. Также можно использовать изображение дав ссылку на URL.</li>
+ <li>Для рисования изображения на canvas используется функция <code>drawImage()</code>.</li>
+</ol>
+
+<p>Давайте посмотрим как это сделать.</p>
+
+<h2 id="Использование_изображений_для_рисования">Использование изображений для рисования</h2>
+
+<p>Canvas API может использовать все перечисленные далее типы данных как источник изображения:</p>
+
+<dl>
+ <dt>{{domxref("HTMLImageElement")}}</dt>
+ <dd>Эти изображения созданы, используя конструктор <code>Image()</code>, также как все{{HTMLElement("img")}} элементы.</dd>
+ <dt>{{domxref("HTMLVideoElement")}}</dt>
+ <dd>Используя HTML {{HTMLElement("video")}} элемент как источник изображения захватывает текущий кадр из видео и использует его как изображение.</dd>
+ <dt>{{domxref("HTMLCanvasElement")}}</dt>
+ <dd>Вы можете использовать другой {{HTMLElement("canvas")}} элемент как источник изображения.</dd>
+</dl>
+
+<p>Эти источники совместно именуемые по типу {{domxref("CanvasImageSource")}}.</p>
+
+<p>Есть несколько способов, чтобы получить изображения для использования на холсте.</p>
+
+<h3 id="Использование_изображений_из_той_же_страницы">Использование изображений из той же страницы</h3>
+
+<p>Мы можем получить ссылку на изображение, на той же странице, на canvas с используя  один из способов: </p>
+
+<ul>
+ <li> {{domxref("document.images")}} коллекция</li>
+ <li>The {{domxref("document.getElementsByTagName()")}} метод</li>
+ <li>Если вы знаете id конкретного изображения, который вы хотите использовать, вы можете использовать {{domxref("document.getElementById ()")}}, чтобы получить это конкретное изображение</li>
+</ul>
+
+<h3 id="Использование_изображений_из_других_доменов">Использование изображений из других доменов</h3>
+
+<p>Использование {{htmlattrxref("crossorigin", "img")}} атрибута {{HTMLElement("img")}} элемент (отображается  {{domxref("HTMLImageElement.crossOrigin")}} свойства), вы можете запросить разрешение на загрузку другого домена для использования в <code>drawImage()</code>. Если хостинг домен разрешает доступ к междоменному изображению, то изображение может быть использовано в вашем canvas без  without tainting it;иначе он может испортить ваш canvas.</p>
+
+<h3 id="Использование_других_canvas_элементов">Использование других canvas элементов</h3>
+
+<p>Как и с обычными изображениями, мы можем получить доступ к другим canvas элементам используя либо {{domxref("document.getElementsByTagName()")}} либо {{domxref("document.getElementById()")}} метод. Проверьте, что в canvas источнике уже что-то нарисовано, прежде чем использовать его в целевом изображении canvas.</p>
+
+<p>Одним из удобных способов было бы использование второго элемента canvas  в качестве миниатюры другого большего изображения canvas.</p>
+
+<h3 id="Создание_изображений_с_нуля">Создание изображений с нуля</h3>
+
+<p>Другой способ это создать новые {{domxref("HTMLImageElement")}} объекты в нашем скрипте.  Чтобы это сделать, вы можете использовать удобный <code>Image()</code> конструктор:</p>
+
+<pre class="brush: js">var img = new Image(); // Создает новый элемент изображения
+img.src = 'myImage.png'; // Устанавливает путь
+</pre>
+
+<p>Когда этот скрипт выполнится, изображение начнет загружаться.</p>
+
+<p>Если вы попытаетесь вызвать функцию <code>drawImage()</code> перед тем как изображение загрузится, то скрипт ничего не сделает (или, в старых браузерах, может даже выдать исключение). Поэтому вам необходимо использовать событие load, чтобы вы не пытались сделать это прежде, чем изображение загрузится:</p>
+
+<pre class="brush: js">var img = new Image(); // Создает новое изображение
+img.addEventListener("load", function() {
+ // здесь выполняет drawImage функцию
+}, false);
+img.src = 'myImage.png'; // Устанавливает источник файла
+</pre>
+
+<p>Если вы используете только одно стороннее изображение, то этот метод может быть хорошим примером, но если нужно следить за несколькими изображениями, то необходимо придумать что-то более умное. Хотя поиски тактики проверки загрузки изображений выходят за пределы этого обучающего курса,  вы должны об этом помнить.</p>
+
+<h3 id="Вложение_изображения_с_помощью_данных_URL">Вложение изображения с помощью данных: URL</h3>
+
+<p>Другой возможный способ включить изображение это через <a class="external" href="/en-US/docs/Web/HTTP/data_URIs" rel="external" title="http://en.wikipedia.org/wiki/Data:_URL">data: url</a>. Data URLs позволяет вам полностью определить изображение как Base64 кодированную строку символов прямо в ваш код.</p>
+
+<pre class="brush: js">var img = new Image(); // Создает новый элемент img
+img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
+</pre>
+
+<p>Одним из преимуществ data URLs  это то что полученное изображение доступно сразу без других запросов туда-обратно на сервер. Другое потенциальное преимущество в том, что также можно инкапсулировать всё в одном файле все ваши <a href="/en-US/docs/Web/CSS" title="/en-US/docs/Web/CSS">CSS</a>, <a href="/en-US/docs/Web/JavaScript" title="/en-US/docs/Web/JavaScript">JavaScript</a>, <a href="/en-US/docs/Web/HTML" title="/en-US/docs/Web/HTML">HTML</a>, и изображения, что делает его более портативным в других местах.</p>
+
+<p>Некоторые недостатки этого метода в том что ваше изображение не кешировано, и для изображений с большим размером кодированние url может стать очень долгим процессом.</p>
+
+<h3 id="Использование_кадров_из_видео">Использование кадров из видео</h3>
+
+<p>Вы также можете использовать кадры из видео представленных {{HTMLElement("video")}} элементом (даже если видео не видно). Например, если у вас есть  {{HTMLElement("video")}} элемент с  ID "myvideo", вы можете сделать:</p>
+
+<pre class="brush: js">function getMyVideo() {
+ var canvas = document.getElementById('canvas');
+ if (canvas.getContext) {
+ var ctx = canvas.getContext('2d');
+
+ return document.getElementById('myvideo');
+ }
+}
+</pre>
+
+<p>Эта функция вернет {{domxref("HTMLVideoElement")}} объект для этого видео, который, как мы упоминали ранее, является одним из объектов, который можно использовать как <code>CanvasImageSource</code>.</p>
+
+<h2 id="Рисование_изображений">Рисование изображений</h2>
+
+<p>Как только мы получили ссылку на источник объекта изображения, мы можем использовать метод <code>drawImage()</code> для включения его в  canvas. Как мы увидим далее, метод <code>drawImage()</code> перегружен и у него есть несколько вариантов. В базовом варианте он выглядит как:</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}</dt>
+ <dd>Рисует  изображение, указанное в <code>CanvasImageSource</code> в координатах  (<code>x</code>, <code>y</code>).</dd>
+</dl>
+
+<div class="note">
+<p>SVG изображения должны указывать ширину и высоту корневого  &lt;svg&gt; элемента.</p>
+</div>
+
+<h3 id="Пример_Простой_линейный_график">Пример: Простой линейный график</h3>
+
+<p>В следующем примере, мы будем использовать внешнее изображение в качестве фона для небольшого линейного графика. Использование фонов может сделать ваш скрипт значительно меньше, потому что мы можем избежать необходимости писать код для создания фона. В этом примере мы используем только один образ, поэтому я использую обработчик событий изображения объекта загрузки для выполнения операторов рисования. <code>drawImage()</code> метод определяющий место фона с координатами (0, 0), которые привязаны к верхнему левому углу canvas.</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+   &lt;canvas id="canvas" width="180" height="150"&gt;&lt;/canvas&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+</div>
+
+<pre class="brush: js;highlight[5]">function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function(){
+    ctx.drawImage(img,0,0);
+    ctx.beginPath();
+    ctx.moveTo(30,96);
+    ctx.lineTo(70,66);
+    ctx.lineTo(103,76);
+    ctx.lineTo(170,15);
+    ctx.stroke();
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
+}</pre>
+
+<p>Получившийся график выглядит так:</p>
+
+<p>{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}</p>
+
+<h2 id="Изменение_размеров">Изменение размеров</h2>
+
+<p>Второй вариант метода <code>drawImage()</code> добавляет два новых параметра и позволяет разместить изображение в  canvas с измененными размерами.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y, width, height)")}}</dt>
+ <dd>Это добавляет параметр ширины и высоты, которые указывают до какого размера нужно изменить изображение при рисовании его в  canvas.</dd>
+</dl>
+
+<h3 id="Пример_Тайлинг_изображения">Пример: Тайлинг изображения</h3>
+
+<p>В этом примере, мы будем использовать изображение в качестве обоев и повторим его в canvas несколько раз. Это может быть сделано просто через цикл, располагая измененные изображения на разных позициях. В коде внизу, первый цикл <code>for</code> проходит по рядам. Второй цикл <code>for</code> проходит по колонкам. Изображение уменьшено на треть от реального размера, которое было  50x38 пикселей.</p>
+
+<div class="note">
+<p><strong>Обратите внимание</strong>: Изображения могут стать размытыми, при большом увеличении или зернистыми при значительном уменьшении. Возможно, лучше всего не изменять размеры изображения, если на них есть текст, который должен остаться читаемым. </p>
+</div>
+
+<div class="hidden">
+<pre class="brush: html">&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">function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function(){
+    for (var i=0;i&lt;4;i++){
+      for (var j=0;j&lt;3;j++){
+        ctx.drawImage(img,j*50,i*38,50,38);
+      }
+    }
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
+}</pre>
+
+<p>Получившийся рисунок canvas выглядит так:</p>
+
+<p>{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}</p>
+
+<h2 id="Нарезка">Нарезка</h2>
+
+<p>У третьего и последнего варианта метода <code>drawImage()</code> в дополнении к источнику изображения есть еще восемь параметров . Он позволяет нам вырезать кусок из изображения, затем изменить его размер и нарисовать его в canvas.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}</dt>
+ <dd>В данном изображении, эта функция берет фрагмент из изображения, в виде прямоугольника, левый верхний угол которого -  (<code>sx</code>, <code>sy</code>), ширина и высота -  <code>sWidth</code> и <code>sHeight</code> и рисует  в  canvas, располагая его в точке  (<code>dx</code>, <code>dy</code>) и изменяя его размер на указанные величины в  <code>dWidth</code> и <code>dHeight</code>.</dd>
+</dl>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/225/Canvas_drawimage.jpg" style="float: right; height: 290px; width: 300px;">Чтобы понять что  делает нарезка, можно посмотреть на изображение справа. Первые четыре параметра определяют местоположение и размер фрагмента исходного изображения.  Последние четыре параметра определяют прямоугольник, в который будет вписано изображение на целевом рисунке  canvas.</p>
+
+<p>Нарезка может быть полезным инструментом, когда вы захотите сделать композицию.  Вы могли бы собрать все элементы в одном файле изображения и использовать этот метод для создания композиции. Например, если вы захотите сделать график, вы могли бы сделать PNG изображение, содержащее все необходимые тексты в одном файле и в зависимости от ваших данных, могли бы достаточно просто изменять график. Другим преимуществом является то, что нет необходимости загружать каждое изображение по отдельности, получив возможность увеличить скорость загрузки.</p>
+
+<h3 id="Пример_Обрамление_изображения">Пример: Обрамление изображения</h3>
+
+<p>В этом примере, мы будем использовать того же носорога, что и в предыдущем примере, но мы отрежем его голову и включим ее в рамку. Изображение рамки это 24-х битный PNG, который включает падающую тень. Так как в 24-х битные PNG изображения включается полный 8-ми битный альфа-канал, в отличие от GIF и 8-битных PNG изображений, он может быть помещен в любой фон, без беспокойства о матовом цвете. </p>
+
+<pre class="brush: html">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+   &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
+ &lt;div style="display:none;"&gt;
+ &lt;img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227"&gt;
+ &lt;img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150"&gt;
+ &lt;/div&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<pre class="brush: js">function draw() {
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ // Рисуем фрагмент
+ ctx.drawImage(document.getElementById('source'),
+ 33, 71, 104, 124, 21, 20, 87, 104);
+
+ // Рисуем рамку
+ ctx.drawImage(document.getElementById('frame'),0,0);
+}</pre>
+
+<p>В этот раз мы применили другой способ загрузки изображения. Вместо загрузки методом создания новых {{domxref("HTMLImageElement")}} объектов, мы включили их как  {{HTMLElement("img")}} тэги прямо в наш HTML файл и из них выбрали изображения. Изображения скрыты с помощью  CSS свойства {{cssxref("display")}}, установленного в "none" для этих изображений.</p>
+
+<p>{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}</p>
+
+<p>Скрипт, сам по себе, очень простой. Каждому {{HTMLElement("img")}} присвоен атрибут ID, который  делает удобным их выбор с использованием {{domxref("document.getElementById()")}}. Потом мы просто используем функцию  <code>drawImage()</code>, чтобы из первого изображения вырезать фрагмент носорога и вставить его в canvas, затем рисуем рамку сверху, используя второй вызов функции <code>drawImage()</code>.</p>
+
+<h2 id="Пример_галереи_искусства">Пример галереи искусства</h2>
+
+<p>В последнем примере этой главы, мы построим небольшую галлерею искусств. Галерея состоит из таблицы, включающей несколько изображений. Когда страница загрузится,  {{HTMLElement("canvas")}}  элемент вставится в каждое изображение, а вокруг будет нарисована рамка. </p>
+
+<p>В этом случае, у каждого изображения фиксированная ширина и высота, такая же, как и у рамки нарисованной вокруг них.  Вы могли бы усовершенствовать этот скрипт так, чтобы он использовал ширину и высоту изображения, чтобы рамка идеально его окружила.</p>
+
+<p>Код ниже должен говорить сам за себя. Мы проходим циклом через {{domxref("document.images")}} контейнер и соответственно добавляем новые элементы  canvas. Возможно следует упомянуть для тех, кто не слишком хорошо знаком с DOM, что для этого используется {{domxref("Node.insertBefore")}} метод. <code>insertBefore()</code> это метод родительского узла (ячейки таблицы) элемента (изображения) перед которым мы хотим вставить наш новый узел  (элемент canvas).</p>
+
+<pre class="brush: html">&lt;html&gt;
+ &lt;body onload="draw();"&gt;
+    &lt;table&gt;
+      &lt;tr&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"&gt;&lt;/td&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"&gt;&lt;/td&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"&gt;&lt;/td&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"&gt;&lt;/td&gt;
+      &lt;/tr&gt;
+      &lt;tr&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"&gt;&lt;/td&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"&gt;&lt;/td&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"&gt;&lt;/td&gt;
+        &lt;td&gt;&lt;img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"&gt;&lt;/td&gt;
+      &lt;/tr&gt;
+    &lt;/table&gt;
+ &lt;img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150"&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>И сюда какую-нибудь CSS для украшения:</p>
+
+<pre class="brush: css">body {
+ background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A;
+ margin: 10px;
+}
+
+img {
+ display: none;
+}
+
+table {
+ margin: 0 auto;
+}
+
+td {
+ padding: 15px;
+}
+</pre>
+
+<p>Связывая все вместе  JavaScript рисует наши изображения в рамках:</p>
+
+<pre class="brush: js">function draw() {
+
+ // Цикл по всем изображениям
+ for (var i=0;i&lt;document.images.length;i++){
+
+ // Не добавляет canvas для изображения рамки
+ if (document.images[i].getAttribute('id')!='frame'){
+
+ // Создает элемент canvas
+ var canvas = document.createElement('canvas');
+ canvas.setAttribute('width',132);
+ canvas.setAttribute('height',150);
+
+ // Вставляет перед изображением
+ document.images[i].parentNode.insertBefore(canvas,document.images[i]);
+
+ var ctx = canvas.getContext('2d');
+
+ // Рисует изображение в canvas
+ ctx.drawImage(document.images[i],15,20);
+
+ // Добавляет рамку
+ ctx.drawImage(document.getElementById('frame'),0,0);
+ }
+ }
+}</pre>
+
+<p>{{EmbedLiveSample("Art_gallery_example", 725, 400)}}</p>
+
+<h2 id="Контроль_изменений_размеров_изображения">Контроль изменений размеров изображения</h2>
+
+<p>Как было отмечено ранее, изменение размеров изображений может привести к размытости или к шуму в процессе преобразования. Вы можете использовать контекст рисования {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} свойства, чтобы контролировать использование сглаживающего алгоритма, когда изменяющиеся изображения в вашем контексте. Обычно это свойство установлено в  <code>true</code>, означая, что изображения будут сглажены во время изменения размеров. Вы можете отключить это свойство так:</p>
+
+<pre class="brush: js">ctx.mozImageSmoothingEnabled = false;
+ctx.webkitImageSmoothingEnabled = false;
+ctx.msImageSmoothingEnabled = false;
+ctx.imageSmoothingEnabled = false;
+</pre>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/композиции/index.html b/files/ru/web/api/canvas_api/tutorial/композиции/index.html
new file mode 100644
index 0000000000..264cc7e544
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/композиции/index.html
@@ -0,0 +1,108 @@
+---
+title: Композиция и обрезка
+slug: Web/API/Canvas_API/Tutorial/Композиции
+tags:
+ - канвас
+translation_of: Web/API/Canvas_API/Tutorial/Compositing
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}</div>
+
+<div class="summary">
+<p>Во всех наших <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations">предыдущих примерах</a>, фигуры всегда были нарисованы одна поверх другой. Это более чем достаточно для большинства ситуаций, но это ограничивает порядок, в котором построены композиционные формы. Однако, мы можем изменить это поведение, установив свойство <code>globalCompositeOperation</code>. Кроме того, свойства <code>clip</code> позволяет скрыть нежелательные части формы.</p>
+</div>
+
+<h2 id="globalCompositeOperation" name="globalCompositeOperation"><code>globalCompositeOperation</code></h2>
+
+<p>Мы можем не только рисовать новые фигуры за существующие формы, но мы также можем использовать его, чтобы замаскировать определенные участки, очистить разделы от холста (не ограничивается прямоугольниками, как{{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} method does) и другое.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation = type")}}</dt>
+ <dd>Это задает Тип операции композиции для применения при разработке новых форм, где Тип является строкой, идентифицирующей, какие из двенадцати операций композитинг в использовании.</dd>
+</dl>
+
+<p>См.  <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing/Example">примеры компоновки</a> кода из следующих примеров.</p>
+
+<p>{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}}</p>
+
+<h2 id="Clipping_paths" name="Clipping_paths">Обрезка контуров</h2>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/209/Canvas_clipping_path.png" style="float: right;">Отсеченный контур похож на обычную форму холста, но он действует как маска, чтобы скрыть нежелательные части фигур. Это визуализируется на изображении справа. Форма красной звезды - наша отправочная дорожка. Все, что выходит за пределы этого пути, не будет нарисовано на холсте.</p>
+
+<p>Если мы сравниваем отсеченный контур со свойством <code>globalCompositeOperation</code> на изображении, мы видим два режима композитинга, которые достигают более или менее того же эффекта в исходном и исходном состоянии.   Наиболее важные различия между ними заключаются в том, что отсечение контура фактически  никогда не обращается к холсту и контур обрезки никогда не влияет добавление новых форм. Это делает обрезку контура идеальным для рисования нескольких фигур в ограниченной области.</p>
+
+<p>В главе о <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes" title="Web/Guide/HTML/Canvas_tutorial/Drawing_shapes#Drawing_paths">рисовании форм</a>, я назвал только <code>stroke()</code> и <code>fill()</code> методы, но есть третий способ можно использовать с контурами, так называемый <code>clip()</code>.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.clip", "clip()")}}</dt>
+ <dd>Преобразует текущий выстраиваемый контур в отсечённый контур.</dd>
+</dl>
+
+<p>Используйте <code>clip()</code> вместо <code>closePath()</code> для закрытия контура и его преобразования в отсечённый контур вместо создания заполняющего  или обрамляющего контура.</p>
+
+<p>По умолчанию элемент {{HTMLElement("canvas")}} использует отсечённый контур, который в точности совпадает по размеру с размером самого холста. Это означает, что никакого отсечения попросту не произойдёт.</p>
+
+<h3 id="A_clip_example" name="A_clip_example">Пример обрезки</h3>
+
+<p>В этом примере мы будем использовать круговую обрезку контура, чтобы ограничить рисование набора случайных звезд определенной областью.</p>
+
+<pre class="brush: js;highlight[9]">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ ctx.fillRect(0, 0, 150, 150);
+ ctx.translate(75, 75);
+
+ // Create a circular clipping path
+ ctx.beginPath();
+ ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
+ ctx.clip();
+
+ // draw background
+ var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
+ lingrad.addColorStop(0, '#232256');
+ lingrad.addColorStop(1, '#143778');
+
+ ctx.fillStyle = lingrad;
+ ctx.fillRect(-75, -75, 150, 150);
+
+ // draw stars
+ for (var j = 1; j &lt; 50; j++) {
+ ctx.save();
+ ctx.fillStyle = '#fff';
+ ctx.translate(75 - Math.floor(Math.random() * 150),
+ 75 - Math.floor(Math.random() * 150));
+ drawStar(ctx, Math.floor(Math.random() * 4) + 2);
+ ctx.restore();
+ }
+
+}
+
+function drawStar(ctx, r) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(r, 0);
+ for (var i = 0; i &lt; 9; i++) {
+ ctx.rotate(Math.PI / 5);
+ if (i % 2 === 0) {
+ ctx.lineTo((r / 0.525731) * 0.200811, 0);
+ } else {
+ ctx.lineTo(r, 0);
+ }
+ }
+ ctx.closePath();
+ ctx.fill();
+ ctx.restore();
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">draw();</pre>
+</div>
+
+<p>В первых нескольких строках кода мы рисуем черный прямоугольник размером с холстом в качестве фона, а затем переводим начало координат в центр. Затем мы создаем круговой обтравочный контур, рисуя дугу и вызывающий <code>clip()</code>. Обрезанные контуры также являются частью состояния сохранения холста. Если бы мы хотели сохранить исходный обтравочный контур, мы могли бы сохранить состояние холста перед созданием нового.</p>
+
+<p>Все, что нарисовано после создания отсеченного контура, появится только внутри этого пути. Вы можете видеть это четко в линейном градиенте, который нарисован далее. После этого набирается набор из 50 случайно расположенных и масштабированных звезд, используя <code>drawStar()</code>. Снова звезды появляются только в пределах определенного обтравочного контура.</p>
+
+<p>{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}</p>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/основы_анимации/index.html b/files/ru/web/api/canvas_api/tutorial/основы_анимации/index.html
new file mode 100644
index 0000000000..a47b8b734e
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/основы_анимации/index.html
@@ -0,0 +1,308 @@
+---
+title: Простые анимации
+slug: Web/API/Canvas_API/Tutorial/Основы_анимации
+tags:
+ - HTML
+ - HTML5
+ - Графика
+ - Обучение
+ - Средний уровень
+ - Холст
+translation_of: Web/API/Canvas_API/Tutorial/Basic_animations
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</div>
+
+<div class="summary">
+<p>Поскольку для управления элементами {{HTMLElement ("canvas")}} используется JavaScript, не составляет труда сделать (интерактивные) анимации. В этой главе мы рассмотрим, как делаются некоторые базовые анимации.</p>
+</div>
+
+<p>Вероятно, самым большим ограничением является то, что когда фигура нарисована, её уже нельзя двигать. Чтобы изобразить движение нам нужно перерисовать фигуру и всё, что было нарисовано до неё. Перерисовка сложных кадров занимает много времени, и производительность сильно зависит от скорости компьютера, на котором она выполняется.</p>
+
+<h2 id="Basic_animation_steps" name="Basic_animation_steps">Основные шаги анимации</h2>
+
+<p>Ниже перечислены необходимые шаги для того, чтобы нарисовать кадр:</p>
+
+<ol>
+ <li><strong>Очистить canvas</strong><br>
+ Если фигура, которую вы собираетесь нарисовать, не занимает всю площадь canvas (как фон, например), то всё что было нарисовано ранее необходимо стереть. Проще всего это сделать при помощи метода {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}.</li>
+ <li><strong>Сохранить изначальное состояние canvas</strong><br>
+ Если вы изменяете любые настройки (такие как стили, трансформации и т.п.), которые затрагивают состояние canvas и вы хотите убедиться, что оригинальное состояние используется каждый раз, когда был отрисован кадр, то вам следует сохранить это оригинальное состояние.</li>
+ <li><strong>Нарисовать анимированные фигуры</strong><br>
+ Шаг на котором вы собственно отрисовываете кадр.</li>
+ <li><strong>Восстановить состояние canvas</strong><br>
+ Если вы сохраняли состояние, восстановите его, прежде чем отрисовывать новый кадр.</li>
+</ol>
+
+<h2 id="Controlling_an_animation" name="Controlling_an_animation">Управление анимацией</h2>
+
+<p>Фигуры отрисовываются на canvas либо напрямую — при помощи методов canvas, либо с помощью сторонних функций. В нормальной ситуации результат станет виден на canvas после окончания выполнения скрипта. К примеру, цикл for использовать для анимации нельзя. </p>
+
+<p>Это значит, нужен способ выполнения функций отрисовки через интервалы времени. Есть два способа для управления такой анимацией.</p>
+
+<h3 id="Запланированные_обновления">Запланированные обновления</h3>
+
+<p>Первый — это функции {{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}}, и {{domxref("window.requestAnimationFrame()")}}, которые могут быть использованы для вызова некоторой функции, через заданный промежуток времени.</p>
+
+<dl>
+ <dt>{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}</dt>
+ <dd>Начинает периодически исполнять функцию <code>function</code> каждые <code>delay</code> миллисекунд.</dd>
+ <dt>{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}</dt>
+ <dd>Запускает выполнение указанной функции <code>function</code> через <code>delay</code> миллисекунд.</dd>
+ <dt>{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}</dt>
+ <dd>Сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает, чтобы браузер вызвал указанную функцию <code>callback</code> для обновления анимации перед следующей перерисовкой.</dd>
+</dl>
+
+<p>Если вы не планируете никакого взаимодействия с пользователем, вы можете использовать функцию <code>setInterval()</code> , которая многократно выполняет, предоставленный ей код. Если же вы планиуете создать игру, в которой контроль анимации осуществляется мышью или клавиатурой, то необходимо использовать  <code>setTimeout()</code>. Установив {{domxref("EventListener")}}, вы можете перехватываете любые действия пользователя и запустить соответствующие функции анимации.</p>
+
+<div class="note">
+<p>В примерах ниже мы будем использовать функцию {{domxref("window.requestAnimationFrame()")}} для контроля анимации. Функция <code>requestAnimationFrame</code> является более эффективной для создания анимации, так как новая итерация вызывается, когда система готова к отрисовке нового кадра. Количество вызовов в секунду примерно равно 60 и уменьшается, когда вкладка неактивна. Для более подробного изучения цикла анимации, особенно для игр, прочитайте статью <a href="/en-US/docs/Games/Anatomy">Анатомия видеоигр </a>В <a href="/en-US/docs/Games">Зоне разработке игр</a>.</p>
+</div>
+
+<h2 id="Анимированная_солнечная_система">Анимированная солнечная система</h2>
+
+<p>В этом примере анимируется небольшая модель солнечной системы.</p>
+
+<pre class="brush: js">var sun = new Image();
+var moon = new Image();
+var earth = new Image();
+function init(){
+ sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
+ moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
+ earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
+ window.requestAnimationFrame(draw);
+}
+
+function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.clearRect(0,0,300,300); // clear canvas
+
+ ctx.fillStyle = 'rgba(0,0,0,0.4)';
+ ctx.strokeStyle = 'rgba(0,153,255,0.4)';
+ ctx.save();
+ ctx.translate(150,150);
+
+ // Earth
+ var time = new Date();
+ ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
+ ctx.translate(105,0);
+ ctx.fillRect(0,-12,50,24); // Shadow
+ ctx.drawImage(earth,-12,-12);
+
+ // Moon
+ ctx.save();
+ ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
+ ctx.translate(0,28.5);
+ ctx.drawImage(moon,-3.5,-3.5);
+ ctx.restore();
+
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
+ ctx.stroke();
+
+ ctx.drawImage(sun,0,0,300,300);
+
+ window.requestAnimationFrame(draw);
+}
+
+init();
+</pre>
+
+<div class="hidden">
+<pre class="brush: html">&lt;canvas id="canvas" width="300" height="300"&gt;&lt;/canvas&gt;</pre>
+</div>
+
+<p>{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}</p>
+
+<h2 id="Анимированные_часы">Анимированные часы</h2>
+
+<p>В этом примере создаются анимированные часы, показывающие правильное время.</p>
+
+<pre class="brush: js">function clock(){
+ var now = new Date();
+ var ctx = document.getElementById('canvas').getContext('2d');
+ ctx.save();
+ ctx.clearRect(0,0,150,150);
+ ctx.translate(75,75);
+ ctx.scale(0.4,0.4);
+ ctx.rotate(-Math.PI/2);
+ ctx.strokeStyle = "black";
+ ctx.fillStyle = "white";
+ ctx.lineWidth = 8;
+ ctx.lineCap = "round";
+
+ // Hour marks
+ ctx.save();
+ for (var i=0;i&lt;12;i++){
+ ctx.beginPath();
+ ctx.rotate(Math.PI/6);
+ ctx.moveTo(100,0);
+ ctx.lineTo(120,0);
+ ctx.stroke();
+ }
+ ctx.restore();
+
+ // Minute marks
+ ctx.save();
+ ctx.lineWidth = 5;
+ for (i=0;i&lt;60;i++){
+ if (i%5!=0) {
+ ctx.beginPath();
+ ctx.moveTo(117,0);
+ ctx.lineTo(120,0);
+ ctx.stroke();
+ }
+ ctx.rotate(Math.PI/30);
+ }
+ ctx.restore();
+
+ var sec = now.getSeconds();
+ var min = now.getMinutes();
+ var hr = now.getHours();
+ hr = hr&gt;=12 ? hr-12 : hr;
+
+ ctx.fillStyle = "black";
+
+ // write Hours
+ ctx.save();
+ ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
+ ctx.lineWidth = 14;
+ ctx.beginPath();
+ ctx.moveTo(-20,0);
+ ctx.lineTo(80,0);
+ ctx.stroke();
+ ctx.restore();
+
+ // write Minutes
+ ctx.save();
+ ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(-28,0);
+ ctx.lineTo(112,0);
+ ctx.stroke();
+ ctx.restore();
+
+ // Write seconds
+ ctx.save();
+ ctx.rotate(sec * Math.PI/30);
+ ctx.strokeStyle = "#D40000";
+ ctx.fillStyle = "#D40000";
+ ctx.lineWidth = 6;
+ ctx.beginPath();
+ ctx.moveTo(-30,0);
+ ctx.lineTo(83,0);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0,0,10,0,Math.PI*2,true);
+ ctx.fill();
+ ctx.beginPath();
+ ctx.arc(95,0,10,0,Math.PI*2,true);
+ ctx.stroke();
+ ctx.fillStyle = "rgba(0,0,0,0)";
+ ctx.arc(0,0,3,0,Math.PI*2,true);
+ ctx.fill();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.lineWidth = 14;
+ ctx.strokeStyle = '#325FA2';
+ ctx.arc(0,0,142,0,Math.PI*2,true);
+ ctx.stroke();
+
+ ctx.restore();
+
+ window.requestAnimationFrame(clock);
+}
+
+window.requestAnimationFrame(clock);</pre>
+
+<div class="hidden">
+<pre class="brush: html">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+</div>
+
+<p>{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}</p>
+
+<h2 id="Зацикленная_панорама">Зацикленная панорама</h2>
+
+<p>В этом примере панорама прокручивается слева направо. Мы используем <a href="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg" title="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg">фото национального парка Йосемити</a> взятое из Википедии, но вы можете использовать любое изображение, большее элемента canvas.</p>
+
+<pre class="brush: js">var img = new Image();
+
+// User Variables - customize these to change the image being scrolled, its
+// direction, and the speed.
+
+img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
+var CanvasXSize = 800;
+var CanvasYSize = 200;
+var speed = 30; //lower is faster
+var scale = 1.05;
+var y = -4.5; //vertical offset
+
+// Main program
+
+var dx = 0.75;
+var imgW;
+var imgH;
+var x = 0;
+var clearX;
+var clearY;
+var ctx;
+
+img.onload = function() {
+ imgW = img.width*scale;
+ imgH = img.height*scale;
+ if (imgW &gt; CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
+ if (imgW &gt; CanvasXSize) { clearX = imgW; } // image larger than canvas
+ else { clearX = CanvasXSize; }
+ if (imgH &gt; CanvasYSize) { clearY = imgH; } // image larger than canvas
+ else { clearY = CanvasYSize; }
+ //Get Canvas Element
+ ctx = document.getElementById('canvas').getContext('2d');
+ //Set Refresh Rate
+ return setInterval(draw, speed);
+}
+
+function draw() {
+ //Clear Canvas
+ ctx.clearRect(0,0,clearX,clearY);
+ //If image is &lt;= Canvas Size
+ if (imgW &lt;= CanvasXSize) {
+ //reset, start from beginning
+ if (x &gt; (CanvasXSize)) { x = 0; }
+ //draw aditional image
+ if (x &gt; (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
+ }
+ //If image is &gt; Canvas Size
+ else {
+ //reset, start from beginning
+ if (x &gt; (CanvasXSize)) { x = CanvasXSize-imgW; }
+ //draw aditional image
+ if (x &gt; (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
+ }
+ //draw image
+ ctx.drawImage(img,x,y,imgW,imgH);
+ //amount to move
+ x += dx;
+}
+</pre>
+
+<p>Заметьте, что ширина и высота должны совпадать  со значениями <code>CanvasXZSize</code> и <code>CanvasYSize</code>.</p>
+
+<pre class="brush: html">&lt;canvas id="canvas" width="800" height="200"&gt;&lt;/canvas&gt;</pre>
+
+<p>{{EmbedLiveSample("A_looping_panorama", "830", "230")}}</p>
+
+<h2 id="Other_examples" name="Other_examples">Другие примеры</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Web/API/Canvas_API/A_basic_ray-caster" title="/en-US/docs/Web/Guide/HTML/A_basic_ray-caster">A basic ray-caster</a></dt>
+ <dd>Хороший пример того, как сделать управляемую анимацию с клавиатуры.</dd>
+ <dt><a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Advanced_animations">Advanced animations</a></dt>
+ <dd>Мы рассмотрим некоторые продвинутые методы анимации и физику в следующей главе.</dd>
+</dl>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/применение_стилей_и_цветов/index.html b/files/ru/web/api/canvas_api/tutorial/применение_стилей_и_цветов/index.html
new file mode 100644
index 0000000000..2c9eeaae78
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/применение_стилей_и_цветов/index.html
@@ -0,0 +1,726 @@
+---
+title: Применение стилей и цветов
+slug: Web/API/Canvas_API/Tutorial/Применение_стилей_и_цветов
+translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}</div>
+
+<div class="summary">
+<p>В главе о <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes" title="Web/Guide/HTML/Canvas_tutorial/Drawing_shapes">рисовании фигур</a>, <span id="result_box" lang="ru"><span>мы использовали</span></span><span 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>.</span></span> <span id="result_box" lang="ru"><span class="hps">Здесь</span> <span class="hps">мы будем исследовать</span> <span class="hps">опции </span></span>canvas<span 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 id="result_box" lang="ru"><span class="hps">Вы узнаете, как</span> <span class="hps">добавлять различные</span> <span class="hps">цвета,</span> <span class="hps">стили линий</span><span>, градиенты</span><span>, узоры</span> <span class="hps">и тени</span> <span class="hps">вашим рисункам</span><span>.</span></span></p>
+</div>
+
+<h2 id="Colors" name="Colors">Цвета</h2>
+
+<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><span id="result_box" lang="ru"><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></span> <code>fillStyle</code> и <code>strokeStyle</code>.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}</dt>
+ <dd>Устанавливает стиль для фона фигур.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}</dt>
+ <dd>Устанавливает стиль контура фигуры. </dd>
+</dl>
+
+<p><em><code>color </code></em>может быть цветом, (<code>строка, представленная в</code> CSS {{cssxref("&lt;color&gt;")}}), градиентом или паттерном. Градиенты и паттерны мы рассмотрим позже. По умолчанию цвет фона и контура  — черный (значение CSS цвета  <code>#000000</code>).</p>
+
+<div class="note">
+<p><strong>На заметку:</strong> Когда вы устанавливаете  значения <code>strokeStyle</code> и/или <code>fillStyle</code>, то новое значение становится стандартным для всех фигур, которые будут нарисованы с этого момента. Когда вам нужен другой цвет, вы должны перезаписать значение в <code>fillStyle</code> или в <code>strokeStyle</code> для каждой фигуры.</p>
+</div>
+
+<p>Чтобы строка <em><code>color </code></em>считалась валидной, она должна соответствовать CSS {{cssxref("&lt;color&gt;")}}. Далее приведены примеры того, как можно по-разному задать один и тот же цвет. </p>
+
+<pre class="brush: js notranslate">// these all set the fillStyle to 'orange'
+
+ctx.fillStyle = "orange";
+ctx.fillStyle = "#FFA500";
+ctx.fillStyle = "rgb(255,165,0)";
+ctx.fillStyle = "rgba(255,165,0,1)";
+</pre>
+
+<h3 id="Пример_fillStyle">Пример <code>fillStyle</code></h3>
+
+<p>В этом примере мы опять воспользуемся двойным циклом, чтобы нарисовать сетку из прямоугольников, каждый из которых имеет свой цвет. Окончательное изображение должно иметь вид, как показано на скриншоте. Здесь не происходит ничего сверхъестественного. Мы используем две переменные <code>i</code> и <code>j</code> для генерации уникального RGB цвета для каждого квадрата и изменяем только красные и зеленые значения. Синий канал представляет собой фиксированное значение. Путем изменения каналов вы можете генерировать всю палитру. Увеличив количество шагов вы можете достигнуть такого вида палитры, какая используется в Photoshop.</p>
+
+<pre class="brush: js;highlight[5,6] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ for (var i=0;i&lt;6;i++){
+ for (var j=0;j&lt;6;j++){
+ ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' +
+ Math.floor(255-42.5*j) + ',0)';
+ ctx.fillRect(j*25,i*25,25,25);
+ }
+ }
+}</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>Результат выглядит так:</p>
+
+<p>{{EmbedLiveSample("Пример_fillStyle", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}</p>
+
+<h3 id="Пример_strokeStyle">Пример <code>strokeStyle</code></h3>
+
+<p>Этот пример похож на предыдущий, но мы используем свойство <code>strokeStyle</code> чтобы изменить цвета очертаний фигур. Так же мы используем метод <code>arc()</code> для рисования окружностей вместо квадратов.</p>
+
+<pre class="brush: js;highlight[5,6] notranslate"> function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ for (var i=0;i&lt;6;i++){
+ for (var j=0;j&lt;6;j++){
+ ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +
+ Math.floor(255-42.5*j) + ')';
+ ctx.beginPath();
+ ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
+ ctx.stroke();
+ }
+ }
+ }
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>Результат выглядит так:</p>
+
+<p>{{EmbedLiveSample("Пример_strokeStyle", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}</p>
+
+<h2 id="Transparency" name="Transparency">Прозрачность</h2>
+
+<p>В дополнении к рисованию непрозрачных фигур, мы также можем рисовать прозрачные (полупрозрачные) фигуры.  Это делается через установку свойства <code>globalAlpha</code> или задачи полупрозрачного цвета фона или контура.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}</dt>
+ <dd>Для применения, указывается значения прозрачности для всех будущих фигур, что будут нарисованы на canvas. Значение полупрозрачности могут быть между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность). Значение 1.0 (полная непрозрачность) установлено по умолчанию.</dd>
+</dl>
+
+<p>Свойство <code>globalAlpha</code> может быть использовано, если вы хотите рисовать формы с одинаковой прозрачностью, но в иной ситуации, обычно устанавливают прозрачность индивидуально к каждой форме, когда указывают их цвет.</p>
+
+<p>Так как свойства <code>strokeStyle</code> и <code>fillStyle</code> принимают цветовые значения rgba через CSS, мы можем использовать следующее обозначение  для назначения прозрачных цветов.</p>
+
+<pre class="brush: js notranslate">// Assigning transparent colors to stroke and fill style
+
+ctx.strokeStyle = "rgba(255,0,0,0.5)";
+ctx.fillStyle = "rgba(255,0,0,0.5)";
+</pre>
+
+<p>Функция <code>rgba()</code> похожа на функцию <code>rgb()</code>, но имеет один дополнительный параметр. Последний параметр устанавливает значение прозрачности для конкретного цвета. Действующий диапозон значений находится между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность).</p>
+
+<h3 id="Пример_globalAlpha">Пример <code>globalAlpha</code></h3>
+
+<p>В данном примере мы нарисуем фон и четыре квадрата с различными цветами.  Сверху изображения будет выведен набор полупрозрачных кругов. Установим свойство <code>globalAlpha</code> значением 0.2, которое будет использовано для всех последующих форм. Каждый шаг цикла рисует круг с большим радиусом. По окончанию получим радиальный градиент. Накладывая еще больше кругов друг на друга, мы фактически сможем уменьшить прозрачность ранее нарисованных кругов. Увеличив счетчик итераций, при этом рисуя еще круги, мы сможем добиться исчезновение центра изображения.</p>
+
+<pre class="brush: js;highlight[15] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ // фон изображения
+ ctx.fillStyle = '#FD0';
+ ctx.fillRect(0,0,75,75);
+ ctx.fillStyle = '#6C0';
+ ctx.fillRect(75,0,75,75);
+ ctx.fillStyle = '#09F';
+ ctx.fillRect(0,75,75,75);
+ ctx.fillStyle = '#F30';
+ ctx.fillRect(75,75,75,75);
+ ctx.fillStyle = '#FFF';
+
+ // устанавливаем значение прозрачности
+ ctx.globalAlpha = 0.2;
+
+ // Рисуем полупрозрачные круги
+ for (i=0;i&lt;7;i++){
+ ctx.beginPath();
+ ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
+ ctx.fill();
+ }
+}</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Пример_globalAlpha", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}</p>
+
+<h3 id="Пример_использования_rgba">Пример использования <code>rgba()</code></h3>
+
+<p>В этом втором примере мы делаем что-то похожее на предыдущее, но вместо рисования кругов друг над другом, я рисовал маленькие прямоугольники с увеличением непрозрачности. Использование <code>rgba()</code> добавляет контроля и гибкости, поскольку мы можем индивидуально настраивать стиль заливки и штриха.</p>
+
+<pre class="brush: js;highlight[16] notranslate">function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Нарисовать фон
+  ctx.fillStyle = 'rgb(255,221,0)';
+  ctx.fillRect(0,0,150,37.5);
+  ctx.fillStyle = 'rgb(102,204,0)';
+  ctx.fillRect(0,37.5,150,37.5);
+  ctx.fillStyle = 'rgb(0,153,255)';
+  ctx.fillRect(0,75,150,37.5);
+  ctx.fillStyle = 'rgb(255,51,0)';
+  ctx.fillRect(0,112.5,150,37.5);
+
+  // Нарисовать полупрозрачные прямоугольники
+  for (var i=0;i&lt;10;i++){
+    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
+    for (var j=0;j&lt;4;j++){
+      ctx.fillRect(5+i*14,5+j*37.5,14,27.5);
+    }
+  }
+}</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Пример_использования_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}</p>
+
+<h2 id="Line_styles" name="Line_styles">Стили линий</h2>
+
+<p>Есть несколько свойств, которые позволяют нам стилизовать линии.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}</dt>
+ <dd>Устанавливает ширину линий, рисуемых в будущем.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}</dt>
+ <dd>Устанавливает внешний вид концов линий.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}</dt>
+ <dd>Устанавливает внешний вид «углов», где встречаются линии.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}</dt>
+ <dd>Устанавливает ограничение на митру, когда две линии соединяются под острым углом, чтобы вы могли контролировать её толщину.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}</dt>
+ <dd>Возвращает текущий массив тире штриховки, содержащий четное число неотрицательных чисел.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}</dt>
+ <dd>Устанавливает текущий пунктир линии.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}</dt>
+ <dd>Указывает, где следует начинать тире массива в строке.</dd>
+</dl>
+
+<p>Вы лучше поймете, что они делают, глядя на приведенные ниже примеры.</p>
+
+<h3 id="Пример_lineWidth">Пример <code>lineWidth</code></h3>
+
+<p>Это свойство задает толщину текущей строки. Значения должны быть положительными. По умолчанию для этого значения установлено 1.0 единицы.</p>
+
+<p>Ширина линии - это толщина хода, центрированного по данному пути. Другими словами, область, которая нарисована, простирается до половины ширины линии по обе стороны пути. Поскольку координаты холста не напрямую ссылаются на пиксели, особое внимание следует уделять получению четких горизонтальных и вертикальных линий.</p>
+
+<p>В приведенном ниже примере 10 прямых линий рисуются с увеличением ширины линий. Линия в крайнем левом углу - 1.0 единицы. Тем не менее, толщина левой и всех других линий нечетной ширины не выглядят четкими из-за позиционирования пути.</p>
+
+<pre class="brush: js;highlight[4] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ for (var i = 0; i &lt; 10; i++){
+ ctx.lineWidth = 1+i;
+ ctx.beginPath();
+ ctx.moveTo(5+i*14,5);
+ ctx.lineTo(5+i*14,140);
+ ctx.stroke();
+ }
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Пример_lineWidth", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}</p>
+
+<p>Получение четких строк требует понимания путей сглаживания. На рисунках ниже представлена сетка координат холста. Квадраты между сетками являются фактическими экранными пикселями. В первом изображении сетки ниже прямоугольник от (2, 1) до (5, 5) заполняется. Вся область между ними (светло-красный) падает на границы пикселей, поэтому полученный заполненный прямоугольник будет иметь четкие края.</p>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/201/Canvas-grid.png"></p>
+
+<p>Если вы рассмотрите путь от (3, 1) до (3, 5) с толщиной строки <code>1.0</code>, вы получите ситуацию во втором изображении. Фактическая заполняемая область, (синяя), распространяется только наполовину в пикселях по обе стороны пути. Приблизительно это означает, что частично затенённые пиксели приводят к заполнению всей области (светло-голубой и синей) цветом, только наполовину темным, чем фактический цвет штриха. Это то, что происходит с линией шириной <code>1.0</code> в предыдущем примере кода.</p>
+
+<p>Чтобы исправить это, вы должны быть более точными при создании пути. Зная, что линия шириной <code>1.0</code> занимает половину единицы по обе стороны пути, создание пути от (3.5, 1) до (3.5, 5) приведёт к ситуации в третьем изображении - ширина линии <code>1.0</code> закончится верно, точно заполняя вертикальную линию с одним пикселем.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Имейте в виду, что в нашем примере с вертикальной линией позиция Y по-прежнему ссылается на целочисленную позицию сетки - иначе мы увидели бы пиксели с половинным охватом в конечных точках (также обратите внимание, что это поведение зависит от текущего стиля <code>lineCap</code>,  значение по умолчанию - <code>butt</code>; вы можете вычислить согласованные штрихи с полупиксельными координатами для линий с нечетной шириной, установив стиль <code>lineCap</code> в <code>square</code>, чтобы внешняя граница вокруг конечной точки линии автоматически расширялась, охватывая весь пиксель в точку).</p>
+
+<p>Также обратите внимание, что затронуты только начальные и конечные  точки пути: если путь закрыт с помощью <code>closePath()</code>, - нет начальной и конечной точки; вместо этого все конечные точки в пути подключены к их прикрепленному предыдущему и следующему сегментам и при текущей настройке стиля <code>lineJoin</code> в значении по умолчанию - <code>miter</code>, с эффектом автоматического расширения внешних границ подключенных сегментов до их точки пересечения - обработанный ход будет точно покрывать полные пиксели с центром в каждой конечной точке, если эти связанные сегменты горизонтальны и/или вертикальны). См. следующие два раздела, демонстрирующие эти дополнительные стили.</p>
+</div>
+
+<p>Для линий с четной шириной каждая половина заканчивается как целое количество пикселей, поэтому вам нужен путь, который находится между пикселями (то есть (3,1) - (3,5)), вместо середины пикселей.</p>
+
+<p>Хотя это и необычно, когда изначально работаешь с масштабируемой 2D-графикой, обращая внимание на сетку пикселей и положение путей, но вы убедитесь, что ваши рисунки будут выглядеть правильно, независимо от масштабирования или любых других преобразований. Вертикальная линия ширины 1,0, построенная таким образом, станет четкой 2-пиксельной линией при увеличении на 2 и появится в правильном положении.</p>
+
+<h3 id="Пример_lineCap">Пример <code>lineCap</code></h3>
+
+<p>Свойство <code>lineCap</code> определяет, как выводятся конечные точки каждой строки. Для этого свойства есть три возможных значения: <code>butt</code>, <code>round</code> и <code>square</code>. По умолчанию для этого свойства установлено значение <code>butt</code>.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/236/Canvas_linecap.png" style="float: right; height: 190px; width: 190px;"></p>
+
+<dl>
+ <dt><code>butt</code></dt>
+ <dd>Концы линий соответствуют крайним точкам.</dd>
+ <dt><code>round</code></dt>
+ <dd>Концы линий округлены.</dd>
+ <dt><code>square</code></dt>
+ <dd>Концы линий описаны квадратом с равной шириной и половиной высоты толщины линии.</dd>
+</dl>
+
+<p>В этом примере мы проведем три строки, каждая из которых имеет другое значение для свойства <code>lineCap</code>. Я также добавил два руководства, чтобы увидеть точные различия между ними. Каждая из этих линий начинается и заканчивается именно на этих направляющих.</p>
+
+<p>Строка слева использует <code>butt</code> опцию по умолчанию. Вы заметите, что она полностью очищена от направляющих. Второй вариант -  <code>round</code> опция. Это добавляет полукруг к концу, который имеет радиус, равный половине ширины линии. Строка справа использует <code>square</code> опцию. Это добавляет поле с равной шириной и половиной высоты толщины линии.</p>
+
+<pre class="brush: js;highlight[18] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ var lineCap = ['butt','round','square'];
+
+ // Draw guides
+ ctx.strokeStyle = '#09f';
+ ctx.beginPath();
+ ctx.moveTo(10,10);
+ ctx.lineTo(140,10);
+ ctx.moveTo(10,140);
+ ctx.lineTo(140,140);
+ ctx.stroke();
+
+ // Draw lines
+ ctx.strokeStyle = 'black';
+ for (var i=0;i&lt;lineCap.length;i++){
+ ctx.lineWidth = 15;
+ ctx.lineCap = lineCap[i];
+ ctx.beginPath();
+ ctx.moveTo(25+i*50,10);
+ ctx.lineTo(25+i*50,140);
+ ctx.stroke();
+ }
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Пример_lineCap", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}</p>
+
+<h3 id="Пример_lineJoin">Пример <code>lineJoin</code></h3>
+
+<p>Свойство <code>lineJoin</code> определяет, как соединяются два сегмента (линий, дуг или кривых) с ненулевой длиной в форме (вырожденные сегменты с нулевой длиной, заданные конечные точки и контрольные точки находятся точно в том же положении - пропущены).</p>
+
+<p>Для этого свойства есть три возможных значения: <code>round</code>, <code>bevel</code> и <code>miter</code>. По умолчанию для этого свойства установлено значение <code>miter</code>. Обратите внимание, что настройка <code>lineJoin</code> не действует, если два связанных сегмента имеют одно и то же направление, потому что в этом случае не будет добавлена ​​область соединения.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/237/Canvas_linejoin.png" style="float: right; height: 190px; width: 190px;"></p>
+
+<dl>
+ <dt><code>round</code></dt>
+ <dd>Радиус заполняемой части для скругленных углов равен половине ширины линии. центр этого радиуса совпадает с концами подключенных сегментов.</dd>
+ <dt><code>bevel</code></dt>
+ <dd>Заполняет дополнительную треугольную область между общей конечной точкой подключенных сегментов и отдельными внешними прямоугольными углами каждого сегмента. </dd>
+ <dt><code>miter</code></dt>
+ <dd>Подключенные сегменты соединяются путем расширения их внешних краев для соединения в одной точке с эффектом заполнения дополнительной области в форме пастилки. Эта настройка выполняется с помощью свойства <code>miterLimit</code>, которое объясняется ниже.</dd>
+</dl>
+
+<p>В приведенном ниже примере показаны три разных пути, демонстрирующие каждый из этих трех свойств <code>lineJoin</code>; результат - выше. </p>
+
+<pre class="brush: js;highlight[6] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ var lineJoin = ['round','bevel','miter'];
+ ctx.lineWidth = 10;
+ for (var i=0;i&lt;lineJoin.length;i++){
+ ctx.lineJoin = lineJoin[i];
+ ctx.beginPath();
+ ctx.moveTo(-5,5+i*40);
+ ctx.lineTo(35,45+i*40);
+ ctx.lineTo(75,5+i*40);
+ ctx.lineTo(115,45+i*40);
+ ctx.lineTo(155,5+i*40);
+ ctx.stroke();
+ }
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Пример_lineJoin", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}</p>
+
+<h3 id="Демонстрация_свойства_miterLimit">Демонстрация свойства <code>miterLimit</code></h3>
+
+<p>Как вы видели в предыдущем примере, при объединении двух строк с опцией <code>miter</code> внешние края двух соединительных линий расширены до точки, где они встречаются. Для линий, которые находятся под большими углами друг с другом, эта точка находится недалеко от внутренней точки соединения. Однако, поскольку углы между каждой линией уменьшаются, расстояние (длина меча) между этими точками увеличивается экспоненциально.</p>
+
+<p>Свойство <code>miterLimit</code> определяет, как далеко можно установить внешнюю точку соединения из внутренней точки подключения. Если две линии превышают это значение, вместо этого получается привязка конуса. Обратите внимание, что максимальная длина митра является произведением ширины линии, измеренной в текущей системе координат, значением этого свойства <code>miterLimit</code> (значение по умолчанию 10,0 в HTML {{HTMLElement("canvas")}}), поэтому <code>miterLimit</code> может устанавливаться независимо от текущей шкалы дисплея или любых аффинных преобразований путей: она влияет только на эффективно визуализированную форму ребер линии.</p>
+
+<p>Точнее, предел митры является максимально допустимым отношением длины расширения (в холсте HTML он измеряется между внешним углом соединенных краев линии и общей конечной точкой соединительных сегментов, указанными на пути), до половины ширины линии. Его можно равнозначно определить как максимально допустимое отношение расстояния между внутренней и внешней точками перехода краев к общей ширине линии. Затем он равен косекансу с половиной минимального внутреннего угла соединительных сегментов, ниже которого не будет создано ни одного соединения митра, а только скос соединяется:</p>
+
+<ul>
+ <li><code>miterLimit</code> = <strong>max</strong> <code>miterLength</code> / <code>lineWidth</code> = 1 / <strong>sin</strong> ( <strong>min</strong> <em>θ</em> / 2 )</li>
+ <li>Предел митры по умолчанию, равный 10,0, разделит все митры углов, острее примерно 11 градусов.</li>
+ <li>Предел митры, равный √2 ≈ 1.4142136 (rounded up) сгладит миты для всех острых углов, поддерживая митры только для тупых или прямых углов.</li>
+ <li>Предел митры, равный 1,0, действителен, но отключит все миты.</li>
+ <li>Значения ниже 1.0 являются недопустимыми для предела митры.</li>
+</ul>
+
+<p>Вот небольшая демонстрация, в которой вы можете динамически установить <code>miterLimit</code> и посмотреть, как это влияет на фигуры на холсте. Синие линии показывают, где начальная и конечная точки для каждой из линий в шаблоне зигзага.</p>
+
+<p>Если вы укажете в этой демонстрации значение <code>miterLimit</code> ниже 4.2, ни один из видимых углов не присоединится к расширению митры, но только с небольшим скосом рядом с синими линиями; с отметкой <code>miterLimit</code> выше 10, большинство углов в этой демонстрации должны соединяться с митрой, удаленной от синих линий, высота которой уменьшается между углами слева направо, потому что они соединяются с растущими углами; с промежуточными значениями углы с левой стороны будут соединяться только с скосом рядом с синими линиями, а углы с правой стороны с удлинителем митры (также с уменьшающейся высотой).</p>
+
+<pre class="brush: js;highlight[18] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // Clear canvas
+ ctx.clearRect(0,0,150,150);
+
+ // Draw guides
+ ctx.strokeStyle = '#09f';
+ ctx.lineWidth = 2;
+ ctx.strokeRect(-5,50,160,50);
+
+ // Set line styles
+ ctx.strokeStyle = '#000';
+ ctx.lineWidth = 10;
+
+ // check input
+ if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) {
+ ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value);
+ } else {
+ alert('Value must be a positive number');
+ }
+
+ // Draw lines
+ ctx.beginPath();
+ ctx.moveTo(0,100);
+ for (i=0;i&lt;24;i++){
+ var dy = i%2==0 ? 25 : -25 ;
+ ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
+ }
+ ctx.stroke();
+ return false;
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;table&gt;
+ &lt;tr&gt;
+ &lt;td&gt;&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;&lt;/td&gt;
+ &lt;td&gt;Change the &lt;code&gt;miterLimit&lt;/code&gt; by entering a new value below and clicking the redraw button.&lt;br&gt;&lt;br&gt;
+ &lt;form onsubmit="return draw();"&gt;
+ &lt;label&gt;Miter limit&lt;/label&gt;
+ &lt;input type="text" size="3" id="miterLimit"/&gt;
+ &lt;input type="submit" value="Redraw"/&gt;
+ &lt;/form&gt;
+ &lt;/td&gt;
+ &lt;/tr&gt;
+&lt;/table&gt;</pre>
+
+<pre class="brush: js notranslate">document.getElementById('miterLimit').value = document.getElementById('canvas').getContext('2d').miterLimit;
+draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Демонстрация_свойства_miterLimit", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}</p>
+
+<h3 id="Использование_штрихов">Использование штрихов</h3>
+
+<p>Метод setLineDash и свойство lineDashOffset задают шаблон штрихов для линий. Метод setLineDash принимает список чисел, который определяет расстояния для попеременного рисования линии и разрыва, а свойство lineDashOffset устанавливает смещение, с которого начинается шаблон.</p>
+
+<p>В этом примере мы создаем эффект походных муравьев. Это техника анимации, часто встречающаяся в инструментах выбора программ компьютерной графики. Это помогает пользователю отличить границу выделения от фона изображения, анимируя границу. В следующей части этого руководства вы узнаете, как сделать эту и другие основные анимации.</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="110" height="110"&gt;&lt;/canvas&gt;</pre>
+</div>
+
+<pre class="brush: js;highlight[6] notranslate">var ctx = document.getElementById('canvas').getContext('2d');
+var offset = 0;
+
+function draw() {
+  ctx.clearRect(0,0, canvas.width, canvas.height);
+  ctx.setLineDash([4, 2]);
+  ctx.lineDashOffset = -offset;
+  ctx.strokeRect(10,10, 100, 100);
+}
+
+function march() {
+  offset++;
+  if (offset &gt; 16) {
+    offset = 0;
+  }
+  draw();
+  setTimeout(march, 20);
+}
+
+march();</pre>
+
+<p>{{EmbedLiveSample("Используемый штрих", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}</p>
+
+<h2 id="Градиенты">Градиенты</h2>
+
+<p>Just like any normal drawing program, we can fill and stroke shapes using linear and radial gradients. We create a {{domxref("CanvasGradient")}} object by using one of the following methods. We can then assign this object to the <code>fillStyle</code> or <code>strokeStyle</code> properties.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}</dt>
+ <dd>Creates a linear gradient object with a starting point of (<code>x1</code>, <code>y1</code>) and an end point of (<code>x2</code>, <code>y2</code>).</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}</dt>
+ <dd>Creates a radial gradient. The parameters represent two circles, one with its center at (<code>x1</code>, <code>y1</code>) and a radius of <code>r1</code>, and the other with its center at (<code>x2</code>, <code>y2</code>) with a radius of <code>r2</code>.</dd>
+</dl>
+
+<p>For example:</p>
+
+<pre class="brush: js notranslate">var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
+</pre>
+
+<p>Once we've created a <code>CanvasGradient</code> object we can assign colors to it by using the <code>addColorStop()</code> method.</p>
+
+<dl>
+ <dt>{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}</dt>
+ <dd>Creates a new color stop on the <code>gradient</code> object. The <code>position</code> is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the <code>color</code> argument must be a string representing a CSS {{cssxref("&lt;color&gt;")}}, indicating the color the gradient should reach at that offset into the transition.</dd>
+</dl>
+
+<p>You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.</p>
+
+<pre class="brush: js notranslate">var lineargradient = ctx.createLinearGradient(0,0,150,150);
+lineargradient.addColorStop(0, 'white');
+lineargradient.addColorStop(1, 'black');
+</pre>
+
+<h3 id="Пример_createLinearGradient">Пример <code>createLinearGradient</code></h3>
+
+<p>In this example, we'll create two different gradients. As you can see here, both the <code>strokeStyle</code> and <code>fillStyle</code> properties can accept a <code>canvasGradient</code> object as valid input.</p>
+
+<pre class="brush: js;highlight[5,11] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // Create gradients
+ var lingrad = ctx.createLinearGradient(0,0,0,150);
+ lingrad.addColorStop(0, '#00ABEB');
+ lingrad.addColorStop(0.5, '#fff');
+ lingrad.addColorStop(0.5, '#26C000');
+ lingrad.addColorStop(1, '#fff');
+
+ var lingrad2 = ctx.createLinearGradient(0,50,0,95);
+ lingrad2.addColorStop(0.5, '#000');
+ lingrad2.addColorStop(1, 'rgba(0,0,0,0)');
+
+ // assign gradients to fill and stroke styles
+ ctx.fillStyle = lingrad;
+ ctx.strokeStyle = lingrad2;
+
+ // draw shapes
+ ctx.fillRect(10,10,130,130);
+ ctx.strokeRect(50,50,50,50);
+
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>The first is a background gradient. As you can see, we assigned two colors at the same position. You do this to make very sharp color transitions—in this case from white to green. Normally, it doesn't matter in what order you define the color stops, but in this special case, it does significantly. If you keep the assignments in the order you want them to appear, this won't be a problem.</p>
+
+<p>In the second gradient, we didn't assign the starting color (at position 0.0) since it wasn't strictly necessary, because it will automatically assume the color of the next color stop. Therefore, assigning the black color at position 0.5 automatically makes the gradient, from the start to this stop, black.</p>
+
+<p>{{EmbedLiveSample("Пример_createLinearGradient", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}</p>
+
+<h3 id="Пример_createRadialGradient">Пример <code>createRadialGradient</code></h3>
+
+<p>In this example, we'll define four different radial gradients. Because we have control over the start and closing points of the gradient, we can achieve more complex effects than we would normally have in the "classic" radial gradients we see in, for instance, Photoshop (that is, a gradient with a single center point where the gradient expands outward in a circular shape).</p>
+
+<pre class="brush: js;highlight[5,10,15,20] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // Create gradients
+ var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
+ radgrad.addColorStop(0, '#A7D30C');
+ radgrad.addColorStop(0.9, '#019F62');
+ radgrad.addColorStop(1, 'rgba(1,159,98,0)');
+
+ var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
+ radgrad2.addColorStop(0, '#FF5F98');
+ radgrad2.addColorStop(0.75, '#FF0188');
+ radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
+
+ var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
+ radgrad3.addColorStop(0, '#00C9FF');
+ radgrad3.addColorStop(0.8, '#00B5E2');
+ radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
+
+ var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
+ radgrad4.addColorStop(0, '#F4F201');
+ radgrad4.addColorStop(0.8, '#E4C700');
+ radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
+
+ // draw shapes
+ ctx.fillStyle = radgrad4;
+ ctx.fillRect(0,0,150,150);
+ ctx.fillStyle = radgrad3;
+ ctx.fillRect(0,0,150,150);
+ ctx.fillStyle = radgrad2;
+ ctx.fillRect(0,0,150,150);
+ ctx.fillStyle = radgrad;
+ ctx.fillRect(0,0,150,150);
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>In this case, we've offset the starting point slightly from the end point to achieve a spherical 3D effect. It's best to try to avoid letting the inside and outside circles overlap because this results in strange effects which are hard to predict.</p>
+
+<p>The last color stop in each of the four gradients uses a fully transparent color. If you want to have a nice transition from this to the previous color stop, both colors should be equal. This isn't very obvious from the code because it uses two different CSS color methods as a demonstration, but in the first gradient <code>#019F62 = rgba(1,159,98,1)</code>.</p>
+
+<p>{{EmbedLiveSample("Пример_createRadialGradient", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}</p>
+
+<h2 id="Шаблоны">Шаблоны</h2>
+
+<p>В одном из предыдущих примеров мы использовали несколько циклов, чтобы создать шаблон из повторяющихся изображений. Однако, есть более простой способ сделать подобное - метод <code>createPattern()</code>.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}</dt>
+ <dd>Создает и возвращает новый canvas объект - шаблон (pattern). <code>image</code> - {{domxref("CanvasImageSource")}} (то есть {{domxref ("HTMLImageElement")}}, другой холст, элемент {{HTMLElement ("video")}} или подобный  объект. <code>type</code> - строка, указывающая, как использовать <code>image</code>.</dd>
+</dl>
+
+<p>Тип указывает, как использовать image для создания шаблона и должен быть одним из следующих значений:</p>
+
+<dl>
+ <dt><code>repeat</code></dt>
+ <dd>Повторяет изображение в вертикальном и горизонтальном направлениях.</dd>
+ <dt><code>repeat-x</code></dt>
+ <dd>Повторяет изображение по горизонтали, но не по вертикали.</dd>
+ <dt><code>repeat-y</code></dt>
+ <dd>Повторяет изображение по вертикали, но не по горизонтали.</dd>
+ <dt><code>no-repeat</code></dt>
+ <dd>Не повторяет изображение. Используется только один раз.</dd>
+</dl>
+
+<p>Мы используем этот метод, чтобы создать {{domxref("CanvasPattern")}} объект, который очень похож на методы градиента, рассмотренные ранее. Как только мы создали шаблон, мы можем назначить ему свойства <code>fillStyle</code> или <code>strokeStyle</code>. Например:</p>
+
+<pre class="brush: js notranslate">var img = new Image();
+img.src = 'someimage.png';
+var ptrn = ctx.createPattern(img,'repeat');
+</pre>
+
+<div class="note">
+<p><strong>Примечание:</strong> По аналогии с методом <code>drawImage()</code>, вы должны убедиться, что изображение, которое вы используете, загружено до вызова этого метода. Иначе шаблон может быть отрисован некорректно.</p>
+</div>
+
+<h3 id="Пример_createPattern">Пример <code>createPattern</code></h3>
+
+<p>In this last example, we'll create a pattern to assign to the <code>fillStyle</code> property. The only thing worth noting is the use of the image's <code>onload</code> handler. This is to make sure the image is loaded before it is assigned to the pattern.</p>
+
+<pre class="brush: js;highlight[10] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // create new image object to use as pattern
+ var img = new Image();
+ img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
+ img.onload = function(){
+
+ // create pattern
+ var ptrn = ctx.createPattern(img,'repeat');
+ ctx.fillStyle = ptrn;
+ ctx.fillRect(0,0,150,150);
+
+ }
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+
+<p>The result looks like this:</p>
+</div>
+
+<p>{{EmbedLiveSample("Пример_createPattern", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}</p>
+
+<h2 id="Тени">Тени</h2>
+
+<p>Using shadows involves just four properties:</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}</dt>
+ <dd>Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}</dt>
+ <dd>Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}</dt>
+ <dd>Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}</dt>
+ <dd>A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.</dd>
+</dl>
+
+<p>The properties <code>shadowOffsetX</code> and <code>shadowOffsetY</code> indicate how far the shadow should extend from the object in the X and Y directions; these values aren't affected by the current transformation matrix. Use negative values to cause the shadow to extend up or to the left, and positive values to cause the shadow to extend down or to the right. These are both 0 by default.</p>
+
+<p>The <code>shadowBlur</code> property indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.</p>
+
+<p>The <code>shadowColor</code> property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Shadows are only drawn for <code>source-over</code> <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing" title="Web/Guide/HTML/Canvas_tutorial/Compositing">compositing operations</a>.</p>
+</div>
+
+<h3 id="Пример_текста_с_тенью">Пример текста с тенью</h3>
+
+<p>This example draws a text string with a shadowing effect.</p>
+
+<pre class="brush: js;highlight[4,5,6,7] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ ctx.shadowOffsetX = 2;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowBlur = 2;
+ ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
+
+ ctx.font = "20px Times New Roman";
+ ctx.fillStyle = "Black";
+ ctx.fillText("Sample String", 5, 30);
+}
+</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="150" height="80"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Пример_текста_с_тенью", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}</p>
+
+<p>We will look at the <code>font</code> property and <code>fillText</code> method in the next chapter about <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text">drawing text</a>.</p>
+
+<h2 id="Canvas_fill_rules">Canvas fill rules</h2>
+
+<p>When using <code>fill</code> (or {{domxref("CanvasRenderingContext2D.clip", "clip")}} and {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}}) you can optionally provide a fill rule algorithm by which to determine if a point is inside or outside a path and thus if it gets filled or not. This is useful when a path intersetcs itself or is nested.<br>
+ <br>
+ Two values are possible:</p>
+
+<ul>
+ <li><code><strong>"nonzero</strong></code>": The <a class="external external-icon" href="http://en.wikipedia.org/wiki/Nonzero-rule">non-zero winding rule</a>, which is the default rule.</li>
+ <li><code><strong>"evenodd"</strong></code>: The <a class="external external-icon" href="http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule">even-odd winding rule</a>.</li>
+</ul>
+
+<p>In this example we are using the <code>evenodd</code> rule.</p>
+
+<pre class="brush: js;highlight[6] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ ctx.beginPath();
+  ctx.arc(50, 50, 30, 0, Math.PI*2, true);
+  ctx.arc(50, 50, 15, 0, Math.PI*2, true);
+ ctx.fill("evenodd");
+}</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="100" height="100"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}</p>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/рисование_текста/index.html b/files/ru/web/api/canvas_api/tutorial/рисование_текста/index.html
new file mode 100644
index 0000000000..90915c5e09
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/рисование_текста/index.html
@@ -0,0 +1,166 @@
+---
+title: Рисование текста
+slug: Web/API/Canvas_API/Tutorial/Рисование_текста
+tags:
+ - Canvas
+ - Графика
+ - Примеры
+ - Рукводовство
+ - мануал
+translation_of: Web/API/Canvas_API/Tutorial/Drawing_text
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}</div>
+
+<div class="summary">
+<p>После того, как мы увидели в предыдущей главе, как <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors">применять стили и цвета</a>, взглянем на написание текста в canvas.</p>
+</div>
+
+<h2 id="Рисование_текста">Рисование текста</h2>
+
+<p>Контекст рендеринга canvas предоставляет два метода для рисования текста:</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.fillText", "fillText(text, x, y [, maxWidth])")}}</dt>
+ <dd>Вставляет заданный текст в положении (x,y). Опционально может быть указана максимальная ширина.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.strokeText", "strokeText(text, x, y [, maxWidth])")}}</dt>
+ <dd>Вставляет контур заданного текста в положении (x,y). Опционально может быть указана максимальная ширина.</dd>
+</dl>
+
+<h3 id="Пример_fillText">Пример <code>fillText</code></h3>
+
+<p>Текст вставлен с использованием текущего <code>fillStyle</code>.</p>
+
+<pre class="brush: js;highlight[4] notranslate">function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.font = "48px serif";
+  ctx.fillText("Hello world", 10, 50);
+}</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="300" height="100"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_fillText_example", 310, 110)}}</p>
+
+<h3 id="Пример_strokeText">Пример <code>strokeText</code></h3>
+
+<p>Текст вставлен с использованием текущего <code>strokeStyle</code>.</p>
+
+<pre class="brush: js;highlight[4] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ ctx.font = "48px serif";
+ ctx.strokeText("Hello world", 10, 50);
+}</pre>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="300" height="100"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js notranslate">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_strokeText_example", 310, 110)}}</p>
+
+<h2 id="Стилизация_текста">Стилизация текста</h2>
+
+<p>В примерах выше мы уже использовали свойство font для изменения размера текста. Кроме него существуют еще несколько свойств, позволяющие настроить вывод текста на canvas:</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.font", "font = value")}}</dt>
+ <dd>Это основной стиль, который будет использоваться для вывода текста. Строка имеет такой же синтаксис, как <a href="/en-US/docs/Web/CSS">CSS</a>-свойство {{cssxref("font")}}. По умолчанию - sans-serif высотой 10px.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.textAlign", "textAlign = value")}}</dt>
+ <dd>Настройка выравнивания текста. Возможные значения: <code>start</code>, <code>end</code>, <code>left</code>, <code>right</code> или <code>center</code>. По умолчанию - <code>start</code>.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline = value")}}</dt>
+ <dd>Настройка выравнивания текста по вертикали. Возможные значения: <code>top</code>, <code>hanging</code>, <code>middle</code>, <code>alphabetic</code>, <code>ideographic</code>, <code>bottom</code>. По умолчанию - <code>alphabetic</code>.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.direction", "direction = value")}}</dt>
+ <dd>Направление текста. Возможные значения: <code>ltr</code>, <code>rtl</code>, <code>inherit</code>. По умолчанию - <code>inherit</code>.</dd>
+</dl>
+
+<p>Эти свойства могут быть вам знакомы если вы работали с CSS.</p>
+
+<p>Изображение от <a class="external" href="http://www.whatwg.org/" title="http://www.whatwg.org/">WHATWG</a> ниже показывает различные варианты свойства <code>textBaseline</code>.<img alt="The top of the em square is
+roughly at the top of the glyphs in a font, the hanging baseline is
+where some glyphs like आ are anchored, the middle is half-way
+between the top of the em square and the bottom of the em square,
+the alphabetic baseline is where characters like Á, ÿ,
+f, and Ω are anchored, the ideographic baseline is
+where glyphs like 私 and 達 are anchored, and the bottom
+of the em square is roughly at the bottom of the glyphs in a
+font. The top and bottom of the bounding box can be far from these
+baselines, due to glyphs extending far outside the em square." src="http://www.whatwg.org/specs/web-apps/current-work/images/baselines.png"></p>
+
+<h3 id="Пример_textBaseline">Пример textBaseline</h3>
+
+<p>Редактируя код ниже, вы можете видеть, как меняется отображение текста на canvas в реальном времени:</p>
+
+<pre class="brush: js;highlight[2] notranslate">ctx.font = "48px serif";
+ctx.textBaseline = "hanging";
+ctx.strokeText("Hello world!", 0, 100);
+</pre>
+
+<div class="hidden">
+<h6 id="Playable_code" name="Playable_code">Playable code</h6>
+
+<pre class="brush: html notranslate">&lt;canvas id="canvas" width="400" height="200" class="playable-canvas"&gt;&lt;/canvas&gt;
+&lt;div class="playable-buttons"&gt;
+  &lt;input id="edit" type="button" value="Edit" /&gt;
+  &lt;input id="reset" type="button" value="Reset" /&gt;
+&lt;/div&gt;
+&lt;textarea id="code" class="playable-code"&gt;
+ctx.font = "48px serif";
+ctx.textBaseline = "hanging";
+ctx.strokeText("Hello world", 0, 100);&lt;/textarea&gt;
+</pre>
+
+<pre class="brush: js notranslate">var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+var textarea = document.getElementById("code");
+var reset = document.getElementById("reset");
+var edit = document.getElementById("edit");
+var code = textarea.value;
+
+function drawCanvas() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ eval(textarea.value);
+}
+
+reset.addEventListener("click", function() {
+ textarea.value = code;
+ drawCanvas();
+});
+
+edit.addEventListener("click", function() {
+ textarea.focus();
+})
+
+textarea.addEventListener("input", drawCanvas);
+window.addEventListener("load", drawCanvas);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', 700, 360) }}</p>
+
+<h2 id="Измерение_ширины_текста">Измерение ширины текста</h2>
+
+<p>Для измерения ширины текста (без рисования его на canvas) можно воспользоваться следующим методом:</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.measureText", "measureText()")}}</dt>
+ <dd>Возвращает объект {{domxref("TextMetrics")}}, содержащий ширину текста в пикселах, до отрисовки на canvas.</dd>
+</dl>
+
+<p>Пример ниже показывает, как можно измерить ширину текста.</p>
+
+<pre class="brush: js;highlight[3] notranslate">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ var text = ctx.measureText("foo"); // TextMetrics object
+ text.width; // 16;
+}
+</pre>
+
+<h2 id="Примечания">Примечания</h2>
+
+<p>В ранних версиях Gecko (движок рендеринга в Firefox, Firefox OS и других приложениях Mozilla) были реализованы <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#Prefixed_APIs">методы API с префиксами</a> для рисования текста на canvas. На данный момент они устарели и уже, возможно, удалены, поэтому их правильная работа не гарантируется.</p>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}</p>
diff --git a/files/ru/web/api/canvas_api/tutorial/рисование_фигур/index.html b/files/ru/web/api/canvas_api/tutorial/рисование_фигур/index.html
new file mode 100644
index 0000000000..f6ca6c23ef
--- /dev/null
+++ b/files/ru/web/api/canvas_api/tutorial/рисование_фигур/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>