svg`<svg width="${w}" height="${h}">
<rect x="0" y="0" width="${w}" height="${h}" stroke="none " fill="${colorScale(1)}"></rect>
<g>
${(() => {
return attractors.map(d => `<circle stroke="none" fill="none" cx="${d.x}" cy="${d.y}" r="5" />`).join('\n')
})()}
</g>
<g transform="translate(${marginX}, ${marginY})">
${(() => {
return array(ny).map(i => {
const y = i * step
return array(nx).map(j => {
const x = j * step
const v = PVector(x, y)
const closest = attractors[attractors.map((d, i) => ({index: i, dist: v.clone().sub(d).mag()}))
.sort((a, b) => a.dist < b.dist ? -1 : a.dist > b.dist ? 1 : 0)[0].index]
const r = v.clone().sub(closest).mag()
let f = .3
return `<path transform="translate(${x}, ${y}) rotate(45) scale(${r/5})" opacity="0.5" fill="${colorScale(1 - r/400)}" stroke="none" d="M 1 0 C ${f} 0, 0 ${f}, 0 1 C 0 ${f}, -${f} 0, -1 0 C -${f} 0, 0 -${f}, 0 -1 C 0 -${f}, ${f} 0, 1 0" />`
}).join('\n')
}).join('\n')
})()}
</g>
</svg>`