canvas = {
const context = DOM.context2d(width, height);
const line = d3.lineRadial()
.context(context)
.curve(d3.curveLinearClosed)
.angle((r, i) => i * 2 * Math.PI / n)
.radius(r => r);
let prevTime = performance.now();
while (true) {
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.lineWidth = lineWidth;
context.lineJoin = "round";
context.globalCompositeOperation = glCompOp;
colors.forEach((color, j) => {
context.beginPath();
line(Float64Array.from({length: n}, (_, i) => {
const a = i * 2 * Math.PI / n;
const t = (paused ? prevTime : performance.now()) * speed;
const c = Math.cos(a * frequency - j * shift + t);
const p = Math.pow((1 + Math.cos(a - t)) / 2, 3);
return radius + amplitude * c * p;
}));
context.strokeStyle = color;
context.stroke();
});
context.restore();
yield context.canvas;
}
}