260531
const animate = anime.animate;
const CANVAS_WIDTH = 800;
const CANVAS_HEIGHT = 800;
const SPHERE_COUNT = 5;
const STAGGER_DELAY = 220;
const JUMP_DURATION = 800;
const PAUSE_DURATION = 1000;
const ONE_JUMP_CYCLE = JUMP_DURATION + PAUSE_DURATION;
const WAVE_DURATION = ONE_JUMP_CYCLE + STAGGER_DELAY * (SPHERE_COUNT - 1);
const CAMERA_TRANSITION = 400;
const ONE_CAMERA_CYCLE = WAVE_DURATION + CAMERA_TRANSITION;
const SPHERE_RADIUS = 50;
const BOX_SIZE = SPHERE_RADIUS * 2;
const SPHERE_GAP = BOX_SIZE * 1.5;
const JUMP_HEIGHT = BOX_SIZE * 1.8;
let palette = [];
let sphereStates = [];
let camera = { progress: 0 };
let cameraAngles = [];
let isWavePlaying = false;
function setup() {
const cameraTilt = TAU / 16;
const cameraTurn = TAU / 16;
cameraAngles = [
{ rotX: -cameraTilt, rotY: cameraTurn },
{ rotX: 0, rotY: 0 },
{ rotX: -cameraTilt, rotY: -cameraTurn },
];
sphereStates = [];
for (let i = 0; i < SPHERE_COUNT; i++) {
sphereStates.push({ count: 0, arc: 0 });
}
createCanvas(CANVAS_WIDTH, CANVAS_HEIGHT, WEBGL);
palette = colorArray[2].colors;
background(palette[0]);
camera.progress = 0;
animate(camera, {
progress: 3,
ease: "linear",
duration: ONE_CAMERA_CYCLE * 3,
loop: true,
onUpdate: () => {
const waveNow = isWavePhase(camera.progress);
if (waveNow && !isWavePlaying) startWave();
isWavePlaying = waveNow;
},
});
startWave();
}
function draw() {
background(palette[0]);
ortho();
noStroke();
strokeWeight(2);
push();
applyCamera(camera.progress);
for (let i = 0; i < SPHERE_COUNT; i++) {
const state = sphereStates[i];
const centerX = (i - (SPHERE_COUNT - 1) / 2) * SPHERE_GAP;
const boxHeight = state.count * BOX_SIZE;
const sphereY = getSphereYOffset(state.arc);
drawSphereAndBox(centerX, sphereY, boxHeight);
}
pop();
}
function isWavePhase(progress) {
const fraction = progress - floor(progress);
return fraction < WAVE_DURATION / ONE_CAMERA_CYCLE;
}
function getCameraRotation(progress) {
const stepIndex = floor(progress) % 3;
const fraction = progress - floor(progress);
const fromAngle = cameraAngles[stepIndex];
const toAngle = cameraAngles[(stepIndex + 1) % 3];
const wavePart = WAVE_DURATION / ONE_CAMERA_CYCLE;
if (fraction < wavePart) {
return fromAngle;
}
const blend = (fraction - wavePart) / (1 - wavePart);
return {
rotX: lerp(fromAngle.rotX, toAngle.rotX, blend),
rotY: lerp(fromAngle.rotY, toAngle.rotY, blend),
};
}
function startWave() {
for (let i = 0; i < SPHERE_COUNT; i++) {
const state = sphereStates[i];
state.count = 0;
state.arc = 0;
animate(state, {
count: [
{ to: 1, ease: "outExpo", duration: JUMP_DURATION },
{ to: 0, ease: "inExpo", duration: PAUSE_DURATION },
],
arc: [
{ to: 1, ease: "out(3)", duration: JUMP_DURATION * 0.5 },
{ to: 0, ease: "in(3)", duration: JUMP_DURATION * 0.5 },
],
duration: ONE_JUMP_CYCLE,
loop: false,
delay: i * STAGGER_DELAY,
});
}
}
function applyCamera(progress) {
const rotation = getCameraRotation(progress);
rotateX(rotation.rotX);
rotateY(rotation.rotY);
}
function getSphereYOffset(jumpAmount) {
const restY = BOX_SIZE / 2;
return restY - jumpAmount * JUMP_HEIGHT;
}
function drawSphereAndBox(centerX, sphereY, boxHeight) {
push();
translate(centerX, 0, 0);
push();
fill(palette[1]);
translate(0, sphereY, 0);
sphere(SPHERE_RADIUS);
pop();
push();
noFill();
stroke(palette[3]);
translate(0, BOX_SIZE - boxHeight / 2, 0);
box(BOX_SIZE, boxHeight, BOX_SIZE);
pop();
pop();
}
const colorArray = [
{
id: 0,
colors: ["#253276", "#dfdad3", "#ffffff", "#000000"],
},
{
id: 1,
colors: [
"#9dbdba",
"#f8b042",
"#e47763",
"#253276",
"#dfdad3",
"#FFFFFF",
"#000000",
],
},
{
id: 2,
colors: ["#758492", "#CCE7FF", "#ece6d7", "#ffffff", "#111111"],
},
]; const animate = anime.animate;
const CANVAS_WIDTH = 800;
const CANVAS_HEIGHT = 800;
const SPHERE_COUNT = 5;
const STAGGER_DELAY = 220;
const JUMP_DURATION = 800;
const PAUSE_DURATION = 1000;
const ONE_JUMP_CYCLE = JUMP_DURATION + PAUSE_DURATION;
const WAVE_DURATION = ONE_JUMP_CYCLE + STAGGER_DELAY * (SPHERE_COUNT - 1);
const CAMERA_TRANSITION = 400;
const ONE_CAMERA_CYCLE = WAVE_DURATION + CAMERA_TRANSITION;
const SPHERE_RADIUS = 50;
const BOX_SIZE = SPHERE_RADIUS * 2;
const SPHERE_GAP = BOX_SIZE * 1.5;
const JUMP_HEIGHT = BOX_SIZE * 1.8;
let palette = [];
let sphereStates = [];
let camera = { progress: 0 };
let cameraAngles = [];
let isWavePlaying = false;
function setup() {
const cameraTilt = TAU / 16;
const cameraTurn = TAU / 16;
cameraAngles = [
{ rotX: -cameraTilt, rotY: cameraTurn },
{ rotX: 0, rotY: 0 },
{ rotX: -cameraTilt, rotY: -cameraTurn },
];
sphereStates = [];
for (let i = 0; i < SPHERE_COUNT; i++) {
sphereStates.push({ count: 0, arc: 0 });
}
createCanvas(CANVAS_WIDTH, CANVAS_HEIGHT, WEBGL);
palette = colorArray[2].colors;
background(palette[0]);
camera.progress = 0;
animate(camera, {
progress: 3,
ease: "linear",
duration: ONE_CAMERA_CYCLE * 3,
loop: true,
onUpdate: () => {
const waveNow = isWavePhase(camera.progress);
if (waveNow && !isWavePlaying) startWave();
isWavePlaying = waveNow;
},
});
startWave();
}
function draw() {
background(palette[0]);
ortho();
noStroke();
strokeWeight(2);
push();
applyCamera(camera.progress);
for (let i = 0; i < SPHERE_COUNT; i++) {
const state = sphereStates[i];
const centerX = (i - (SPHERE_COUNT - 1) / 2) * SPHERE_GAP;
const boxHeight = state.count * BOX_SIZE;
const sphereY = getSphereYOffset(state.arc);
drawSphereAndBox(centerX, sphereY, boxHeight);
}
pop();
}
function isWavePhase(progress) {
const fraction = progress - floor(progress);
return fraction < WAVE_DURATION / ONE_CAMERA_CYCLE;
}
function getCameraRotation(progress) {
const stepIndex = floor(progress) % 3;
const fraction = progress - floor(progress);
const fromAngle = cameraAngles[stepIndex];
const toAngle = cameraAngles[(stepIndex + 1) % 3];
const wavePart = WAVE_DURATION / ONE_CAMERA_CYCLE;
if (fraction < wavePart) {
return fromAngle;
}
const blend = (fraction - wavePart) / (1 - wavePart);
return {
rotX: lerp(fromAngle.rotX, toAngle.rotX, blend),
rotY: lerp(fromAngle.rotY, toAngle.rotY, blend),
};
}
function startWave() {
for (let i = 0; i < SPHERE_COUNT; i++) {
const state = sphereStates[i];
state.count = 0;
state.arc = 0;
animate(state, {
count: [
{ to: 1, ease: "outExpo", duration: JUMP_DURATION },
{ to: 0, ease: "inExpo", duration: PAUSE_DURATION },
],
arc: [
{ to: 1, ease: "out(3)", duration: JUMP_DURATION * 0.5 },
{ to: 0, ease: "in(3)", duration: JUMP_DURATION * 0.5 },
],
duration: ONE_JUMP_CYCLE,
loop: false,
delay: i * STAGGER_DELAY,
});
}
}
function applyCamera(progress) {
const rotation = getCameraRotation(progress);
rotateX(rotation.rotX);
rotateY(rotation.rotY);
}
function getSphereYOffset(jumpAmount) {
const restY = BOX_SIZE / 2;
return restY - jumpAmount * JUMP_HEIGHT;
}
function drawSphereAndBox(centerX, sphereY, boxHeight) {
push();
translate(centerX, 0, 0);
push();
fill(palette[1]);
translate(0, sphereY, 0);
sphere(SPHERE_RADIUS);
pop();
push();
noFill();
stroke(palette[3]);
translate(0, BOX_SIZE - boxHeight / 2, 0);
box(BOX_SIZE, boxHeight, BOX_SIZE);
pop();
pop();
}
const colorArray = [
{
id: 0,
colors: ["#253276", "#dfdad3", "#ffffff", "#000000"],
},
{
id: 1,
colors: [
"#9dbdba",
"#f8b042",
"#e47763",
"#253276",
"#dfdad3",
"#FFFFFF",
"#000000",
],
},
{
id: 2,
colors: ["#758492", "#CCE7FF", "#ece6d7", "#ffffff", "#111111"],
},
];