简体   繁体   English

有没有办法使用 HTML canvas 围绕这两个圆圈绘制路径/形状?

[英]Is there a way using HTML canvas to draw a path/shape around these 2 circles?

I want to add a shape/path around the 2 circles.我想在 2 个圆圈周围添加一个形状/路径。 我想要的图片

Here is my current code.这是我当前的代码。

var length = 200
var size = 50
// circles
ctx.beginPath();
ctx.arc(123,120,100,0,2*Math.PI);
ctx.stroke();
ctx.fill()
ctx.beginPath();
ctx.arc(length,length,size,0,2*Math.PI);
ctx.stroke();
ctx.fill()
// line between the 2 circles
ctx.beginPath();
ctx.moveTo(123,120);
ctx.lineTo(length,length);
ctx.stroke();

If you find the outer tangents of the two circles, you can draw two lines between them.如果你找到两个圆的外切线,你可以在它们之间画两条线。 You can then use.arc to draw the remaining circle parts:然后您可以使用 .arc 绘制剩余的圆形部分:

 // Setup const cvs = document.createElement("canvas"); cvs.width = cvs.height = 400; const ctx = cvs.getContext("2d"); const inputs = Array.from(document.querySelectorAll("input")); inputs.forEach(el => el.addEventListener("input", onChange)); document.body.appendChild(cvs); onChange(); // Drawing utils function drawCircle({ x, y, r }, color = "black", width = 1) { ctx.strokeStyle = color; ctx.lineWidth = width; ctx.beginPath(); ctx.arc(x, y, r, 0, 2*Math.PI); ctx.stroke(); } function drawLine(x1, y1, x2, y2, color = "black", width = 1) { ctx.strokeStyle = color; ctx.lineWidth = width; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); } function drawArc(x, y, r, a1, a2, color = "black", width = 1) { ctx.strokeStyle = color; ctx.lineWidth = width; ctx.beginPath(); ctx.arc(x, y, r, a1, a2); ctx.stroke(); } function render(c1, c2) { ctx.clearRect(0, 0, cvs.width, cvs.height); // circles drawCircle(c1); drawCircle(c2); // line between the 2 circles drawLine(c1.x, c1.y, c2.x, c2.y); // tangents const tangents = outerTangents(c1, c2); tangents.lines.forEach( ([[x1, y1], [x2, y2]]) => drawLine(x1, y1, x2, y2, "rgba(255, 0, 0, 0.5)", 5) ); // Arcs const [ a1, a2 ] = tangents.angles; const from = a2 + a1; const to = a1 - a2; drawArc(c1.x, c1.y, c1.r, from, to, "rgba(0, 255, 255, 0.5)", 5); drawArc(c2.x, c2.y, c2.r, to, from, "rgba(255, 0, 255, 0.5)", 5); } function onChange() { const [ x1, y1, r1, x2, y2, r2 ] = inputs.map(el => el.valueAsNumber); render({ x: x1, y: y1, r: r1 }, { x: x2, y: y2, r: r2 }); } // https://en.wikipedia.org/wiki/Tangent_lines_to_circles#Outer_tangent function outerTangents({ x: x1, y: y1, r: r1 }, { x: x2, y: y2, r: r2 }) { const dx = x2 - x1; const dy = y2 - y1; const dxy = Math.sqrt(dx ** 2 + dy ** 2); if (dxy <= Math.abs(r2 - r1)) { return { lines: [], angles: [] }; } const a1 = Math.atan2(dy, dx); const a2 = Math.acos((r1 - r2) / dxy); return { lines: [ [ [x1 + r1 * Math.cos(a1 + a2), y1 + r1 * Math.sin(a1 + a2)], [x2 + r2 * Math.cos(a1 + a2), y2 + r2 * Math.sin(a1 + a2)] ], [ [x1 + r1 * Math.cos(a1 - a2), y1 + r1 * Math.sin(a1 - a2)], [x2 + r2 * Math.cos(a1 - a2), y2 + r2 * Math.sin(a1 - a2)] ] ], angles: [ a1, a2 ] }; }
 X1 <input type="range" min="10" max="150" step="1" value="123"> Y1 <input type="range" min="10" max="150" step="1" value="120"> R1 <input type="range" min="10" max="150" step="1" value="100"> X2 <input type="range" min="10" max="250" step="1" value="200"> Y2 <input type="range" min="10" max="250" step="1" value="140"> R2 <input type="range" min="10" max="150" step="1" value="50">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM