@joshtol/emotive-engine 3.3.6 → 3.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@joshtol/emotive-engine",
4
- "version": "3.3.6",
4
+ "version": "3.3.7",
5
5
  "description": "Open-source animation engine for AI-controlled emotional visualizations with musical time synchronization",
6
6
  "main": "dist/emotive-mascot.umd.js",
7
7
  "module": "dist/mascot.js",
@@ -539,26 +539,27 @@ export class Rhythm3DAdapter {
539
539
  // This is frame-rate independent because beatProgress/barProgress come from
540
540
  // RhythmEngine which uses performance.now(), not accumulated frame deltas
541
541
  //
542
- // Apply BPM multiplier to scale animation speed:
543
- // - multiplier 0.5 = animations run at half speed (for high BPM songs)
544
- // - multiplier 2.0 = animations run at double speed (for slow songs)
545
- const effectiveBeatProgress = (this.beatProgress * this.bpmMultiplier) % 1;
546
- const effectiveBarProgress = (this.barProgress * this.bpmMultiplier) % 1;
542
+ // BPM multiplier scales animation FREQUENCY (not progress value):
543
+ // - multiplier 0.5 = animations take 2 beats to complete one cycle (half speed)
544
+ // - multiplier 2.0 = animations complete 2 cycles per beat (double speed)
545
+ // Applied directly to the phase calculation, not the progress value
547
546
 
548
547
  // Vertical bounce: synced to beat with configurable frequency
549
- const bouncePhase = (effectiveBeatProgress * bounceFreq * Math.PI * 2) + phaseOffset;
548
+ // bpmMultiplier scales the frequency so 0.5 = half as many bounces per beat
549
+ const bouncePhase = (this.beatProgress * bounceFreq * this.bpmMultiplier * Math.PI * 2) + phaseOffset;
550
550
  const rawBounce = Math.sin(bouncePhase);
551
551
  const easedBounce = this._applyEasing(rawBounce, easing);
552
552
 
553
553
  // Horizontal sway: synced to bar with configurable frequency
554
- const swayPhase = (effectiveBarProgress * swayFreq * Math.PI * 2) + phaseOffset;
554
+ const swayPhase = (this.barProgress * swayFreq * this.bpmMultiplier * Math.PI * 2) + phaseOffset;
555
555
  const rawSway = Math.sin(swayPhase);
556
556
  const easedSway = this._applyEasing(rawSway, easing);
557
557
 
558
558
  // Accent response: smooth curve that peaks at beat start, scaled by accent level
559
559
  // Uses cosine curve centered on beat boundaries (0 and 1) for smooth falloff
560
560
  // beatProgress 0.0 → peak, 0.5 → minimum, 1.0 → peak again
561
- const beatProximity = (Math.cos(effectiveBeatProgress * Math.PI * 2) + 1) * 0.5; // 0-1, peaks at beat
561
+ // Note: accent response uses raw beatProgress (not multiplied) to still sync with actual beats
562
+ const beatProximity = (Math.cos(this.beatProgress * Math.PI * 2) + 1) * 0.5; // 0-1, peaks at beat
562
563
  const accentStrength = Math.max(0, this.accent - 0.4) / 0.6; // 0-1, normalized above 0.4 threshold
563
564
  const accentBoost = beatProximity * accentStrength * 0.25; // Smooth accent curve
564
565