constructor(index, total)
The constructor runs once when each Chime object is created. It sets up all the physics variables needed for pendulum motion, calculates the geometric position and size, and creates an audio oscillator that's ready to play. The key insight is that each oscillator starts silent but is always running—we control when you hear it by changing the amplitude in the strike() method.
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();
}
đź”§ Subcomponents:
this.angle = 0; this.angleVel = 0; this.angleAcc = 0;
Sets up the pendulum motion variables: angle (current swing position), angleVel (how fast it's swinging), and angleAcc (how the force changes the velocity)
const t = total > 1 ? index / (total - 1) : 0; this.freq = lerp(freqHigh, freqLow, t);
Maps tube index to a frequency: first tube gets 880Hz (high), last tube gets 220Hz (low), middle tubes get frequencies in between using lerp()
this.osc = new p5.Oscillator('sine'); this.osc.freq(this.freq); this.osc.amp(0); this.osc.start();
Creates a sine wave oscillator at the calculated frequency, sets it to silent (amp 0), and starts it running (ready to play when strike() is called)
Line by Line:
this.index = index;- Stores which chime this is (0-4), used to calculate position and frequency
this.total = total;- Stores the total number of chimes (5), used for spacing and frequency calculations
this.angle = 0;- Initializes the pendulum angle to 0 (vertical, at rest)
this.angleVel = 0;- Initializes angular velocity to 0 (not moving yet)
this.angleAcc = 0;- Initializes angular acceleration to 0 (no forces acting yet)
this.damping = 0.995;- Sets damping to 0.995, meaning each frame the velocity is multiplied by 0.995, gradually slowing the swing (0.995 = 0.5% energy loss per frame)
this.k = 0.02;- Sets the spring constant (restoring force strength), controlling how quickly the pendulum returns to center. Higher values = faster return
this.updateGeometry();- Calls the method that calculates x0, y0, and length based on current canvas size
const t = total > 1 ? index / (total - 1) : 0;- Calculates a normalized value t from 0 to 1: if index=0, t=0; if index=4, t=1; this maps the tube position to a frequency range
this.freq = lerp(freqHigh, freqLow, t);- Uses lerp() to interpolate between 880Hz and 220Hz based on t, so first tube is high pitch, last tube is low pitch
this.osc = new p5.Oscillator('sine');- Creates a new sine wave oscillator (smooth, musical tone)
this.osc.freq(this.freq);- Sets the oscillator's frequency to the calculated frequency for this chime
this.osc.amp(0);- Sets the oscillator's amplitude (volume) to 0, so it's silent until strike() is called
this.osc.start();- Starts the oscillator running in the background (it's always generating sound, but at 0 volume)