Published
Edited
Apr 24, 2020
1 fork
8 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
seed = Date.now()
Insert cell
n = 800
Insert cell
Insert cell
colorScale = scales.inferno
//colorScale = scales.procScale([0.29,0.47,0.08],[0.04,0.47,0.58],[0.01,0.94,0.2],[0.17,0.7,0.77])

Insert cell
Insert cell
svg`<svg width="${w}" height="${h}">
<defs>
${array(n).map(i => {
return `<linearGradient id="linegrad${i}" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="${colorScale(random(.2))}"/>
<stop offset="100%" stop-color="${colorScale(random(.5, 1))}"/>
</linearGradient>`
}).join('\n')}

${array(n).map(i => {
const offset = random(10)
return `<filter id="shadow${i}" x="-50%" y="-50%" width="200%" height="200%">
<feOffset result="offOut" in="SourceGraphic" dx="${offset}" dy="${offset}" />
<feColorMatrix result = "matrixOut" in = "offOut" type = "matrix" values = "0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0"/>
<feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>`
}).join('\n')}

<mask id="Mask">
<rect x="0" y="0" width="${w}" height="${h}" fill="white" />
<rect x="${margin}" y="${margin}" width="${w - margin * 2}" height="${h - margin * 2}" fill="black" />
</mask>
</defs>

<rect x="0" y="0" width="${w}" height="${h}" fill="${colorScale(0)}" />

${shuffle(array(n)).map((index, j) => {
const y = -200 + (h + 400) / n * index
return `<path
opacity="0.8"
stroke="url(#linegrad${index})"
stroke-width="${random(5, 5 +(n-j)/2)}"
stroke-dasharray="${array(10).map(() => random() < .6 ? randInt(2, 400) : random(2, 20)).join(" ")}"
fill="none"
filter="url(#shadow${index})"
d="M -30 ${y} C ${w / 3} ${y + simplex.noise3D(w / 3 / noiseScale, y / noiseScale, seed) * h} ${w / 3 * 2} ${y + simplex.noise3D(w / 3 * 2/ noiseScale, (y-400) / noiseScale, seed) * h} ${w + 30} ${y-400}"
/>`
}).join('\n')}

<rect
x="0"
y="0"
width="${w}"
height="${h}"
stroke="none"
fill="black"
fill="${colorScale(0)}"
mask="url(#Mask)"
/>
${shuffle(array(40)).map((index, j) => {
const y = -200 + (h + 400) / n * randInt(100, n)
return `<path
opacity="0.8"
stroke="url(#linegrad${index})"
stroke-width="${random(5, 45)}"
stroke-dasharray="0 ${random(250, 350)} ${array(10).map(() => random() < .6 ? randInt(2, 400) : random(2, 20)).join(" ")}"
fill="none"
filter="url(#shadow${index})"
d="M -30 ${y} C ${w / 3} ${y + simplex.noise3D(w / 3 / noiseScale, y / noiseScale, seed) * h} ${w / 3 * 2} ${y + simplex.noise3D(w / 3 * 2/ noiseScale, (y-400) / noiseScale, seed) * h} ${w + 30} ${y-400}"
/>`
}).join('\n')}

<!--
<rect
x="0"
y="0"
width="${margin}"
height="${h}"
stroke="none"
fill="black"
/>
-->
<rect
x="0"
y="${h-margin}"
width="${w}"
height="${margin}"
stroke="none"
fill="black"
/>
</svg>`
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