Published
Edited
May 16, 2022
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
N = params.N || 8
Insert cell
seed = params.seed || Date.now()
Insert cell
p = params.p || getRandomPalette()
Insert cell
palette = params.palette || shuffle(p)
//palette = ["#262626", "#595959", "#d9d9d9", "#a6a6a6", "#0d0d0d"]
Insert cell
Insert cell
Insert cell
svg`<svg width="${w}" height="${h}" style="background: ${palette[0]}">
<style>
g {
/* testing different blend modes, only the last one is used
mix-blend-mode: normal;
mix-blend-mode: darken;
mix-blend-mode: exclusion;
mix-blend-mode: difference;
mix-blend-mode: overlay;
mix-blend-mode: soft-light;
mix-blend-mode: multiply;
mix-blend-mode: screen;
mix-blend-mode: hard-light;
*/
}
</style>

<defs>
${(() => {
const createClip = N => {
const size = w / N
return `<clipPath id="clip-${N}">
<rect
x="0"
y="0"
width="${size + .2}"
height="${size + .2}"
/>
</clipPath>`
}
const clips = []
for(let i = 2; i <= 32; i *= 2) {
clips.push(createClip(i))
}
return clips.join('')
})()}
</defs>

${(() => {
const prng = new PRNG(seed)
const createShapes = N => {
const size = w / N
let ny = Math.ceil(h / size)
if(ny % 2) ny ++
const marginY = (h - ny * size) / 2
return array(N).map((d, i, arr) => {
const x = i * size
return array(ny).map(j => {
const c = palette[prng.rand(1, palette.length-1)]
const y = marginY + j * size
const cx = prng.rand(1) * size
const cy = prng.rand(1) * size
const dir = prng.rand(1)
return `<g
transform="translate(${x}, ${y})"
clip-path="url(#clip-${N})"
>
${array(2).map(j => {
const lw = prng.rand(size)
const x1 = dir === 0 ? prng.rand(-size, size) : prng.rand(size * 2)
const x2 = x1 + (size + lw * 2) * (dir === 0 ? 1: -1)
// const x1 = prng.rand(-size, size)
// const x2 = x1 + size + lw * 2
return `<line
x1="${x1}"
y1="${-lw}"
x2="${x2}"
y2="${size + lw}"
stroke="${c}"
stroke-width="${lw*.8}"
opacity="${prng.rand(.95, 1.2)}"
/>`
}).join()}
</g>`
}).join('')
}).join('')
}
const shapes = []
for(let i = 64; i >= 4; i /= 2) {
shapes.push(createShapes(i))
}
return shapes.join('')
})()}
</svg>`
Insert cell
Insert cell
import {array, shuffle, cut, PRNG, TAU, randInt, random} from '@makio135/utilities'
Insert cell
import {getRandomPalette, displayPalettes} from '@makio135/give-me-colors'
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