@sage-rsc/talking-head-react 1.0.72 → 1.0.74

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/README.md CHANGED
@@ -1,74 +1,76 @@
1
- # Talking Head React
1
+ # @sage-rsc/talking-head-react
2
2
 
3
- A reusable React component library for 3D talking avatars with lip-sync and text-to-speech capabilities. Perfect for creating interactive learning experiences, virtual assistants, and animated presentations.
3
+ A powerful React component library for creating interactive 3D talking avatars with realistic lip-sync, multiple text-to-speech services, and curriculum-based learning capabilities.
4
4
 
5
- ## Features
5
+ ## Features
6
6
 
7
- - 🎭 **3D Avatar Rendering** - Support for GLB/GLTF avatar models
8
- - 🎤 **Lip-Sync** - Real-time lip synchronization with audio
9
- - 🔊 **Text-to-Speech** - Multiple TTS services (Edge TTS, ElevenLabs, Google Cloud, Azure, Browser)
10
- - 🎬 **Animation Support** - FBX animation support and code-based animations
11
- - 🎯 **Programmatic Control** - Full control via props and ref methods
12
- - 🎨 **Zero UI** - Pure component, no built-in UI elements
13
- - 📦 **NPM Ready** - Easy to install and use
7
+ - 🎭 **3D Avatar Rendering** - Support for GLB/GLTF avatar models with full body or head-only modes
8
+ - 🎤 **Real-time Lip-Sync** - Automatic lip synchronization with audio using viseme-based animation
9
+ - 🔊 **Multiple TTS Services** - Edge TTS, ElevenLabs, Deepgram, Google Cloud, Azure, and Browser TTS
10
+ - 📚 **Curriculum Learning** - Built-in curriculum system with lessons, questions, and code examples
11
+ - 🎬 **Animation Support** - FBX animation support and code-based body movements
12
+ - ⏯️ **Playback Control** - Pause, resume, and stop speech functionality
13
+ - 🎯 **Interactive Mode** - Manual control over curriculum progression
14
+ - 💻 **Code IDE Integration** - Simulate code typing and execution in an IDE
15
+ - 🎨 **Zero UI** - Pure components, no built-in UI elements - full control over styling
14
16
 
15
- ## Installation
17
+ ## 📦 Installation
16
18
 
17
19
  ```bash
18
- npm install talking-head-react
20
+ npm install @sage-rsc/talking-head-react
19
21
  ```
20
22
 
21
- ## Peer Dependencies
22
-
23
- This package requires the following peer dependencies:
23
+ ### Peer Dependencies
24
24
 
25
25
  ```bash
26
26
  npm install react react-dom three
27
27
  ```
28
28
 
29
- ## Quick Start
29
+ **Requirements:**
30
+ - React 18.0.0+ or 19.0.0+
31
+ - React DOM 18.0.0+ or 19.0.0+
32
+ - Three.js 0.150.0+
33
+
34
+ ## 🚀 Quick Start
35
+
36
+ ### Simple Talking Avatar
30
37
 
31
- ### Basic Usage
38
+ The simplest way to get started - just pass text and the avatar speaks:
32
39
 
