aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/api/canvasrenderingcontext2d/arcto
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/canvasrenderingcontext2d/arcto
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/canvasrenderingcontext2d/arcto')
-rw-r--r--files/ru/web/api/canvasrenderingcontext2d/arcto/index.html256
1 files changed, 256 insertions, 0 deletions
diff --git a/files/ru/web/api/canvasrenderingcontext2d/arcto/index.html b/files/ru/web/api/canvasrenderingcontext2d/arcto/index.html
new file mode 100644
index 0000000000..53a13ff758
--- /dev/null
+++ b/files/ru/web/api/canvasrenderingcontext2d/arcto/index.html
@@ -0,0 +1,256 @@
+---
+title: CanvasRenderingContext2D.arcTo()
+slug: Web/API/CanvasRenderingContext2D/arcTo
+tags:
+ - API
+ - Canvas
+ - Method
+translation_of: Web/API/CanvasRenderingContext2D/arcTo
+---
+<div>{{APIRef}}</div>
+
+<p>В Canvas 2D API есть метод <code><strong>CanvasRenderingContext2D</strong></code><strong><code>.arcTo()</code></strong>. Он добавляет дугу к контуру (path) с заданными контрольными точками и радиусом, соединяя их прямой линией с предыдущей точкой контура.</p>
+
+<p>Обычно метод используется для скругления углов.</p>
+
+<div class="blockIndicator note">
+<p><strong>Примечание:</strong> Помните, что вы можете получить неожиданный результат при использовании большого радиуса: соединтельная линия дуги будет идти в любом направлении, в котором она должна соответствовать указанному радиусу.</p>
+</div>
+
+<h2 id="Синтаксис">Синтаксис</h2>
+
+<pre class="syntaxbox">void <var><em>ctx</em>.arcTo(x1, y1, x2, y2, radius);</var>
+</pre>
+
+<h3 id="Параметры">Параметры</h3>
+
+<dl>
+ <dt><code>x1</code></dt>
+ <dd>Координата <u>x</u> первой контрольной точки.</dd>
+ <dt><code>y1</code></dt>
+ <dd>Координата <u>y</u> первой контрольной точки.</dd>
+ <dt><code>x2</code></dt>
+ <dd>Координата <u>x</u> второй контрольной точки.</dd>
+ <dt><code>y2</code></dt>
+ <dd>Координата <u>y</u> второй контрольной точки.</dd>
+ <dt><code>radius</code></dt>
+ <dd>Радиус дуги. Не может быть отрицательным.</dd>
+</dl>
+
+<h2 id="Примеры">Примеры</h2>
+
+<h3 id="Как_работает_arcTo">Как работает arcTo</h3>
+
+<p>Один из способов понять как работает <code>arcTo()</code> - представить две прямые линии: одна идёт от начальной точки к первой контрольной точке, а вторая от этой точки до второй контрольной точки. Без <code>arcTo()</code> эти два сегмента образовали бы остый угол: <code>arcTo()</code> cоздаёт дугу между этими двумя точками и сглаживает его. Другими словами, дуга является касательной для обеих линий.</p>
+
+<h4 id="HTML">HTML</h4>
+
+<pre class="brush: html">&lt;canvas id="canvas"&gt;&lt;/canvas&gt;</pre>
+
+<h4 id="JavaScript">JavaScript</h4>
+
+<pre class="brush: js">const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+
+// Касательная линия
+ctx.beginPath();
+ctx.strokeStyle = 'gray';
+ctx.moveTo(200, 20);
+ctx.lineTo(200, 130);
+ctx.lineTo(50, 20);
+ctx.stroke();
+
+// Дуга
+ctx.beginPath();
+ctx.strokeStyle = 'black';
+ctx.lineWidth = 5;
+ctx.moveTo(200, 20);
+ctx.arcTo(200,130, 50,20, 40);
+ctx.stroke();
+
+// Начальная точка
+ctx.beginPath();
+ctx.fillStyle = 'blue';
+ctx.arc(200, 20, 5, 0, 2 * Math.PI);
+ctx.fill();
+
+// Контрольные точки
+ctx.beginPath();
+ctx.fillStyle = 'red';
+ctx.arc(200, 130, 5, 0, 2 * Math.PI); // Первая контрольная точка
+ctx.arc(50, 20, 5, 0, 2 * Math.PI); // Вторая контрольная точка
+ctx.fill();</pre>
+
+<h4 id="Результат">Результат</h4>
+
+<p>В этом примере контур, созданный с помощью <code>arcTo()</code> <strong>жирный и чёрный</strong>. <span style="color: gray;">Касательная линия серия</span>, <span style="color: red;">контрольные точки красные</span>, а <span style="color: blue;">начальная точка синяя</span>. </p>
+
+<p>{{ EmbedLiveSample('Как_работает_arcTo', 315, 165) }}</p>
+
+<h3 id="Создание_скругленного_угла">Создание скругленного угла</h3>
+
+<p>В этом примере создаётся скруглённый угол с использованием <code>arcTo()</code>. Это ещё один метод, который часто используется.</p>
+
+<h4 id="HTML_2">HTML</h4>
+
+<pre class="brush: html">&lt;canvas id="canvas"&gt;&lt;/canvas&gt;</pre>
+
+<h4 id="JavaScript_2">JavaScript</h4>
+
+<p>Дуга начинается в точке, заданной в <code>moveTo()</code>: (230, 20). Она сформирована так, чтобы соответствовать точкам на (90, 130) и (20, 20) с радиусом 50. Метод <code>lineTo()</code> соединяет дугу с (20, 20) прямой линией. Заметьте, что вторая контрольная точка дуги и точка, заданная в <code>lineTo()</code> одинаковые, что создаёт абсолютно гладкий угол.</p>
+
+<pre class="brush: js">const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+const p0 = { x: 230, y: 20 }
+const p1 = { x: 90, y: 130 }
+const p2 = { x: 20, y: 20 }
+
+const labelPoint = function (p) {
+ const offset = 15;
+ ctx.fillText('(' + p.x + ',' + p.y + ')', p.x + offset, p.y + offset);
+}
+
+ctx.beginPath();
+ctx.moveTo(p0.x, p0.y);
+ctx.arcTo(p1.x, p1.y, p2.x, p2.y, 50);
+ctx.lineTo(p2.x, p2.y);
+
+labelPoint(p0);
+labelPoint(p1);
+labelPoint(p2);
+
+ctx.stroke();</pre>
+
+<h4 id="Результат_2">Результат</h4>
+
+<p>{{ EmbedLiveSample('Создание_скругленного_угла', 315, 165) }}</p>
+
+<h3 id="Результат_с_большим_радиусом">Результат с большим радиусом</h3>
+
+<p>Если вы используете относительно большой радиус, дуга может появиться в том месте, где вы её не ожидаете. В данном примере соединительная линия дуги идёт вверху, а не внизу. Это происходит потому что радиус слишком большой, чтобы уместить дугу между точками.</p>
+
+<h4 id="HTML_3">HTML</h4>
+
+<pre class="brush: html">&lt;canvas id="canvas"&gt;&lt;/canvas&gt;</pre>
+
+<h4 id="JavaScript_3">JavaScript</h4>
+
+<pre class="brush: js">const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+
+ctx.beginPath();
+ctx.moveTo(180, 90);
+ctx.arcTo(180,130, 110,130, 130);
+ctx.lineTo(110, 130);
+ctx.stroke();</pre>
+
+<h4 id="Результат_3">Результат</h4>
+
+<p>{{ EmbedLiveSample('Результат_с_большим_радиусом', 315, 165) }}</p>
+
+<h3 id="Живая_демонстрация">Живая демонстрация</h3>
+
+<p>Более сложная демонстрация метода. Вы можете поиграть с диапазоном ввода, чтобы увидеть, как изменяется дуга.</p>
+
+<h4 id="HTML_4">HTML</h4>
+
+<pre class="brush: html">&lt;div&gt;
+ &lt;label for="radius"&gt;Radius: &lt;/label&gt;
+ &lt;input name="radius" type="range" id="radius" min=0 max=100 value=50&gt;
+ &lt;label for="radius" id="radius-output"&gt;50&lt;/label&gt;
+&lt;/div&gt;
+&lt;canvas id="canvas"&gt;&lt;/canvas&gt;</pre>
+
+<h4 id="JavaScript_4">JavaScript</h4>
+
+<pre class="brush: js">const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+
+const controlOut = document.getElementById('radius-output');
+const control = document.getElementById('radius');
+ control.oninput = () =&gt; {
+ controlOut.textContent = r = control.value;
+ };
+
+const mouse = { x: 0, y: 0 };
+
+let r = 100; // Radius
+const p0 = { x: 0, y: 50 };
+
+const p1 = { x: 100, y: 100 };
+const p2 = { x: 150, y: 50 };
+const p3 = { x: 200, y: 100 };
+
+const labelPoint = function (p, offset, i = 0){
+ const {x, y} = offset;
+ ctx.beginPath();
+ ctx.arc(p.x, p.y, 2, 0, Math.PI * 2);
+ ctx.fill();
+ ctx.fillText(`${i}:(${p.x}, ${p.y})`, p.x + x, p.y + y);
+}
+
+const drawPoints = function (points){
+ for (let i = 0; i &lt; points.length; i++) {
+ var p = points[i];
+ labelPoint(p, { x: 0, y: -20 } , i)
+ }
+}
+
+// Draw arc
+const drawArc = function ([p0, p1, p2], r) {
+ ctx.beginPath();
+ ctx.moveTo(p0.x, p0.y);
+ ctx.arcTo(p1.x, p1.y, p2.x, p2.y, r);
+ ctx.lineTo(p2.x, p2.y);
+ ctx.stroke();
+}
+
+
+let t0 = 0;
+let rr = 0; // радиус, который меняется со временем
+let a = 0; // angle
+let PI2 = Math.PI * 2;
+const loop = function (t) {
+ t0 = t / 1000;
+ a = t0 % PI2;
+ rr = Math.abs(Math.cos(a) * r);
+
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ drawArc([p1, p2, p3], rr);
+ drawPoints([p1, p2, p3]);
+ requestAnimationFrame(loop);
+}
+
+loop(0);</pre>
+
+<h4 id="Результат_4">Результат</h4>
+
+<p>{{EmbedLiveSample('Живая_демонстрация', 315, 200) }}</p>
+
+<h2 id="Спецификации">Спецификации</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Спецификация</th>
+ <th scope="col">Статус</th>
+ <th scope="col">Комментарий</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('HTML WHATWG', "scripting.html#dom-context-2d-arcto", "CanvasRenderingContext2D.arcTo")}}</td>
+ <td>{{Spec2('HTML WHATWG')}}</td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Поддержка_браузерами">Поддержка браузерами</h2>
+
+<p>{{Compat("api.CanvasRenderingContext2D.arcTo")}}</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li>Элемент определяющий этот метод, {{domxref("CanvasRenderingContext2D")}}</li>
+</ul>