From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../api/canvasrenderingcontext2d/arcto/index.html | 260 +++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 files/ja/web/api/canvasrenderingcontext2d/arcto/index.html (limited to 'files/ja/web/api/canvasrenderingcontext2d/arcto/index.html') diff --git a/files/ja/web/api/canvasrenderingcontext2d/arcto/index.html b/files/ja/web/api/canvasrenderingcontext2d/arcto/index.html new file mode 100644 index 0000000000..a672a83843 --- /dev/null +++ b/files/ja/web/api/canvasrenderingcontext2d/arcto/index.html @@ -0,0 +1,260 @@ +--- +title: CanvasRenderingContext2D.arcTo() +slug: Web/API/CanvasRenderingContext2D/arcTo +translation_of: Web/API/CanvasRenderingContext2D/arcTo +--- +
{{APIRef}}
+ +

Canvas 2D APIの CanvasRenderingContext2D.arcTo() メソッドは、2つの制御点と半径を指定して現在のサブパスに円弧を追加します。円弧は現在のパスの最後の点と自動的に直線で連結されます。

+ +

このメソッドは主に角丸の図形を描画するのに使用されます。

+ +
+

Note: 相対的に大きな半径を指定した場合、得られる角丸の描線が期待するものとは異なる可能性があります: 円弧と連結する直線は円弧の半径に合うように描線されます。

+
+ +

Syntax

+ +
void ctx.arcTo(x1, y1, x2, y2, radius);
+
+ +

Parameters

+ +
+
x1
+
1つ目の制御点のx座標。
+
y1
+
1つ目の制御点のy座標。
+
x2
+
2つ目の制御点のx座標。
+
y2
+
2つ目の制御点のy座標。
+
radius
+
円弧の半径。負でない値を設定する必要があります。
+
+ +

Examples

+ +

 arcTo の仕組み

+ +

arcTo() の仕組みを解釈するには、始点と1つ目の制御点を結ぶ直線と、そこから2つ目の制御点を結ぶ直線の2つの線をイメージする方法があります。arcTo()を使用しない場合、これら2つの線分は鋭角を形成しますが、arcTo() はこの鋭角部分に接する円弧を描くことで滑らかに接続します。すなわち、2直線に接する円弧を作成するということになります。

+ +

HTML

+ +
<canvas id="canvas"></canvas>
+ +

JavaScript

+ +
const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+
+// Tangential lines
+ctx.beginPath();
+ctx.strokeStyle = 'gray';
+ctx.moveTo(200, 20);
+ctx.lineTo(200, 130);
+ctx.lineTo(50, 20);
+ctx.stroke();
+
+// Arc
+ctx.beginPath();
+ctx.strokeStyle = 'black';
+ctx.lineWidth = 5;
+ctx.moveTo(200, 20);
+ctx.arcTo(200,130, 50,20, 40);
+ctx.stroke();
+
+// Start point
+ctx.beginPath();
+ctx.fillStyle = 'blue';
+ctx.arc(200, 20, 5, 0, 2 * Math.PI);
+ctx.fill();
+
+// Control points
+ctx.beginPath();
+ctx.fillStyle = 'red';
+ctx.arc(200, 130, 5, 0, 2 * Math.PI); // Control point one
+ctx.arc(50, 20, 5, 0, 2 * Math.PI);   // Control point two
+ctx.fill();
+
+ +

Result

+ +

この例では、arcTo() によって描かれる線を黒い太線接線を灰色制御点を赤始点となる現在のパスの最後の点を青で描画しています。

+ +

{{ EmbedLiveSample('How_arcTo_works', 315, 165) }}

+ +

角丸図形の作成

+ +

この例では arcTo()を用いて丸い角をもつ線を描画しています。これが最も一般的な使われ方です。

+ +

HTML

+ +
<canvas id="canvas"></canvas>
+
+ +

JavaScript

+ +

描線は直前のmoveTo()により座標 (230, 20)から開始し、2つの制御点(90, 130) と (20, 20) を結ぶ直線に接するように形成された半径50の円弧に接続されます。円弧の終端からは lineTo() メソッドにより (20, 20) の点まで直線が描画されます。2つ目の制御点の座標と同じ座標を lineTo() で指定することで、滑らかな描線を得ることができます。

+ +
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();
+
+ +

Result

+ +

{{ EmbedLiveSample('Creating_a_rounded_corner', 315, 165) }}

+ +

大きすぎる半径を指定した場合

+ +

相対的に大きな半径を指定した場合には、前述の方法では期待されるような滑らかな描線は得られません。この例では、moveTo()後の地点から円弧に接続される線は下方ではなく上方に向かってしまっています。これは、2つの直線に接する円の半径が大き過ぎるために、始点よりも上方に円弧との接点があるために発生しています。

+ +

HTML

+ +
<canvas id="canvas"></canvas>
+
+ +

JavaScript

+ +
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();
+
+ +

Result

+ +

{{ EmbedLiveSample('Result_of_a_large_radius', 315, 165) }}

+ +

Live demo

+ +

以下はより洗練されたデモです。半径の変化幅を調節し、どのように描線が変化するかを試すことができます。

+ +

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>
+
+ +

JavaScript

+ +
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; // the radius that changes over time
+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);
+ +

Result

+ +
{{EmbedLiveSample('Live_demo', 315, 200) }}
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "scripting.html#dom-context-2d-arcto", "CanvasRenderingContext2D.arcTo")}}{{Spec2('HTML WHATWG')}}
+ +

Browser compatibility

+ + + +

{{Compat("api.CanvasRenderingContext2D.arcTo")}}

+ +

See also

+ + -- cgit v1.2.3-54-g00ecf