33
40
  ```jsx
34
- import React, { useRef, useEffect } from 'react';
35
- import { TalkingHeadAvatar } from 'talking-head-react';
41
+ import React, { useRef } from 'react';
42
+ import { SimpleTalkingAvatar } from '@sage-rsc/talking-head-react';
36
43
 
37
44
  function App() {
38
45
  const avatarRef = useRef(null);
39
46
 
40
- useEffect(() => {
41
- // Wait for avatar to be ready
42
- if (avatarRef.current?.isReady) {
43
- // Make the avatar speak
44
- avatarRef.current.speakText("Hello! I'm your talking avatar.");
45
- }
46
- }, []);
47
+ const handleSpeak = () => {
48
+ avatarRef.current?.speakText("Hello! I'm a talking avatar.");
49
+ };
47
50
 
48
51
  return (
49
52
  <div style={{ width: '100vw', height: '100vh' }}>
50
- <TalkingHeadAvatar
53
+ <SimpleTalkingAvatar
51
54
  ref={avatarRef}
52
- avatarUrl="/path/to/your/avatar.glb"
55
+ avatarUrl="/avatars/brunette.glb"
53
56
  avatarBody="F"
54
57
  mood="happy"
55
- ttsService="edge"
56
- ttsVoice="en-US-AriaNeural"
57
- showFullAvatar={true}
58
- onReady={(talkingHead) => {
59
- console.log('Avatar is ready!', talkingHead);
60
- }}
58
+ showFullAvatar={false}
59
+ onReady={() => console.log('Avatar ready!')}
61
60
  />
61
+ <button onClick={handleSpeak}>Speak</button>
62
62
  </div>
63
63
  );
64
64
  }
65
65
  ```
66
66
 
67
- ### With FBX Animations
67
+ ### Full-Featured Avatar
68
+
69
+ For advanced control with animations and custom configurations:
68
70
 
69
71
  ```jsx
70
72
  import React, { useRef } from 'react';
71
- import { TalkingHeadAvatar } from 'talking-head-react';
73
+ import { TalkingHeadAvatar } from '@sage-rsc/talking-head-react';
72
74
 
73
75
  function App() {
74
76
  const avatarRef = useRef(null);
@@ -76,61 +78,60 @@ function App() {
76
78
  const animations = {
77
79
  teaching: "/animations/Arguing.fbx",
78
80
  correct: "/animations/Happy.fbx",
79
- incorrect: "/animations/Disappointed.fbx",
80
- lessonComplete: "/animations/Step.fbx"
81
- };
82
-
83
- const handleSpeak = () => {
84
- if (avatarRef.current?.isReady) {
85
- // Play animation while speaking
86
- avatarRef.current.playAnimation(animations.teaching, true);
87
- avatarRef.current.speakText("Let me explain this concept to you.");
88
- }
81
+ incorrect: "/animations/Disappointed.fbx"
89
82
  };
90
83
 
91
84
  return (
92
85
  <div style={{ width: '100vw', height: '100vh' }}>
93
86
  <TalkingHeadAvatar
94
87
  ref={avatarRef}
95
- avatarUrl="/path/to/your/avatar.glb"
88
+ avatarUrl="/avatars/brunette.glb"
89
+ avatarBody="F"
90
+ mood="happy"
91
+ ttsService="elevenlabs"
92
+ ttsApiKey="your-api-key"
93
+ ttsVoice="21m00Tcm4TlvDq8ikWAM"
94
+ showFullAvatar={false}
95
+ bodyMovement="gesturing"
96
96
  animations={animations}
97
97
  onReady={() => {
98
- console.log('Avatar ready!');
98
+ avatarRef.current?.speakText("Welcome!");
99
99
  }}
100
100
  />
101
- <button onClick={handleSpeak}>Start Teaching</button>
102
101
  </div>
103
102
  );
104
103
  }
105
104
  ```
106
105
 
107
- ### With Curriculum Data
106
+ ### Curriculum Learning
107
+
108
+ Complete learning system with lessons, questions, and automatic progression:
108
109
 
