function initSketch({ centres, w, h, debug, strokeWidth = 1 } = {}) {
const negativePadding = maxRadius;
const svg = htl.svg`<svg width=${w} height=${h} viewbox=${[
negativePadding,
negativePadding,
w - 2 * negativePadding,
h - 2 * negativePadding
]}>`;
d3.select(svg)
.append("rect")
.attr("width", w)
.attr("height", h)
.attr("fill", palette.bg);
const circles = d3
.select(svg)
.append("g")
.attr("class", "circles")
.style("mix-blend-mode", palette.blend ?? "normal")
.selectAll(".circle")
.data(centres)
.join("circle")
.attr("class", "circle")
.attr("r", 1)
.attr("fill", "none")
.attr("stroke", palette.fg)
.attr("cx", (d) => d[0])
.attr("cy", (d) => d[1]);
if (debug) {
const debugG = d3.select(svg).append("g").attr("class", "debug");
debugG
.selectAll("circle")
.data(centres)
.join("circle")
.attr("r", 1)
.attr("fill", palette.debug)
.attr("cx", (d) => d[0])
.attr("cy", (d) => d[1]);
debugG
.selectAll(".hexagon")
.data(centres)
.join("path")
.attr("class", "hexagon")
.attr("transform", (d) => `translate(${d[0]},${d[1]})`)
.attr("fill", "none")
.attr("stroke", palette.debug)
.attr("stroke-width", 1)
.attr("d", hexbin.hexagon());
}
function draw(T = 0) {
const t = eases.sineInOut(T);
const r = math.lerp(minRadius, maxRadius, t);
circles.attr("r", r);
}
return Object.assign(svg, { draw });
}