Public
Edited
May 10, 2023
1 fork
7 stars
Insert cell
Insert cell
{
const width = 240 * 3
const height = 360 * 3
const ctx = DOM.context2d(width, height)

function ease(x) {
return -(Math.cos(Math.PI * x) - 1) / 2;
}

function split(node){

if (node.depth > 12){
return
}
if (Math.random() < 0.1 && node.depth > 8){
return
}

const color_shift = 2/node.depth
const axis = (node.axis == "vertical") ? "horizontal" : "vertical"
node.left = {left: null, right: null, ratio: 0.0, axis: axis, color: node.color, depth: node.depth + 1, parent:node}
node.right = {left: null, right: null, ratio: 0.0, axis: axis, color: node.color + randRange(0, color_shift), depth: node.depth + 1,parent:node}
node.ratio = randRange(.3, .7)

split(node.left)
split(node.right)
}
function isLeaf(node){
return (node.left == null && node.right == null)
}


function draw(ctx, root, box){
const scale = colorScales.interpolateSpectral
if (isLeaf(root)){
ctx.beginPath()
ctx.fillStyle = scale(Math.cos(root.color) * .5 + .5)
ctx.rect(box.x + randRange(-1,1), box.y + randRange(-1,1), box.w + randRange(-1,1), box.h + randRange(-1,1))
ctx.fill()
//ctx.stroke()
}
else {
box.x += 2/root.depth
box.y += 2/root.depth
box.w -= 4/root.depth
box.h -= 4/root.depth
const split_boxes = splitBox(box, root.ratio, root.axis)
draw(ctx, root.left, split_boxes.left)
draw(ctx, root.right, split_boxes.right)
}
}

const root = {left: null, right: null, ratio: 0.0, axis: "horizontal", color: 0, depth: 1}


split(root)

ctx.fillStyle = "#403F3B"
ctx.fillRect(0,0,width, height)
draw(ctx, root, {x:0, y:0, w: width, h:height})

return ctx.canvas



}
Insert cell
function splitBox(box, ratio, axis){
if (axis == "horizontal"){
return {
left: {
x: box.x,
y: box.y,
w: box.w * ratio,
h: box.h
},
right:{
x: box.x + (box.w * ratio),
y: box.y,
w: box.w * (1- ratio),
h: box.h
},
}
} else if (axis == "vertical"){
return {
left: {
x: box.x,
y: box.y,
w: box.w,
h: box.h * ratio
},
right:{
x: box.x,
y: box.y + (box.h * ratio),
w: box.w,
h: box.h * (1- ratio)
},
}
} else {
throw "unknown split direction"
}
}
Insert cell
function randChoice(arr){
let idx = Math.floor(randRange(0, arr.length))
return arr[idx]
}
Insert cell
function randRange(min, max){
return min + Math.random() * (max - min)
}
Insert cell
colorScales = import("d3-scale-chromatic")
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