setup()
setup() runs once when the sketch starts. Here it's used to size the canvas, precompute the total cycle length so draw() doesn't need to add it up every frame, and populate the particles array up front so no particles need to be created later during animation.
function setup(){
createCanvas(windowWidth,windowHeight);textAlign(CENTER,CENTER);
c1=color(5,10,40);c2=color(60,20,90);
totalDur=phaseDur.reduce((a,b)=>a+b);
minR=60;maxR=min(width,height)*0.25;
for(let i=0;i<80;i++)particles.push({x:random(width),y:random(height),s:random(1,3),a:random(40,100),spd:random(0.05,0.3)});
}
Line-by-line explanation (5 lines)
🔧 Subcomponents:
for(let i=0;i<80;i++)particles.push({x:random(width),y:random(height),s:random(1,3),a:random(40,100),spd:random(0.05,0.3)});
Creates 80 particle objects, each with a random position, tiny size, random opacity, and its own upward drift speed
createCanvas(windowWidth,windowHeight);textAlign(CENTER,CENTER);- Makes the canvas fill the entire browser window and sets all future text() calls to be centered both horizontally and vertically on their coordinates
c1=color(5,10,40);c2=color(60,20,90);- Defines the two colors used for the background gradient - a very dark navy blue and a muted purple
totalDur=phaseDur.reduce((a,b)=>a+b);- Adds up all four phase durations (4000+2000+4000+2000) into one total, giving a 12000ms (12 second) full breathing cycle
minR=60;maxR=min(width,height)*0.25;- Sets the circle's smallest radius to 60 pixels, and its largest radius to a quarter of whichever screen dimension (width or height) is smaller, so it always fits on any screen
for(let i=0;i<80;i++)particles.push({x:random(width),y:random(height),s:random(1,3),a:random(40,100),spd:random(0.05,0.3)});- Runs 80 times, each time pushing a new particle object with random x/y position, size, alpha (opacity), and speed into the particles array