@sage-rsc/talking-head-react 1.8.1 → 1.8.2

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@sage-rsc/talking-head-react",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "A reusable React component for 3D talking avatars with lip-sync and text-to-speech",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -1019,6 +1019,10 @@ const SimpleTalkingAvatar = forwardRef(({
1019
1019
  // IMPORTANT: Ensure isSpeaking is false to prevent startSpeaking() from continuing
1020
1020
  talkingHeadRef.current.isSpeaking = false;
1021
1021
 
1022
+ // CRITICAL: Stop animations when pausing
1023
+ isSpeakingRef.current = false;
1024
+ currentAnimationGroupRef.current = null;
1025
+
1022
1026
  // If we have trimmed buffer, store speech queue to restore on resume
1023
1027
  // This way speech won't continue automatically, only when resumed
1024
1028
  if (pausedAudioData && pausedAudioData.audio && savedSpeechQueue) {
@@ -3174,12 +3174,14 @@ class TalkingHead {
3174
3174
 
3175
3175
  // Manually check if current FBX animation has finished (backup to mixer 'finished' event)
3176
3176
  // This ensures the callback fires reliably even if the mixer event doesn't
3177
- if (this.currentFBXActionForCallback && this.currentFBXActionForCallback.isRunning() && this.currentFBXActionStartTime !== null) {
3177
+ if (this.currentFBXActionForCallback && this.currentFBXActionForCallback.isRunning() && this.currentFBXActionClipDuration) {
3178
3178
  const actionTime = this.currentFBXActionForCallback.time;
3179
3179
  const clipDuration = this.currentFBXActionClipDuration;
3180
3180
 
3181
+ // For LoopOnce, action.time goes from 0 to clipDuration
3181
3182
  // Check if animation has reached the end (with small tolerance for timing)
3182
- if (actionTime >= clipDuration - 0.01) {
3183
+ // Also check if action is paused (time doesn't advance when paused)
3184
+ if (actionTime >= clipDuration - 0.05 || (actionTime > 0 && !this.currentFBXActionForCallback.paused && actionTime >= clipDuration - 0.1)) {
3183
3185
  // Animation finished - call callback manually
3184
3186
  if (this.currentFBXActionCallback) {
3185
3187
  this.currentFBXActionCallback();
@@ -3187,6 +3189,7 @@ class TalkingHead {
3187
3189
  }
3188
3190
  this.currentFBXActionForCallback = null;
3189
3191
  this.currentFBXActionStartTime = null;
3192
+ this.currentFBXActionClipDuration = null;
3190
3193
  }
3191
3194
  }
3192
3195
  }
@@ -5604,6 +5607,11 @@ class TalkingHead {
5604
5607
  // Small delay for smooth transition
5605
5608
  setTimeout(() => {
5606
5609
  this.currentFBXAction = action;
5610
+ // IMPORTANT: Update callback tracking variables inside setTimeout
5611
+ // This ensures manual checking works correctly for fade transitions
5612
+ this.currentFBXActionForCallback = action;
5613
+ this.currentFBXActionCallback = finishedHandler;
5614
+ this.currentFBXActionClipDuration = item.clip.duration;
5607
5615
  this.currentFBXActionStartTime = this.mixer.time; // Track when animation starts
5608
5616
  try {
5609
5617
  action.fadeIn(0.5).play();