Public
Edited
Apr 29
Insert cell
Insert cell
w = 842
Insert cell
Insert cell
seed = Date.now()
Insert cell
noiseScale = 2000
Insert cell
margin = 30
Insert cell
length = 40
Insert cell
strokeWidth = 20
Insert cell
strokeCap = 'butt' // butt, square or round
Insert cell
nMax = 6000
Insert cell
p = getRandomPalette()
Insert cell
//palette = shuffle(p)
//palette = ["#262425", "#77524c", "#fffefa", "#d79f90", "#df1c0a"]
palette = shuffle(["#1a202d", "#1a9ac1", "#e523c0", "#bf9749", "#a5a5a5"])
Insert cell
Insert cell
svg`<svg width="${w}" height="${h}">

<rect x="0" y="0" width="${w}" height="${h}" stroke="none" fill="${palette[0]}"></rect>

<g>
${(() => {
const lines = []

return array(nMax).map(d => {
const pos = PVector(Math.random(), Math.random()).mult(PVector(w, h).sub(2 * margin)).add(margin)
const angle = simplex.noise3D(pos.x / noiseScale, pos.y / noiseScale, seed) * Math.PI
const v = PVector.fromAngle(angle).setMag(length/2)
const line = new Line(pos.clone().add(v), pos.clone().sub(v))

if(lines.length < 1 || getIntersections(line, lines).length < 1) {
lines.push(line)
return `<polyline
stroke-width="1"
stroke-linecap="${strokeCap}"
stroke="${palette[1 + Math.random() * (palette.length - 1) | 0]}"
points="${line.a.x},${line.a.y} ${line.b.x},${line.b.y}"
/>`
}
}).filter(d => d).join('\n')
})()}
</g>
</svg>`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more