Two circles intersect at 0, 1, or 2 points. Drop a perpendicular from the line between centres at distance a, then step ±h along it. The first circle is fixed; the second follows the mouse.
See also: Circle ↔ line intersection — same idea (foot of perpendicular ± offset), with a line replacing the second circle.
d = distance(c1, c2)
if (d > r1 + r2) return [] // too far apart
if (d < |r1 - r2|) return [] // one contained
a = (r1*r1 - r2*r2 + d*d) / (2 * d)
h = sqrt(r1*r1 - a*a)
mid = c1 + (c2 - c1) * (a / d)
perp = perpendicular(c2 - c1) / d // unit, 90°
return [mid + perp * h, mid - perp * h]
const c1x = 120, c1y = 150, r1 = 70
const c2x = mouseX, c2y = mouseY, r2 = 55
const dx = c2x - c1x
const dy = c2y - c1y
const d = Math.sqrt(dx * dx + dy * dy)
if (d > r1 + r2 || d < Math.abs(r1 - r2) || d === 0) {
// no intersection
} else {
const a = (r1 * r1 - r2 * r2 + d * d) / (2 * d)
const h = Math.sqrt(r1 * r1 - a * a)
const mx = c1x + dx * a / d
const my = c1y + dy * a / d
// perpendicular to (dx, dy), scaled by h/d
const ix1 = mx + (dy * h / d)
const iy1 = my - (dx * h / d)
const ix2 = mx - (dy * h / d)
const iy2 = my + (dx * h / d)
}