109
110
  ```jsx
110
111
  import React, { useRef } from 'react';
111
- import { CurriculumLearning } from 'talking-head-react';
112
+ import { CurriculumLearning } from '@sage-rsc/talking-head-react';
112
113
 
113
114
  function App() {
114
- const curriculumRef = useRef(null);
115
-
116
115
  const curriculumData = {
117
116
  curriculum: {
118
- title: "Introduction to Computer Science",
117
+ title: "Introduction to Programming",
118
+ description: "Learn the basics of programming",
119
+ language: "en",
119
120
  modules: [
120
121
  {
121
- title: "Module 1",
122
+ title: "Module 1: Variables",
122
123
  lessons: [
123
124
  {
124
- title: "Lesson 1",
125
- body: "This is lesson content...",
126
- avatar_script: "Welcome to this lesson!",
125
+ title: "JavaScript Variables",
126
+ avatar_script: "Let's learn about variables.",
127
+ body: "Variables store data values in your program.",
127
128
  questions: [
128
129
  {
129
130
  type: "multiple_choice",
130
- question: "What is a variable?",
131
- options: ["Option A", "Option B", "Option C"],
132
- answer: "Option A",
133
- explanation: "A variable is..."
131
+ question: "Which keyword creates a constant variable?",
132
+ options: ["let", "const", "var"],
133
+ answer: "const",
134
+ explanation: "The 'const' keyword creates a constant variable."
134
135
  }
135
136
  ]
136
137
  }
@@ -140,122 +141,297 @@ function App() {
140
141
  }
141
142
  };
142
143
 
143
- const animations = {
144
- teaching: "/animations/Arguing.fbx",
145
- correct: "/animations/Happy.fbx",
146
- incorrect: "/animations/Disappointed.fbx"
147
- };
148
-
149
144
  const avatarConfig = {
150
- avatarUrl: "/path/to/your/avatar.glb",
145
+ avatarUrl: "/avatars/brunette.glb",
151
146
  avatarBody: "F",
152
- ttsService: "edge",
153
- ttsVoice: "en-US-AriaNeural"
147
+ mood: "happy",
148
+ showFullAvatar: false
154
149
  };
155
150
 
156
151
  return (
157
152
  <div style={{ width: '100vw', height: '100vh' }}>
158
153
  <CurriculumLearning
159
- ref={curriculumRef}
160
154
  curriculumData={curriculumData}
161
155
  avatarConfig={avatarConfig}
162
- animations={animations}
163
156
  autoStart={true}
164
- onLessonStart={(data) => {
165
- console.log('Lesson started:', data);
166
- }}
167
157
  onLessonComplete={(data) => {
168
158
  console.log('Lesson completed:', data);
169
159
  }}
170
- onQuestionAnswer={(data) => {
171
- console.log('Question answered:', data);
172
- }}
173
160
  />
174
161
  </div>
175
162
  );
176
163
  }
177
164
  ```
178
165
 
179
- ## API Reference
166
+ ## 📖 Components
167
+
168
+ ### SimpleTalkingAvatar
169
+
170
+ A lightweight component for simple text-to-speech scenarios. Perfect when you just need an avatar to speak text.
180
171
 
181
- ### TalkingHeadAvatar Props
172
+ **Props:**
182
173
 
183
174
  | Prop | Type | Default | Description |
184
175
  |------|------|---------|-------------|
185
- | `avatarUrl` | `string` | `"/avatars/brunette.glb"` | URL/path to the GLB avatar file |
176
+ | `text` | `string` | `null` | Text to speak (optional, can use `speakText` method) |
177
+ | `avatarUrl` | `string` | `"/avatars/brunette.glb"` | URL/path to GLB avatar file |
186
178
  | `avatarBody` | `string` | `"F"` | Avatar body type ('M' or 'F') |
187
- | `mood` | `string` | `"neutral"` | Initial mood ('happy', 'sad', 'neutral', etc.) |
179
+ | `mood` | `string` | `"neutral"` | Initial mood ('happy', 'sad', 'neutral', 'excited') |
188
180
  | `ttsLang` | `string` | `"en"` | Text-to-speech language code |
189
- | `ttsService` | `string` | `null` | TTS service ('edge', 'elevenlabs', 'google', 'azure', 'browser') |
181
+ | `ttsService` | `string` | `null` | TTS service ('edge', 'elevenlabs', 'deepgram', 'google', 'azure', 'browser') |
190
182
  | `ttsVoice` | `string` | `null` | TTS voice ID |
