Published
Edited
Jul 13, 2020
7 stars
Insert cell
Insert cell
w = 540
Insert cell
Insert cell
p = getRandomPalette()
Insert cell
palette = shuffle(p)
Insert cell
Insert cell
bnb({
w, h,
numFrames: 100,
fps: 25,
record: true,
video: 'mp4',
shutterAngle: .8,
samplesPerFrame: 8,
setup: (s, g) => {
const rects = []
const margin = 40
divideRect4(margin, margin, w - 2 * margin, h - 2 * margin, 5, rects, .6)
g.tiles = rects.map(r => new Tile(r.x, r.y, r.w, r.n)).sort((a, b) => a.n < b.n ? 1 : a.n > b.n ? -1 : 0)
},
draw: (s, t, g) => {
s.background(palette[0])
s.translate(w/2, h/2)
s.rotate((ease(linearstep(t, 0.3, 0.45),2) + ease(linearstep(t, 0.8, 0.95),2)) * s.PI)
s.translate(-w/2, -h/2)
g.tiles.forEach(tile => tile.display(s, t))
}
})
Insert cell
class Tile {
constructor(x, y, w, n) {
this.x = x
this.y = y
this.w = w
this.n = n
this.angle = Math.PI / 2 * randInt(4)
this.isAnimated = random() < .5
this.offset = random(.1)
this.c1 = palette[randInt(1, palette.length)]
this.c2 = palette[randInt(1, palette.length)]
while(this.c1 === this.c2) this.c2 = palette[randInt(1, palette.length)]
}

display(s, t) {
s.push()
s.translate(this.x + this.w / 2, this.y + this.w / 2)

if(this.isAnimated) {
s.rotate((ease(linearstep(t, .05, .2), 2) + ease(linearstep(t, .55, .7), 2)) * s.PI/2)
}
else {
s.rotate((ease(linearstep(t, .3, .45), 2) + ease(linearstep(t, .8, .95), 2)) * s.PI/2)
}

s.noStroke()
// const c = (this.n % 2) ? 1 : 0
// s.fill(palette[c])
s.fill(this.c1)

s.rectMode(s.CENTER)
s.rect(0, 0, this.w, this.w)

s.circle(-this.w / 2, -this.w / 2, this.w / 3 * 2)
s.circle(this.w / 2, -this.w / 2, this.w / 3 * 2)
s.circle(this.w / 2, this.w / 2, this.w / 3 * 2)
s.circle(-this.w / 2, this.w / 2, this.w / 3 * 2)

s.rotate(this.angle)
s.noFill()
// s.stroke(palette[1 - c])
s.stroke(this.c2)
s.strokeWeight(this.w / 3)
s.strokeCap(s.ROUND)

s.arc(-this.w / 2, -this.w / 2, this.w, this.w, 0, s.PI/2)
s.arc(this.w / 2, this.w / 2, this.w, this.w, s.PI, s.PI*3/2)
s.pop()
}
}
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