@bod.ee/ai-avatar 1.0.0
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 +444 -0
- package/dist/PlaybackSync-CZsM--xy.js +2029 -0
- package/dist/PlaybackSync-DwFiX-W4.cjs +1 -0
- package/dist/avatar-react.d.ts +9 -0
- package/dist/components/Avatar.d.ts +24 -0
- package/dist/core.cjs +1 -0
- package/dist/core.js +20 -0
- package/dist/favicon.ico +0 -0
- package/dist/hooks/useCursorTracking.d.ts +24 -0
- package/dist/hooks/useGlitchEffect.d.ts +34 -0
- package/dist/hooks/useSpeech.d.ts +31 -0
- package/dist/lib/avatar/AvatarController.d.ts +203 -0
- package/dist/lib/avatar/PlaybackSync.d.ts +50 -0
- package/dist/lib/avatar/SpeechBubbleGrouper.d.ts +42 -0
- package/dist/lib/avatar/SpeechController.d.ts +75 -0
- package/dist/lib/avatar/emotions.d.ts +11 -0
- package/dist/lib/avatar/expressions.d.ts +9 -0
- package/dist/lib/avatar/index.d.ts +35 -0
- package/dist/lib/avatar/sequences.d.ts +8 -0
- package/dist/lib/avatar/types.d.ts +101 -0
- package/dist/lib/avatar/useAvatarController.d.ts +28 -0
- package/dist/lib/utils/EventEmitter.d.ts +13 -0
- package/dist/placeholder.svg +1 -0
- package/dist/react.cjs +1 -0
- package/dist/react.js +503 -0
- package/dist/robots.txt +14 -0
- package/package.json +121 -0
package/README.md
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
# Avatar Studio - AI Agent Component
|
|
2
|
+
|
|
3
|
+
An interactive avatar component designed for AI systems with both programmable API and scripting language support. Perfect for chatbots, virtual assistants, and AI-powered applications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎭 **30+ Expressive Facial Expressions** - From happy to surprised, tired to excited
|
|
8
|
+
- 👄 **Phoneme-Based Mouth Shapes** - Support for A, E, I, O, U, M, F, W phonemes
|
|
9
|
+
- 🎬 **Animation Sequences** - Pre-built sequences and custom timing
|
|
10
|
+
- 📝 **Declarative Scripting Language** - Simple, human-readable script syntax
|
|
11
|
+
- 🔌 **Framework-Agnostic Core** - Works with React, Vue, or vanilla JS
|
|
12
|
+
- 🎯 **Dual Interface** - Both API and script-based control
|
|
13
|
+
- ⚡ **Lightweight & Performant** - Optimized for real-time interactions
|
|
14
|
+
- 👀 **Cursor Tracking** - Eyes follow mouse movement
|
|
15
|
+
- ✨ **Glitch Effects** - Personality-rich transitions
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git clone <YOUR_GIT_URL>
|
|
23
|
+
cd ai-avatar
|
|
24
|
+
npm install
|
|
25
|
+
npm run dev
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Visit `http://localhost:8080` to see the demo.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### React Hook (Recommended for React apps)
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { useAvatarController } from '@/lib/avatar';
|
|
36
|
+
import Avatar from '@/components/Avatar';
|
|
37
|
+
|
|
38
|
+
function MyApp() {
|
|
39
|
+
const controller = useAvatarController({ autoAnimate: true });
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div>
|
|
43
|
+
<Avatar controller={controller} />
|
|
44
|
+
<button onClick={() => controller.setExpression('happy')}>
|
|
45
|
+
Make Happy
|
|
46
|
+
</button>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Core Controller (Framework-agnostic)
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { AvatarControllerClass } from '@/lib/avatar';
|
|
56
|
+
|
|
57
|
+
const controller = new AvatarControllerClass({ autoAnimate: true });
|
|
58
|
+
|
|
59
|
+
// API control
|
|
60
|
+
controller.setExpression('happy');
|
|
61
|
+
await controller.playSequence('greeting');
|
|
62
|
+
await controller.blink();
|
|
63
|
+
|
|
64
|
+
// Listen to events
|
|
65
|
+
controller.on('stateChange', (state) => {
|
|
66
|
+
console.log('State changed:', state);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
controller.on('expressionChange', (id) => {
|
|
70
|
+
console.log('Expression changed to:', id);
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Scripting Language
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { executeScript } from '@/lib/scripting';
|
|
78
|
+
import { AvatarControllerClass } from '@/lib/avatar';
|
|
79
|
+
|
|
80
|
+
const controller = new AvatarControllerClass();
|
|
81
|
+
|
|
82
|
+
const script = `
|
|
83
|
+
EXPRESSION neutral
|
|
84
|
+
PAUSE 500ms
|
|
85
|
+
BLINK
|
|
86
|
+
SPEAK "Hello everyone!"
|
|
87
|
+
EXPRESSION happy
|
|
88
|
+
SEQUENCE cheerful
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
await executeScript(script, controller);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Script Syntax Reference
|
|
95
|
+
|
|
96
|
+
### Commands
|
|
97
|
+
|
|
98
|
+
| Command | Syntax | Description |
|
|
99
|
+
|---------|--------|-------------|
|
|
100
|
+
| **EXPRESSION** | `EXPRESSION <id>` | Set facial expression |
|
|
101
|
+
| **PAUSE** | `PAUSE <duration>` | Wait (e.g., 1s, 500ms) |
|
|
102
|
+
| **BLINK** | `BLINK [duration]` | Trigger eye blink |
|
|
103
|
+
| **SEQUENCE** | `SEQUENCE <id>` | Play animation sequence |
|
|
104
|
+
| **SPEAK** | `SPEAK "<text>"` | Display speech text* |
|
|
105
|
+
| **LOOK_LEFT** | `LOOK_LEFT` | Look to the left |
|
|
106
|
+
| **LOOK_RIGHT** | `LOOK_RIGHT` | Look to the right |
|
|
107
|
+
| **LOOK_UP** | `LOOK_UP` | Look upward |
|
|
108
|
+
| **LOOK_DOWN** | `LOOK_DOWN` | Look downward |
|
|
109
|
+
| **REPEAT** | `REPEAT <n> { ... }` | Loop commands |
|
|
110
|
+
|
|
111
|
+
*Note: TTS integration planned for future release
|
|
112
|
+
|
|
113
|
+
### Example Scripts
|
|
114
|
+
|
|
115
|
+
**Simple Greeting:**
|
|
116
|
+
```
|
|
117
|
+
EXPRESSION neutral
|
|
118
|
+
PAUSE 500ms
|
|
119
|
+
BLINK
|
|
120
|
+
SPEAK "Hello! I'm your AI assistant."
|
|
121
|
+
EXPRESSION happy
|
|
122
|
+
PAUSE 2s
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Presentation Mode:**
|
|
126
|
+
```
|
|
127
|
+
EXPRESSION neutral
|
|
128
|
+
SPEAK "Welcome to today's presentation."
|
|
129
|
+
PAUSE 1s
|
|
130
|
+
LOOK_RIGHT
|
|
131
|
+
PAUSE 800ms
|
|
132
|
+
SPEAK "Let me show you something interesting."
|
|
133
|
+
EXPRESSION excited
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Loop Example:**
|
|
137
|
+
```
|
|
138
|
+
REPEAT 3 {
|
|
139
|
+
BLINK
|
|
140
|
+
PAUSE 800ms
|
|
141
|
+
}
|
|
142
|
+
EXPRESSION neutral
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
More examples available in `src/examples/scripts.ts`.
|
|
146
|
+
|
|
147
|
+
## API Reference
|
|
148
|
+
|
|
149
|
+
### AvatarControllerClass
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
class AvatarControllerClass {
|
|
153
|
+
// Core methods
|
|
154
|
+
setExpression(id: string): void
|
|
155
|
+
setState(state: Partial<AvatarState>): void
|
|
156
|
+
blink(duration?: number): Promise<void>
|
|
157
|
+
playSequence(id: string): Promise<void>
|
|
158
|
+
stopSequence(): void
|
|
159
|
+
setAutoAnimate(enabled: boolean): void
|
|
160
|
+
|
|
161
|
+
// Getters
|
|
162
|
+
getState(): Readonly<AvatarState>
|
|
163
|
+
getCurrentExpression(): string | null
|
|
164
|
+
getExpressions(): ExpressionConfig[]
|
|
165
|
+
getSequences(): AnimationSequence[]
|
|
166
|
+
isAnimating(): boolean
|
|
167
|
+
|
|
168
|
+
// Lifecycle
|
|
169
|
+
destroy(): void
|
|
170
|
+
|
|
171
|
+
// Events (inherited from EventEmitter)
|
|
172
|
+
on(event: 'stateChange', handler: (state: AvatarState) => void): void
|
|
173
|
+
on(event: 'expressionChange', handler: (id: string) => void): void
|
|
174
|
+
on(event: 'sequenceStart', handler: (id: string) => void): void
|
|
175
|
+
on(event: 'sequenceEnd', handler: (id: string) => void): void
|
|
176
|
+
on(event: 'autoAnimateChange', handler: (enabled: boolean) => void): void
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Available Expressions
|
|
181
|
+
|
|
182
|
+
**Base States:**
|
|
183
|
+
- `neutral`, `blink`
|
|
184
|
+
|
|
185
|
+
**Happy States:**
|
|
186
|
+
- `happy`, `happySmall`, `happyBig`, `cheerful`, `excited`
|
|
187
|
+
|
|
188
|
+
**Squint Variations:**
|
|
189
|
+
- `squintLight`, `squintMedium`, `squint`, `squintDeep`
|
|
190
|
+
|
|
191
|
+
**Tired States:**
|
|
192
|
+
- `focused`, `tired`, `sleepy`
|
|
193
|
+
|
|
194
|
+
**Looking Directions:**
|
|
195
|
+
- `lookLeft`, `lookRight`, `lookUp`, `lookDown`
|
|
196
|
+
|
|
197
|
+
**Emotional:**
|
|
198
|
+
- `surprised`, `curious`, `skeptical`, `shy`
|
|
199
|
+
|
|
200
|
+
**Talking/Phonemes:**
|
|
201
|
+
- `talking1`, `talking2`, `talking3`
|
|
202
|
+
- `talking-A`, `talking-E`, `talking-I`, `talking-O`, `talking-U`, `talking-M`, `talking-F`, `talking-W`
|
|
203
|
+
|
|
204
|
+
### Available Sequences
|
|
205
|
+
|
|
206
|
+
- `blink`, `doubleBlink`, `slowBlink`
|
|
207
|
+
- `greeting`, `cheerful`, `wakeUp`
|
|
208
|
+
- `thinking`, `curiousScan`
|
|
209
|
+
- `demoLoop`, `idle`
|
|
210
|
+
|
|
211
|
+
(See `src/lib/avatar/sequences.ts` for complete list)
|
|
212
|
+
|
|
213
|
+
## AI Integration
|
|
214
|
+
|
|
215
|
+
### LLM Script Generation
|
|
216
|
+
|
|
217
|
+
Train your LLM to generate scripts dynamically:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
const prompt = `Generate an avatar script for: ${userRequest}
|
|
221
|
+
|
|
222
|
+
Available commands:
|
|
223
|
+
- EXPRESSION <id>
|
|
224
|
+
- PAUSE <duration>
|
|
225
|
+
- BLINK
|
|
226
|
+
- SEQUENCE <id>
|
|
227
|
+
- SPEAK "<text>"
|
|
228
|
+
- LOOK_LEFT/RIGHT/UP/DOWN
|
|
229
|
+
- REPEAT <n> { ... }
|
|
230
|
+
|
|
231
|
+
Output only the script, no explanations.`;
|
|
232
|
+
|
|
233
|
+
const aiScript = await llm.generate(prompt);
|
|
234
|
+
await executeScript(aiScript, controller);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Direct API Integration
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
class AIAgent {
|
|
241
|
+
private controller: AvatarControllerClass;
|
|
242
|
+
|
|
243
|
+
constructor() {
|
|
244
|
+
this.controller = new AvatarControllerClass();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
async respondToUser(message: string) {
|
|
248
|
+
// Set thinking expression
|
|
249
|
+
this.controller.setExpression('focused');
|
|
250
|
+
|
|
251
|
+
// Generate response
|
|
252
|
+
const response = await this.llm.chat(message);
|
|
253
|
+
|
|
254
|
+
// Show happy while speaking
|
|
255
|
+
this.controller.setExpression('happy');
|
|
256
|
+
|
|
257
|
+
// Speak (with future TTS integration)
|
|
258
|
+
await this.speakText(response);
|
|
259
|
+
|
|
260
|
+
// Return to neutral
|
|
261
|
+
this.controller.setExpression('neutral');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Architecture
|
|
267
|
+
|
|
268
|
+
### Project Structure
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
src/
|
|
272
|
+
├── lib/
|
|
273
|
+
│ ├── avatar/ # Core avatar system
|
|
274
|
+
│ │ ├── types.ts # TypeScript definitions
|
|
275
|
+
│ │ ├── expressions.ts # Expression registry
|
|
276
|
+
│ │ ├── sequences.ts # Animation sequences
|
|
277
|
+
│ │ ├── AvatarController.ts # Framework-agnostic class
|
|
278
|
+
│ │ ├── useAvatarController.ts # React hook wrapper
|
|
279
|
+
│ │ ├── emotions.ts # Emotion-to-action mapping
|
|
280
|
+
│ │ └── index.ts # Public API
|
|
281
|
+
│ │
|
|
282
|
+
│ └── scripting/ # Scripting engine
|
|
283
|
+
│ ├── parser/
|
|
284
|
+
│ │ ├── Lexer.ts # Tokenizer
|
|
285
|
+
│ │ └── Parser.ts # Script parser
|
|
286
|
+
│ ├── ast/
|
|
287
|
+
│ │ └── nodes.ts # AST definitions
|
|
288
|
+
│ ├── executor/
|
|
289
|
+
│ │ └── ScriptExecutor.ts # Script runner
|
|
290
|
+
│ └── index.ts # Public exports
|
|
291
|
+
│
|
|
292
|
+
├── components/
|
|
293
|
+
│ ├── Avatar.tsx # Visual renderer
|
|
294
|
+
│ ├── AvatarControlPanel.tsx # Control UI
|
|
295
|
+
│ └── ScriptEditor.tsx # Script input UI
|
|
296
|
+
│
|
|
297
|
+
├── examples/
|
|
298
|
+
│ └── scripts.ts # Example scripts
|
|
299
|
+
│
|
|
300
|
+
└── hooks/ # Custom React hooks
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Key Design Principles
|
|
304
|
+
|
|
305
|
+
1. **Framework-Agnostic Core**: The `AvatarController` class works without React
|
|
306
|
+
2. **Type Safety**: Full TypeScript support with strict typing
|
|
307
|
+
3. **Event-Driven**: Uses EventEmitter for reactive updates
|
|
308
|
+
4. **Modular**: Each component has a single responsibility
|
|
309
|
+
5. **Extensible**: Easy to add new expressions, sequences, or commands
|
|
310
|
+
|
|
311
|
+
## Customization
|
|
312
|
+
|
|
313
|
+
### Adding a New Expression
|
|
314
|
+
|
|
315
|
+
Edit `src/lib/avatar/expressions.ts`:
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
myExpression: {
|
|
319
|
+
id: "myExpression",
|
|
320
|
+
name: "My Expression",
|
|
321
|
+
state: {
|
|
322
|
+
eyes: { scaleY: 1, scaleX: 1, position: { x: 0, y: 0 } },
|
|
323
|
+
mouth: { shape: 'smile', openness: 0.6 },
|
|
324
|
+
},
|
|
325
|
+
transitionDuration: 150,
|
|
326
|
+
easing: "ease-out",
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Creating an Animation Sequence
|
|
331
|
+
|
|
332
|
+
Edit `src/lib/avatar/sequences.ts`:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
mySequence: {
|
|
336
|
+
id: "mySequence",
|
|
337
|
+
name: "My Sequence",
|
|
338
|
+
frames: [
|
|
339
|
+
{ expression: "neutral", duration: 500 },
|
|
340
|
+
{ expression: "happy", duration: 1000 },
|
|
341
|
+
{ expression: "neutral", duration: 500 },
|
|
342
|
+
],
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Adjusting Eye Tracking
|
|
347
|
+
|
|
348
|
+
Edit `src/hooks/useCursorTracking.ts`:
|
|
349
|
+
|
|
350
|
+
- `DEAD_ZONE_RADIUS`: Center area with no movement (default: 0.08)
|
|
351
|
+
- `SMOOTHING_FACTOR`: Motion smoothness 0-1 (default: 0.12)
|
|
352
|
+
- `MAX_OFFSET`: Maximum eye displacement (default: 0.4)
|
|
353
|
+
|
|
354
|
+
## Roadmap
|
|
355
|
+
|
|
356
|
+
### MVP (Current - v0.1)
|
|
357
|
+
- ✅ Framework-agnostic core controller
|
|
358
|
+
- ✅ Rich mouth shapes (phonemes)
|
|
359
|
+
- ✅ Scripting language (parser + executor)
|
|
360
|
+
- ✅ React integration
|
|
361
|
+
- ✅ Example scripts and documentation
|
|
362
|
+
|
|
363
|
+
### Planned Features (v0.2+)
|
|
364
|
+
- 🔜 **TTS Integration** - Web Speech API, ElevenLabs support
|
|
365
|
+
- 🔜 **Lip-sync Engine** - Automatic phoneme matching
|
|
366
|
+
- 🔜 **Audio Analysis** - Real-time audio-driven animation
|
|
367
|
+
- 🔜 **Expression Blending** - Smooth interpolation between states
|
|
368
|
+
- 🔜 **Vue/Svelte Adapters** - Framework-specific wrappers
|
|
369
|
+
- 🔜 **NPM Package** - Easy installation via npm
|
|
370
|
+
- 🔜 **Plugin System** - Custom commands and behaviors
|
|
371
|
+
- 🔜 **Animation Timeline** - Visual sequence editor
|
|
372
|
+
|
|
373
|
+
## Technologies Used
|
|
374
|
+
|
|
375
|
+
This project is built with:
|
|
376
|
+
|
|
377
|
+
- **React 18.3.1** - UI framework
|
|
378
|
+
- **TypeScript 5.8.3** - Type safety
|
|
379
|
+
- **Vite 5.4.19** - Build tool
|
|
380
|
+
- **Tailwind CSS** - Styling
|
|
381
|
+
- **shadcn/ui** - UI components
|
|
382
|
+
- **TanStack React Query** - State management
|
|
383
|
+
|
|
384
|
+
## Development
|
|
385
|
+
|
|
386
|
+
### Available Scripts
|
|
387
|
+
|
|
388
|
+
| Command | Purpose |
|
|
389
|
+
|---------|---------|
|
|
390
|
+
| `npm run dev` | Dev server on http://localhost:8080 |
|
|
391
|
+
| `npm run build` | Production build |
|
|
392
|
+
| `npm run lint` | ESLint check |
|
|
393
|
+
| `npm run preview` | Preview production build |
|
|
394
|
+
| `npm run test` | Run tests once |
|
|
395
|
+
| `npm run test:watch` | Tests in watch mode |
|
|
396
|
+
|
|
397
|
+
### Path Aliases
|
|
398
|
+
|
|
399
|
+
Use `@/` to reference `src/`:
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
import { Avatar } from "@/components/Avatar";
|
|
403
|
+
import { useAvatarController } from "@/lib/avatar";
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Deployment
|
|
407
|
+
|
|
408
|
+
Build files go to `dist/` after `npm run build`. Deploy to:
|
|
409
|
+
- Vercel
|
|
410
|
+
- Netlify
|
|
411
|
+
- GitHub Pages
|
|
412
|
+
- Any static hosting
|
|
413
|
+
|
|
414
|
+
## Contributing
|
|
415
|
+
|
|
416
|
+
Contributions are welcome! Please:
|
|
417
|
+
|
|
418
|
+
1. Fork the repository
|
|
419
|
+
2. Create a feature branch
|
|
420
|
+
3. Make your changes
|
|
421
|
+
4. Add tests if applicable
|
|
422
|
+
5. Submit a pull request
|
|
423
|
+
|
|
424
|
+
## License
|
|
425
|
+
|
|
426
|
+
MIT License - feel free to use in your projects!
|
|
427
|
+
|
|
428
|
+
## Support
|
|
429
|
+
|
|
430
|
+
- **Documentation**: See `/CLAUDE.md` for detailed development guide
|
|
431
|
+
- **Issues**: Report bugs or request features on GitHub
|
|
432
|
+
- **Examples**: Check `src/examples/scripts.ts` for usage examples
|
|
433
|
+
|
|
434
|
+
## Credits
|
|
435
|
+
|
|
436
|
+
Built with ❤️ for the AI community.
|
|
437
|
+
|
|
438
|
+
Special thanks to:
|
|
439
|
+
- shadcn for the beautiful UI components
|
|
440
|
+
- The React and TypeScript communities
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
**Ready to bring your AI to life with expressive avatars!** 🎭✨
|