Chime constructor()
The constructor runs once per Chime object when it's created with 'new Chime(...)'. It's the perfect place to set up starting state and calculate anything that doesn't need to change every frame, like the tube's fixed frequency.
constructor(index, total) {
this.index = index;
this.total = total;
// Pendulum physics state
this.angle = 0;
this.angleVel = 0;
this.angleAcc = 0;
this.damping = 0.995; // how quickly it slows down
this.k = 0.02; // springiness (restoring force)
// Geometry (set in updateGeometry so it recomputes on resize)
this.x0 = 0;
this.y0 = 0;
this.length = 0;
this.updateGeometry();
// Sound: longer tube = lower frequency
const freqHigh = 880; // short tube, higher pitch
const freqLow = 220; // long tube, lower pitch
const t = total > 1 ? index / (total - 1) : 0;
this.freq = lerp(freqHigh, freqLow, t);
this.osc = new p5.Oscillator('sine');
this.osc.freq(this.freq);
this.osc.amp(0); // start silent
this.osc.start();
}
Line-by-line explanation (9 lines)
🔧 Subcomponents:
const t = total > 1 ? index / (total - 1) : 0;
Avoids dividing by zero when there's only one chime, and normalizes the index to a 0-1 range for pitch interpolation
this.index = index;- Remembers which position (0 to 4) this chime occupies, used later for spacing and pitch
this.damping = 0.995; // how quickly it slows down- A multiplier applied to velocity each frame - values just under 1 slowly bleed off swing energy like air resistance
this.k = 0.02; // springiness (restoring force)- How strongly the chime is pulled back toward angle zero, like a spring constant
this.updateGeometry();- Calls the method that computes this chime's x/y position and tube length based on canvas size
const t = total > 1 ? index / (total - 1) : 0;- Converts the chime's index into a fraction from 0 to 1 so it can be used to interpolate pitch
this.freq = lerp(freqHigh, freqLow, t);- Blends between the high and low frequency based on t, so tube 0 is highest-pitched and the last tube is lowest-pitched
this.osc = new p5.Oscillator('sine');- Creates a sine-wave sound generator for this chime using the p5.sound library
this.osc.amp(0); // start silent- Sets the oscillator's volume to zero so it's silent until strike() is called
this.osc.start();- Starts the oscillator running continuously in the background - it's always 'on' but silent until amp is raised