{
const W = width;
const H = 600;
const ctx = DOM.context2d(W, H);
let t = 0;
function drawDynamicPattern(shapes) {
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, W, H);
shapes.forEach(({ baseRadius, oscillationAmplitude, speed, direction, color, edges }) => {
ctx.beginPath();
ctx.lineWidth = 1;
for (let i = 0; i <= 360; i++) {
const angle = Math.PI * 2 * i / 360;
const oscillation = Math.sin(t * speed) * oscillationAmplitude + Math.sin(t * direction) * 20;
const radius = baseRadius + oscillation * Math.sin(angle * edges);
const x = W / 2 + Math.sin(angle) * radius;
const y = H / 2 + Math.cos(angle) * radius;
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
ctx.strokeStyle = `rgb(${color})`;
ctx.stroke();
});
t += 0.02;
}
return Generators.observe(notify => {
const render = () => {
const shapes = generateShapes(numberOfShapes, variance, edges);
drawDynamicPattern(shapes);
notify(ctx.canvas);
};
render();
const interval = setInterval(render, 50);
return () => clearInterval(interval);
});
}