class Box {
constructor(i, n) {
this.radius = 430;
this.w = map(i, 0, n - 1, 50, 150);
this.startAngle = random(TAU);
this.endAngle = this.startAngle + expRand(PI / 6, PI / 2);
this.black = random() < 0.75;
this.offset = random();
this.rot = random(TAU);
}
display(s, t, g) {
const tt = (t + this.offset) % 1;
const endAngle =
this.startAngle +
easings.easeQuadInOut(linearstep(tt, 0, 0.3)) *
(this.endAngle - this.startAngle);
const startAngle =
this.startAngle +
easings.easeQuadInOut(linearstep(tt, 0.35, 0.65)) *
(this.endAngle - this.startAngle);
if (endAngle - startAngle > 0.001) {
const white = 255;
const n = ((endAngle - startAngle) / 0.05) | 0;
const angles = array(n).map((i) =>
map(i, 0, n - 1, startAngle, endAngle)
);
const coses = array(n).map((i) => s.cos(angles[i]));
const sines = array(n).map((i) => s.sin(angles[i]));
s.push();
s.noStroke();
s.fill(this.black ? 150 : white);
s.beginShape(s.QUADS);
s.vertex(
coses[0] * (this.radius - this.w / 2),
-this.w / 2,
sines[0] * (this.radius - this.w / 2)
);
s.vertex(
coses[0] * (this.radius + this.w / 2),
-this.w / 2,
sines[0] * (this.radius + this.w / 2)
);
s.vertex(
coses[0] * (this.radius + this.w / 2),
+this.w / 2,
sines[0] * (this.radius + this.w / 2)
);
s.vertex(
coses[0] * (this.radius - this.w / 2),
+this.w / 2,
sines[0] * (this.radius - this.w / 2)
);
s.endShape();
s.beginShape(s.QUADS);
s.vertex(
coses[n - 1] * (this.radius - this.w / 2),
-this.w / 2,
sines[n - 1] * (this.radius - this.w / 2)
);
s.vertex(
coses[n - 1] * (this.radius + this.w / 2),
-this.w / 2,
sines[n - 1] * (this.radius + this.w / 2)
);
s.vertex(
coses[n - 1] * (this.radius + this.w / 2),
+this.w / 2,
sines[n - 1] * (this.radius + this.w / 2)
);
s.vertex(
coses[n - 1] * (this.radius - this.w / 2),
+this.w / 2,
sines[n - 1] * (this.radius - this.w / 2)
);
s.endShape();
//top
s.beginShape(s.TRIANGLE_STRIP);
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius - this.w / 2),
-this.w / 2,
sines[i] * (this.radius - this.w / 2)
);
s.vertex(
coses[i] * (this.radius + this.w / 2),
-this.w / 2,
sines[i] * (this.radius + this.w / 2)
);
});
s.endShape();
//bottom
s.beginShape(s.TRIANGLE_STRIP);
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius - this.w / 2),
+this.w / 2,
sines[i] * (this.radius - this.w / 2)
);
s.vertex(
coses[i] * (this.radius + this.w / 2),
+this.w / 2,
sines[i] * (this.radius + this.w / 2)
);
});
s.endShape();
//inner
s.beginShape(s.TRIANGLE_STRIP);
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius - this.w / 2),
+this.w / 2,
sines[i] * (this.radius - this.w / 2)
);
s.vertex(
coses[i] * (this.radius - this.w / 2),
-this.w / 2,
sines[i] * (this.radius - this.w / 2)
);
});
s.endShape();
//outer
s.beginShape(s.TRIANGLE_STRIP);
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius + this.w / 2),
+this.w / 2,
sines[i] * (this.radius + this.w / 2)
);
s.vertex(
coses[i] * (this.radius + this.w / 2),
-this.w / 2,
sines[i] * (this.radius + this.w / 2)
);
});
s.endShape();
s.noFill();
s.strokeWeight(7);
s.stroke(this.black ? white : 30);
const m = 0;
s.beginShape();
s.vertex(
coses[0] * (this.radius - (this.w / 2 + m)),
-(this.w / 2 + m),
sines[0] * (this.radius - (this.w / 2 + m))
);
s.vertex(
coses[0] * (this.radius + (this.w / 2 + m)),
-(this.w / 2 + m),
sines[0] * (this.radius + (this.w / 2 + m))
);
s.vertex(
coses[0] * (this.radius + (this.w / 2 + m)),
+(this.w / 2 + m),
sines[0] * (this.radius + (this.w / 2 + m))
);
s.vertex(
coses[0] * (this.radius - (this.w / 2 + m)),
+(this.w / 2 + m),
sines[0] * (this.radius - (this.w / 2 + m))
);
s.endShape(s.CLOSE);
s.beginShape();
s.vertex(
coses[n - 1] * (this.radius - (this.w / 2 + m)),
-(this.w / 2 + m),
sines[n - 1] * (this.radius - (this.w / 2 + m))
);
s.vertex(
coses[n - 1] * (this.radius + (this.w / 2 + m)),
-(this.w / 2 + m),
sines[n - 1] * (this.radius + (this.w / 2 + m))
);
s.vertex(
coses[n - 1] * (this.radius + (this.w / 2 + m)),
+(this.w / 2 + m),
sines[n - 1] * (this.radius + (this.w / 2 + m))
);
s.vertex(
coses[n - 1] * (this.radius - (this.w / 2 + m)),
+(this.w / 2 + m),
sines[n - 1] * (this.radius - (this.w / 2 + m))
);
s.endShape(s.CLOSE);
//top
s.beginShape();
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius - (this.w / 2 + m)),
-(this.w / 2 + m),
sines[i] * (this.radius - (this.w / 2 + m))
);
});
s.endShape();
s.beginShape();
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius + (this.w / 2 + m)),
-(this.w / 2 + m),
sines[i] * (this.radius + (this.w / 2 + m))
);
});
s.endShape();
//bottom
s.beginShape();
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius - (this.w / 2 + m)),
+(this.w / 2 + m),
sines[i] * (this.radius - (this.w / 2 + m))
);
});
s.endShape();
s.beginShape();
array(n).forEach((i) => {
s.vertex(
coses[i] * (this.radius + (this.w / 2 + m)),
+(this.w / 2 + m),
sines[i] * (this.radius + (this.w / 2 + m))
);
});
s.endShape();
s.noStroke();
s.pop();
}
}
}