191
- | `bodyMovement` | `string` | `"idle"` | Initial body movement type |
183
+ | `ttsApiKey` | `string` | `null` | TTS API key (ElevenLabs, Deepgram, Google, or Azure |
184
+ | `bodyMovement` | `string` | `"idle"` | Body movement type ('idle', 'gesturing', 'dancing') |
192
185
  | `movementIntensity` | `number` | `0.5` | Movement intensity (0-1) |
193
- | `showFullAvatar` | `boolean` | `true` | Whether to show full body avatar |
194
- | `cameraView` | `string` | `"upper"` | Camera view ('upper', 'full', etc.) |
195
- | `animations` | `object` | `{}` | Object mapping animation names to FBX file paths |
186
+ | `showFullAvatar` | `boolean` | `false` | Whether to show full body avatar |
187
+ | `cameraView` | `string` | `"upper"` | Camera view ('upper', 'full') |
188
+ | `autoSpeak` | `boolean` | `false` | Automatically speak `text` prop when ready |
196
189
  | `onReady` | `function` | `() => {}` | Callback when avatar is ready |
197
- | `onLoading` | `function` | `() => {}` | Callback for loading progress |
198
190
  | `onError` | `function` | `() => {}` | Callback for errors |
191
+ | `onSpeechEnd` | `function` | `() => {}` | Callback when speech ends |
199
192
  | `className` | `string` | `""` | Additional CSS classes |
200
193
  | `style` | `object` | `{}` | Additional inline styles |
201
194
 
202
- ### TalkingHeadAvatar Ref Methods
195
+ **Ref Methods:**
203
196
 
204
197
  | Method | Parameters | Description |
205
198
  |--------|------------|-------------|
206
- | `speakText(text)` | `text: string` | Make the avatar speak the given text |
207
- | `stopSpeaking()` | - | Stop current speech |
208
- | `setMood(mood)` | `mood: string` | Set avatar mood |
209
- | `setTimingAdjustment(rate)` | `rate: number` | Adjust animation timing (e.g., 1.05 for 5% slower) |
210
- | `playAnimation(name, disablePositionLock)` | `name: string`, `disablePositionLock: boolean` | Play an FBX animation |
211
- | `setBodyMovement(movement)` | `movement: string` | Set body movement type |
212
- | `setMovementIntensity(intensity)` | `intensity: number` | Set movement intensity (0-1) |
213
- | `playRandomDance()` | - | Play a random dance animation |
214
- | `playReaction(reactionType)` | `reactionType: string` | Play a reaction animation |
199
+ | `speakText(text, options)` | `text: string`, `options: object` | Make avatar speak text |
200
+ | `pauseSpeaking()` | - | Pause current speech |
201
+ | `resumeSpeaking()` | - | Resume paused speech |
202
+ | `stopSpeaking()` | - | Stop all speech |
203
+ | `resumeAudioContext()` | - | Resume audio context (for user interaction) |
204
+ | `isPaused()` | - | Check if currently paused |
205
+ | `setMood(mood)` | `mood: string` | Change avatar mood |
206
+ | `setBodyMovement(movement)` | `movement: string` | Change body movement |
207
+ | `playAnimation(name)` | `name: string` | Play FBX animation |
208
+ | `playReaction(type)` | `type: string` | Play reaction animation |
215
209
  | `playCelebration()` | - | Play celebration animation |
216
210
  | `setShowFullAvatar(show)` | `show: boolean` | Toggle full body mode |
211
+ | `isReady` | - | Boolean indicating if avatar is ready |
212
+
213
+ **Example:**
214
+
215
+ ```jsx
216
+ const avatarRef = useRef(null);
217
+
218
+ // Speak text
219
+ avatarRef.current?.speakText("Hello world!", {
220
+ lipsyncLang: 'en',
221
+ onSpeechEnd: () => console.log('Done speaking')
222
+ });
223
+
224
+ // Pause/Resume
225
+ avatarRef.current?.pauseSpeaking();
226
+ avatarRef.current?.resumeSpeaking();
227
+
228
+ // Change mood
229
+ avatarRef.current?.setMood("happy");
230
+ ```
231
+
232
+ ### TalkingHeadAvatar
233
+
234
+ Full-featured avatar component with advanced controls, animations, and TTS configuration.
235
+
236
+ **Props:** Same as `SimpleTalkingAvatar` plus:
237
+
238
+ | Prop | Type | Default | Description |
239
+ |------|------|---------|-------------|
240
+ | `animations` | `object` | `{}` | Object mapping animation names to FBX file paths |
241
+ | `onLoading` | `function` | `() => {}` | Callback for loading progress |
242
+
243
+ **Ref Methods:** Same as `SimpleTalkingAvatar` plus:
244
+
245
+ | Method | Parameters | Description |
246
+ |--------|------------|-------------|
247
+ | `setTimingAdjustment(rate)` | `rate: number` | Adjust animation timing (e.g., 1.05 for 5% slower) |
248
+ | `setMovementIntensity(intensity)` | `intensity: number` | Set movement intensity (0-1) |
249
+ | `playRandomDance()` | - | Play random dance animation |
217
250
  | `lockAvatarPosition()` | - | Lock avatar position |
218
251
  | `unlockAvatarPosition()` | - | Unlock avatar position |
219
252
 
220
- ### CurriculumLearning Props
253
+ ### CurriculumLearning
254
+
255
+ Complete learning system with curriculum management, questions, and code examples.
256
+
257
+ **Props:**
221
258
 
222
259
  | Prop | Type | Default | Description |
223
260
  |------|------|---------|-------------|
224
- | `curriculumData` | `object` | `null` | Curriculum data object |
225
- | `avatarConfig` | `object` | `{}` | Avatar configuration |
261
+ | `curriculumData` | `object` | `null` | Curriculum data object (see structure below) |
262
+ | `avatarConfig` | `object` | `{}` | Avatar configuration (same as `SimpleTalkingAvatar` props) |
226
263
  | `animations` | `object` | `{}` | Animation files mapping |
264
+ | `autoStart` | `boolean` | `false` | Automatically start teaching when ready |
227
265
  | `onLessonStart` | `function` | `() => {}` | Callback when lesson starts |
228
266
  | `onLessonComplete` | `function` | `() => {}` | Callback when lesson completes |
229
267
  | `onQuestionAnswer` | `function` | `() => {}` | Callback when question is answered |
230
268
  | `onCurriculumComplete` | `function` | `() => {}` | Callback when curriculum completes |
231
- | `autoStart` | `boolean` | `false` | Whether to auto-start the curriculum |
269
+ | `onCustomAction` | `function` | `() => {}` | Callback for custom actions (interactive mode) |
232
270
 
233
- ### CurriculumLearning Ref Methods
271
+ **Ref Methods:**
234
272
 
235
273
  | Method | Parameters | Description |
236
274
  |--------|------------|-------------|
237
- | `startTeaching()` | - | Start teaching the current lesson |
275
+ | `startTeaching()` | - | Start teaching current lesson |
238
276
  | `startQuestions()` | - | Start asking questions |
239
- | `handleAnswerSelect(answer)` | `answer: string/boolean` | Handle answer selection |
277
+ | `handleAnswerSelect(answer)` | `answer: string/boolean` | Submit answer to current question |
240
278
  | `nextQuestion()` | - | Move to next question |
279
+ | `previousQuestion()` | - | Move to previous question |
241
280
  | `nextLesson()` | - | Move to next lesson |
281
+ | `previousLesson()` | - | Move to previous lesson |
242
282
  | `completeLesson()` | - | Complete current lesson |
243
283
  | `completeCurriculum()` | - | Complete entire curriculum |
244
284
  | `resetCurriculum()` | - | Reset curriculum to beginning |
245
285
  | `getState()` | - | Get current curriculum state |
286
+ | `pauseSpeaking()` | - | Pause avatar speech |
287
+ | `resumeSpeaking()` | - | Resume avatar speech |
288
+ | `isPaused()` | - | Check if paused |
289
+ | `speakText(text, options)` | `text: string`, `options: object` | Make avatar speak text |
246
290
 
247
- ## TTS Configuration
248
-
249
- The package includes a TTS configuration system. You can configure TTS services in `src/config/ttsConfig.js`:
291
+ **Curriculum Data Structure:**
250
292
 
251
293
  ```javascript
252
- import { getActiveTTSConfig } from 'talking-head-react';
294
+ {
295
+ curriculum: {
296
+ title: "Course Title",
297
+ description: "Course description",
298
+ language: "en",
299
+ modules: [
300
+ {
301
+ title: "Module Title",
302
+ lessons: [
303
+ {
304
+ title: "Lesson Title",
305
+ avatar_script: "What the avatar will say",
306
+ body: "Lesson content text",
307
+ code_example: { // Optional
308
+ code: "console.log('Hello');",
309
+ language: "javascript",
310
+ description: "Code example description",
311
+ autoRun: true,
312
+ typingSpeed: 50
313
+ },
314
+ questions: [ // Optional
315
+ {
316
+ type: "multiple_choice", // or "true_false" or "code_test"
317
+ question: "Question text?",
318
+ options: ["Option 1", "Option 2", "Option 3"], // For multiple_choice
319
+ answer: "Option 1", // or true/false for true_false
320
+ explanation: "Why this answer is correct"
321
+ }
322
+ ]
323
+ }
324
+ ]
325
+ }
326
+ ]
327
+ }
328
+ }
329
+ ```
253
330
 
254
- const config = getActiveTTSConfig();
255
- console.log(config.service); // 'edge', 'elevenlabs', 'google', 'azure', or 'browser'
331
+ **Interactive Mode:**
332
+
333
+ For manual control over curriculum progression:
334
+
335
+ ```jsx
336
+ const curriculumRef = useRef(null);
337
+
338
+ // Handle custom actions
339
+ const handleCustomAction = (action) => {
340
+ switch (action.type) {
341
+ case 'teachingComplete':
342
+ // Teaching finished, enable "Start Questions" button
343
+ break;
344
+ case 'questionStart':
345
+ // Question started, show question UI
346
+ break;
347
+ case 'answerFeedbackComplete':
348
+ // Answer feedback finished, enable "Next Question" button
349
+ break;
350
+ case 'allQuestionsComplete':
351
+ // All questions done, enable "Complete Lesson" button
352
+ break;
353
+ case 'lessonCompleteFeedbackDone':
354
+ // Lesson completion feedback done, enable "Next Lesson" button
355
+ break;
356
+ case 'codeExampleReady':
357
+ // Code example ready, trigger IDE typing animation
358
+ break;
359
+ }
360
+ };
361
+
362
+ <CurriculumLearning
363
+ ref={curriculumRef}
364
+ curriculumData={curriculumData}
365
+ avatarConfig={avatarConfig}
366
+ autoStart={false} // Manual control
367
+ onCustomAction={handleCustomAction}
368
+ />
369
+
370
+ // Control progression manually
371
+ curriculumRef.current?.startTeaching();
372
+ curriculumRef.current?.startQuestions();
373
+ curriculumRef.current?.nextQuestion();
374
+ curriculumRef.current?.completeLesson();
375
+ ```
376
+
377
+ ## 🎤 Text-to-Speech Services
378
+
379
+ ### Edge TTS (Default)
380
+
381
+ Free, no API key required:
382
+
383
+ ```jsx
384
+ <SimpleTalkingAvatar
385
+ ttsService="edge"
386
+ ttsVoice="en-US-AriaNeural"
387
+ />
388
+ ```
389
+
390
+ ### ElevenLabs
391
+
392
+ High-quality voices, requires API key:
393
+
394
+ ```jsx
395
+ <SimpleTalkingAvatar
396
+ ttsService="elevenlabs"
397
+ ttsApiKey="your-api-key"
398
+ ttsVoice="21m00Tcm4TlvDq8ikWAM"
399
+ />
256
400
  ```
257
401
 
258
- ## Animation Support
402
+ ### Deepgram
403
+
404
+ Fast, high-quality TTS, requires API key:
405
+
406
+ ```jsx
407
+ <SimpleTalkingAvatar
408
+ ttsService="deepgram"
409
+ ttsApiKey="your-api-key"
410
+ ttsVoice="aura-asteria-en" // Options: aura-thalia-en, aura-asteria-en, aura-orion-en, etc.
411
+ />
412
+ ```
413
+
414
+ ### Browser TTS
415
+
416
+ Uses browser's built-in speech synthesis:
417
+
418
+ ```jsx
419
+ <SimpleTalkingAvatar
420
+ ttsService="browser"
421
+ />
422
+ ```
423
+
424
+ ### Google Cloud / Azure
425
+
426
+ ```jsx
427
+ <SimpleTalkingAvatar
428
+ ttsService="google" // or "azure"
429
+ ttsApiKey="your-api-key"
430
+ ttsVoice="en-US-Wavenet-D"
431
+ />
432
+ ```
433
+
434
+ ## 🎬 Animations
259
435
 
260
436
  ### FBX Animations
261
437
 
@@ -265,7 +441,8 @@ Provide animation mappings via the `animations` prop:
265
441
  const animations = {
266
442
  teaching: "/animations/Arguing.fbx",
267
443
  correct: "/animations/Happy.fbx",
268
- incorrect: "/animations/Disappointed.fbx"
444
+ incorrect: "/animations/Disappointed.fbx",
445
+ lessonComplete: "/animations/Step.fbx"
269
446
  };
270
447
 
271
448
  <TalkingHeadAvatar animations={animations} />
@@ -273,19 +450,173 @@ const animations = {
273
450
 
274
451
  ### Code-Based Animations
275
452
 
276
- The package also supports code-based animations:
453
+ Built-in body movements:
277
454
 
278
455
  - `idle` - Idle animation
279
456
  - `gesturing` - Teaching gestures
457
+ - `dancing` - Dance animation
280
458
  - `happy` - Happy mood animation
281
459
  - `sad` - Sad mood animation
282
- - `dancing` - Dance animation
283
- - And more...
284
460
 
285
- ## License
461
+ ```jsx
462
+ avatarRef.current?.setBodyMovement("gesturing");
463
+ avatarRef.current?.playReaction("happy");
464
+ avatarRef.current?.playCelebration();
465
+ ```
466
+
467
+ ## 📚 Question Types
468
+
469
+ ### Multiple Choice
470
+
471
+ ```javascript
472
+ {
473
+ type: "multiple_choice",
474
+ question: "What is a variable?",
475
+ options: ["A container", "A function", "A loop"],
476
+ answer: "A container",
477
+ explanation: "A variable is a container that stores data."
478
+ }
479
+ ```
480
+
481
+ ### True/False
482
+
483
+ ```javascript
484
+ {
485
+ type: "true_false",
486
+ question: "JavaScript is a compiled language.",
487
+ answer: false,
488
+ explanation: "JavaScript is an interpreted language."
489
+ }
490
+ ```
491
+
492
+ ### Code Test
493
+
494
+ ```javascript
495
+ {
496
+ type: "code_test",
497
+ question: "Write a function that adds two numbers.",
498
+ testCriteria: {
499
+ type: "function",
500
+ functionName: "add",
501
+ testCases: [
502
+ { input: [2, 3], expectedOutput: 5 },
503
+ { input: [10, 20], expectedOutput: 30 }
504
+ ]
505
+ },
506
+ explanation: "The function should return the sum of two numbers."
507
+ }
508
+ ```
509
+
510
+ ## 💻 Code Examples
511
+
512
+ Include code examples in lessons for IDE integration:
513
+
514
+ ```javascript
515
+ {
516
+ title: "JavaScript Variables",
517
+ avatar_script: "Let's learn about variables.",
518
+ body: "Variables store data values.",
519
+ code_example: {
520
+ code: "let name = 'Alice';\nconst age = 25;\nconsole.log(name);",
521
+ language: "javascript", // "javascript", "python", "java", "html"
522
+ description: "Basic variable declarations",
523
+ autoRun: true, // Automatically run after typing
524
+ typingSpeed: 50 // Characters per second
525
+ }
526
+ }
527
+ ```
528
+
529
+ Listen for `codeExampleReady` event in interactive mode:
530
+
531
+ ```jsx
532
+ const handleCustomAction = (action) => {
533
+ if (action.type === 'codeExampleReady') {
534
+ // Trigger IDE typing animation
535
+ handleCodeExample(action.codeExample);
536
+ }
537
+ };
538
+ ```
539
+
540
+ ## 🎯 Use Cases
541
+
542
+ - **Educational Platforms** - Interactive learning with curriculum management
543
+ - **Virtual Assistants** - Conversational avatars with TTS
544
+ - **Code Tutorials** - Step-by-step coding lessons with IDE integration
545
+ - **Training Simulations** - Interactive training with questions and feedback
546
+ - **Presentation Tools** - Animated presentations with talking avatars
547
+
548
+ ## 🔧 Configuration
549
+
550
+ ### TTS Configuration
551
+
552
+ Configure default TTS service in your app:
553
+
554
+ ```javascript
555
+ import { getActiveTTSConfig } from '@sage-rsc/talking-head-react';
556
+
557
+ const config = getActiveTTSConfig();
558
+ // Returns current TTS configuration
559
+ ```
560
+
561
+ ### Avatar Configuration
562
+
563
+ Common avatar settings:
564
+
565
+ ```javascript
566
+ const avatarConfig = {
567
+ avatarUrl: "/avatars/brunette.glb",
568
+ avatarBody: "F", // "M" or "F"
569
+ mood: "happy",
570
+ ttsService: "elevenlabs",
571
+ ttsApiKey: "your-key",
572
+ ttsVoice: "voice-id",
573
+ showFullAvatar: false, // false = head only, true = full body
574
+ bodyMovement: "gesturing",
575
+ movementIntensity: 0.7
576
+ };
577
+ ```
578
+
579
+ ## 📝 Examples
580
+
581
+ Check the `example-*.jsx` files in the repository for complete examples:
582
+
583
+ - `example-simple-avatar.jsx` - Simple text-to-speech usage
584
+ - `example-interactive-mode.jsx` - Manual curriculum control
585
+ - `example-with-code-ide.jsx` - Code IDE integration
586
+ - `example-with-api-key.jsx` - TTS service configuration
587
+
588
+ ## 🐛 Troubleshooting
589
+
590
+ ### Audio Not Playing
591
+
592
+ If you see "Web Audio API suspended" error:
593
+
594
+ ```jsx
595
+ // The component automatically resumes audio context on user interaction
596
+ // But you can also manually resume:
597
+ avatarRef.current?.resumeAudioContext();
598
+ ```
599
+
600
+ ### Avatar Not Loading
601
+
602
+ - Ensure the avatar file path is correct
603
+ - Check browser console for loading errors
604
+ - Verify GLB file is valid
605
+
606
+ ### Lip-Sync Not Working
607
+
608
+ - Ensure avatar model has viseme morph targets
609
+ - Check that `lipsyncLang` matches your TTS language
610
+ - Verify TTS service is working correctly
611
+
612
+ ## 📄 License
286
613
 
287
614
  MIT
288
615
 
289
- ## Contributing
616
+ ## 🤝 Contributing
290
617
 
291
618
  Contributions are welcome! Please feel free to submit a Pull Request.
619
+
620
+ ## 📞 Support
621
+
622
+ For issues, questions, or feature requests, please open an issue on GitHub.