diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/api/canvasrenderingcontext2d/arcto | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-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.html | 256 |
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"><canvas id="canvas"></canvas></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"><canvas id="canvas"></canvas></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"><canvas id="canvas"></canvas></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"><div> + <label for="radius">Radius: </label> + <input name="radius" type="range" id="radius" min=0 max=100 value=50> + <label for="radius" id="radius-output">50</label> +</div> +<canvas id="canvas"></canvas></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 = () => { + 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 < 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> |