{
replay;
await visibility();
const bricksPerSecond = 30;
const gradient = DOM.uid("gradient");
const padding = paddingRatio * brickWidth * unitSize;
const width = brickWidth * unitSize + 2 * padding;
const height = brickHeight * unitSize + 2 * padding;
const container = svg`
<svg viewBox="${-padding}, ${-padding}, ${width}, ${height}"
style="width: 100%; height: 100%; display: block;">
<defs>
<linearGradient id="${gradient.id}" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color: #fff; stop-opacity: 0.2;"/>
<stop offset="100%" style="stop-color: #000; stop-opacity: 0.2;"/>
</linearGradient>
</defs>
<rect x="${-padding}" y="${-padding}"
width="${width}" height="${height}"
fill="#eee"/>
</svg>`;
yield container;
for (const { x, y, width, height, color } of bricks) {
const dotsSvg = Array.from({ length: width * height }).map((_, i) => {
const dotX = i % width;
const dotY = Math.floor(i / width);
const cx = (dotX + 0.5) * unitSize;
const cy = (dotY + 0.5) * unitSize;
return svg`
<circle cx="${cx - 1}" cy="${cy - 1}" r="${brickRadius}" fill="#fff"/>
<circle cx="${cx + 1}" cy="${cy + 1}" r="${brickRadius}" fill="#000"/>
<circle cx="${cx}" cy="${cy}" r="${brickRadius}" fill="${
colors[color]
}"/>
<circle cx="${cx}" cy="${cy}" r="${brickRadius}" fill="${gradient}"/>`;
});
await Promises.tick(1000 / bricksPerSecond);
container.append(svg`
<g transform="translate(${x * unitSize}, ${y * unitSize})">
<rect x="${brickBorder}" y="${brickBorder}"
width="${width * unitSize - 2 * brickBorder}"
height="${height * unitSize - 2 * brickBorder}"
fill="${colors[color]}"/>
${dotsSvg}
</g>`);
}
}