const ctx = canvas.getContext("2d");
const m = {
x: 0,
y: 0
};
document.addEventListener("mousemove", e => {
var b = canvas.getBoundingClientRect();
m.x = e.pageX - b.left - scrollX;
m.y = e.pageY - b.top - scrollY;
});
const PI = Math.PI;
const PI2 = Math.PI * 2;
const circles = [];
function circle(x, y, r, col, f = 0, t = PI2, w = 2) {
var c;
circles.push(c = { x, y,r, col, f, t, w});
return c;
};
function drawCircle(A) {
ctx.strokeStyle = A.col;
ctx.lineWidth = A.w;
ctx.beginPath();
ctx.arc(A.x, A.y, A.r, A.f, A.t);
ctx.stroke();
}
function mark(x, y, r, c) {
ctx.strokeStyle = c;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(x, y, r, 0, PI2);
ctx.stroke();
}
function line(A, B, c) {
ctx.strokeStyle = c;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.lineTo(A.x, A.y);
ctx.lineTo(B.x, B.y);
ctx.stroke();
}
// note I am sharing calc results between function
function circleIntercept(A, B) {
var vx, vy, dist, c, d, x, y, x1, y1, x2, y2, dir, a1, a2;
// Vec from A to B
vx = B.x - A.x;
vy = B.y - A.y;
// Distance between
dist = Math.sqrt(vx * vx + vy * vy);
// Are the intercepting
if (dist < A.r + B.r && dist > B.r - A.r) {
c = (B.r * B.r - (dist * dist + A.r * A.r)) / (-2 * dist);
// Find mid point on cord
x = A.x + vx * (c / dist);
y = A.y + vy * (c / dist);
mark(x, y, 5, "blue");
// Find circumference intercepts
//#################################################################
//=================================================================
// SVG path
// Use x1,y1 and x2,y2 as the start and end angles of the ArcTo SVG
d = Math.sqrt(A.r * A.r - c * c);
x1 = x - vy * (d / dist);
y1 = y + vx * (d / dist);
x2 = x + vy * (d / dist);
y2 = y - vx * (d / dist);
// SVG path from above coords
// d = `M ${x1}, ${y1} A ${A.r}, ${A,r1} 0, 1, 1, ${x2}, ${y2}`;
//=================================================================
// draw the chord
line({x: x1,y: y1}, {x: x2,y: y2}, "red");
// mark the intercepts
mark(x1, y1, 5, "Green");
mark(x2, y2, 5, "Orange");
// Get direction from A to B
dir = Math.atan2(vy, vx);
// Get half inside sweep
a1 = Math.acos(c / A.r);
// Draw arc for A
A.col = "black";
A.w = 4;
A.f = dir - a1;
A.t = dir + a1;
drawCircle(A);
A.col = "#aaa";
A.w = 2;
A.f = 0;
A.t = PI2;
// inside sweep for B
a2 = Math.asin(d / B.r);
// Draw arc for B
B.col = "black";
B.w = 4;
if (dist < c) {
B.t = dir - a2;
B.f = dir + a2;
} else {
B.f = dir + PI - a2;
B.t = dir + PI + a2;
}
drawCircle(B);
B.col = "#aaa";
B.w = 2;
B.f = 0;
B.t = PI2;
}
}
var w = canvas.width;
var h = canvas.height;
var cw = w / 2; // center
var ch = h / 2;
var C1 = circle(cw, ch, ch * 0.5, "#aaa");
var C2 = circle(cw, ch, ch * 0.8, "#aaa");
function update(timer) {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.globalAlpha = 1;
if (w !== innerWidth || h !== innerHeight) {
cw = (w = canvas.width = innerWidth) / 2;
ch = (h = canvas.height = innerHeight) / 2;
C1.x = cw;
C1.y = ch;
C1.r = ch * 0.5;
ctx.lineCap = "round";
}
C2.x = m.x;
C2.y = m.y;
ctx.clearRect(0, 0, w, h);
drawCircle(C1);
drawCircle(C2);
circleIntercept(C1, C2);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas {
position: absolute;
top: 0px;
left: 0px;
}
<canvas id="canvas"></canvas>