{
const context = DOM.context2d(width, height);
function drawCircle(i, now, above) {
const angle0 = (i / n + now / period1) % 1 * (2 * Math.PI);
const angle1 = angle0 + now / period2;
if ((Math.cos(angle1) < 0) === above) return;
context.save();
context.beginPath();
context.rotate(angle0);
context.translate(radius + Math.sin(angle1) * waveRadius, 0);
context.moveTo(ballRadius, 0);
context.arc(0, 0, ballRadius, 0, 2 * Math.PI);
context.lineWidth = gap * 2;
context.strokeStyle = "#fff";
context.stroke();
context.fillStyle = "#000";
context.fill();
context.restore();
}
while (true) {
const now = Date.now();
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
for (let i = 0; i < n; ++i) drawCircle(i, now, false);
context.beginPath();
context.moveTo(radius, 0);
context.arc(0, 0, radius, 0, 2 * Math.PI);
context.lineWidth = ballRadius + gap * 2;
context.strokeStyle = "#fff";
context.stroke();
context.lineWidth = ballRadius;
context.strokeStyle = "#000";
context.stroke();
for (let i = 0; i < n; ++i) drawCircle(i, now, true);
context.restore();
yield context.canvas;
}
}