svg`<svg width="${w}" height="${h}">
<rect x="0" y="0" width="${w}" height="${h}" stroke="none" fill="black"></rect>
<g transform="translate(${marginX}, ${marginY})">
${(() => {
return array(ny).map(i => {
const y = i * step
return array(nx).map(j => {
let x = j * step
let v = PVector(x, y)
return `<path
stroke="rgba(${x/w * 255}, ${y/h * 255}, 127, 0.2)"
fill="none"
d="M${x} ${y} ${array(trailLength).map(() => {
const isInside = v.x >= 0 && v.x <= w && v.y >= 0 && v.y <= h
if(!isInside) return
const angle = simplex.noise3D(v.x/noiseScale, v.y/noiseScale, seed) * TAU
v.add(PVector.fromAngle(angle).setMag(stepLength))
return `L${v.x} ${v.y}`
}).filter(d => d).join(' ')}"
/>`
}).join('\n')
}).join('\n')
})()}
</g>
</svg>`