canvas = {
const colors = ["cyan", "magenta", "yellow"];
const shift = (2 * Math.PI) / 3;
const speed = 1 / 2500;
const n = 360;
const frequency = 7;
const amplitude = 15;
const height = 640;
const radius = Math.min(width, height) / 2 - amplitude * 2;
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);
while (true) {
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.lineWidth = 5;
context.lineJoin = "round";
context.globalCompositeOperation = "multiply";
colors.forEach((color, j) => {
context.beginPath();
line(
Float64Array.from({ length: n }, (_, i) => {
const a = (i * 2 * Math.PI) / n;
const t = performance.now() * speed;
const c = Math.cos(a * frequency - j * shift + t);
const p = Math.pow((1 + Math.cos(a - t)) / 2, 1);
return radius + amplitude * c * p;
})
);
context.strokeStyle = color;
context.stroke();
});
context.restore();
yield context.canvas;
}
}