@joshtol/emotive-engine 3.4.0 → 3.4.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/README.md +81 -530
- package/dist/emotive-mascot-3d-elementals.js +1 -1
- package/dist/emotive-mascot-3d-elementals.umd.js +1 -1
- package/dist/emotive-mascot-3d.js +1 -1
- package/dist/emotive-mascot-3d.umd.js +1 -1
- package/dist/emotive-mascot.lean.js +1 -1
- package/dist/emotive-mascot.lean.umd.js +1 -1
- package/dist/emotive-mascot.minimal.js +1 -1
- package/dist/emotive-mascot.minimal.umd.js +1 -1
- package/dist/emotive-mascot.umd.js +1 -1
- package/dist/mascot.js +1 -1
- package/docs/README.md +263 -0
- package/package.json +4 -5
- /package/{THIRD-PARTY-LICENSES.md → docs/THIRD-PARTY-LICENSES.md} +0 -0
package/README.md
CHANGED
|
@@ -8,62 +8,59 @@
|
|
|
8
8
|
[](./LICENSE.md)
|
|
9
9
|
[](https://www.npmjs.com/package/@joshtol/emotive-engine)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
<img src="assets/previews/elemental-gestures.gif" alt="Emotive Engine — 8 elemental shaders, 160+ gestures" width="100%" />
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- [Features](#features)
|
|
17
|
-
- [Demo Gallery](#demo-gallery)
|
|
18
|
-
- [Installation](#installation)
|
|
19
|
-
- [3D Assets (Models & Textures)](#3d-assets-models--textures)
|
|
20
|
-
- [LLM Integration with feel()](#llm-integration-with-feel)
|
|
21
|
-
- [Emotions](#emotions)
|
|
22
|
-
- [Gestures](#gestures)
|
|
23
|
-
- [Elemental Gestures (3D)](#elemental-gestures-3d)
|
|
24
|
-
- [3D Geometries](#3d-geometries)
|
|
25
|
-
- [Configuration](#configuration)
|
|
26
|
-
- [API Reference](#api-reference)
|
|
27
|
-
- [Running Locally](#running-locally)
|
|
28
|
-
- [Browser Support](#browser-support)
|
|
29
|
-
- [Multi-Instance Support](#multi-instance-support)
|
|
30
|
-
- [Server-Side Rendering (SSR)](#server-side-rendering-ssr)
|
|
31
|
-
- [Performance Tips](#performance-tips)
|
|
32
|
-
- [License](#license)
|
|
13
|
+
Real-time character animation engine with **Canvas 2D** and **WebGL 3D**
|
|
14
|
+
rendering.<br/> 8 elemental shader systems. 160+ elemental gestures. One
|
|
15
|
+
replicable pattern.
|
|
33
16
|
|
|
34
|
-
|
|
17
|
+
**[Live Demo](https://joshtol.github.io/emotive-engine)** ·
|
|
18
|
+
**[Elemental Gestures Demo](https://joshtol.github.io/emotive-engine/examples/3d/elemental-gestures.html)**
|
|
19
|
+
· **[NPM](https://www.npmjs.com/package/@joshtol/emotive-engine)**
|
|
35
20
|
|
|
36
|
-
|
|
21
|
+
</div>
|
|
37
22
|
|
|
38
|
-
|
|
39
|
-
import { EmotiveMascot } from '@joshtol/emotive-engine';
|
|
23
|
+
---
|
|
40
24
|
|
|
41
|
-
|
|
42
|
-
await mascot.init(document.getElementById('app'));
|
|
43
|
-
mascot.start();
|
|
44
|
-
mascot.feel('happy, bouncing'); // Natural language control!
|
|
45
|
-
```
|
|
25
|
+
## Quick Start
|
|
46
26
|
|
|
47
27
|
```bash
|
|
48
28
|
npm install @joshtol/emotive-engine
|
|
49
29
|
```
|
|
50
30
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
31
|
+
### 3D Mode (WebGL)
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d';
|
|
54
35
|
|
|
55
|
-
|
|
36
|
+
const mascot = new EmotiveMascot3D({
|
|
37
|
+
coreGeometry: 'crystal',
|
|
38
|
+
assetBasePath: '/assets', // self-hosted assets (see below)
|
|
39
|
+
});
|
|
56
40
|
|
|
57
|
-
|
|
41
|
+
mascot.init(document.getElementById('container'));
|
|
42
|
+
mascot.start();
|
|
58
43
|
|
|
59
|
-
|
|
60
|
-
|
|
44
|
+
mascot.setEmotion('joy');
|
|
45
|
+
mascot.express('bounce');
|
|
46
|
+
mascot.morphTo('heart');
|
|
47
|
+
mascot.feel('happy, bouncing'); // Natural language control
|
|
48
|
+
```
|
|
61
49
|
|
|
62
|
-
|
|
63
|
-
[Documentation](#api-reference) |
|
|
64
|
-
[NPM](https://www.npmjs.com/package/@joshtol/emotive-engine)
|
|
50
|
+
3D mode requires Three.js: `npm install three`
|
|
65
51
|
|
|
66
|
-
|
|
52
|
+
### 2D Mode (Canvas)
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
import { EmotiveMascot } from '@joshtol/emotive-engine';
|
|
56
|
+
|
|
57
|
+
const mascot = new EmotiveMascot();
|
|
58
|
+
await mascot.init(document.getElementById('container'));
|
|
59
|
+
mascot.start();
|
|
60
|
+
mascot.feel('happy, bouncing');
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
2D mode has no dependencies and requires no external assets.
|
|
67
64
|
|
|
68
65
|
---
|
|
69
66
|
|
|
@@ -96,19 +93,14 @@ rendering.
|
|
|
96
93
|
</tr>
|
|
97
94
|
</table>
|
|
98
95
|
|
|
99
|
-
**Shared
|
|
100
|
-
|
|
101
|
-
- 15 emotional states with smooth transitions
|
|
102
|
-
- 180+ base gestures including directional movements
|
|
103
|
-
- **Natural language `feel()` API** for LLM integration
|
|
104
|
-
- TypeScript definitions
|
|
105
|
-
- Unified API
|
|
96
|
+
**Shared:** 15 emotions · 180+ gestures · Natural language `feel()` API ·
|
|
97
|
+
TypeScript definitions · Unified API
|
|
106
98
|
|
|
107
99
|
---
|
|
108
100
|
|
|
109
101
|
## Demo Gallery
|
|
110
102
|
|
|
111
|
-
### 3D WebGL
|
|
103
|
+
### 3D WebGL
|
|
112
104
|
|
|
113
105
|
<table>
|
|
114
106
|
<tr>
|
|
@@ -137,66 +129,70 @@ rendering.
|
|
|
137
129
|
</tr>
|
|
138
130
|
</table>
|
|
139
131
|
|
|
140
|
-
### 2D Canvas
|
|
132
|
+
### 2D Canvas
|
|
141
133
|
|
|
142
134
|
<table>
|
|
143
135
|
<tr>
|
|
144
136
|
<td align="center" width="33%">
|
|
145
137
|
<img src="assets/previews/hello-world.gif" alt="Hello World" width="100%" /><br/>
|
|
146
|
-
<strong>Hello World</strong
|
|
147
|
-
<sub>Minimal setup</sub>
|
|
138
|
+
<strong>Hello World</strong>
|
|
148
139
|
</td>
|
|
149
140
|
<td align="center" width="33%">
|
|
150
141
|
<img src="assets/previews/basic-usage.gif" alt="Basic Usage" width="100%" /><br/>
|
|
151
|
-
<strong>Basic Usage</strong
|
|
152
|
-
<sub>Emotions and gestures</sub>
|
|
142
|
+
<strong>Basic Usage</strong>
|
|
153
143
|
</td>
|
|
154
144
|
<td align="center" width="33%">
|
|
155
145
|
<img src="assets/previews/breathing.gif" alt="Breathing App" width="100%" /><br/>
|
|
156
|
-
<strong>Breathing App</strong
|
|
157
|
-
<sub>Guided breathing</sub>
|
|
146
|
+
<strong>Breathing App</strong>
|
|
158
147
|
</td>
|
|
159
148
|
</tr>
|
|
160
149
|
<tr>
|
|
161
150
|
<td align="center" width="33%">
|
|
162
151
|
<img src="assets/previews/events.gif" alt="Events" width="100%" /><br/>
|
|
163
|
-
<strong>Event Handling</strong
|
|
164
|
-
<sub>Real-time monitoring</sub>
|
|
152
|
+
<strong>Event Handling</strong>
|
|
165
153
|
</td>
|
|
166
154
|
<td align="center" width="33%">
|
|
167
155
|
<img src="assets/previews/rhythm.gif" alt="Rhythm Sync" width="100%" /><br/>
|
|
168
|
-
<strong>Rhythm Sync</strong
|
|
169
|
-
<sub>Beat detection</sub>
|
|
170
|
-
</td>
|
|
171
|
-
<td align="center" width="33%">
|
|
172
|
-
<img src="assets/previews/claude-chat.gif" alt="Claude Chat" width="100%" /><br/>
|
|
173
|
-
<strong>LLM Integration</strong><br/>
|
|
174
|
-
<sub>Claude sentiment analysis</sub>
|
|
156
|
+
<strong>Rhythm Sync</strong>
|
|
175
157
|
</td>
|
|
176
158
|
</tr>
|
|
177
159
|
</table>
|
|
178
160
|
|
|
179
161
|
---
|
|
180
162
|
|
|
181
|
-
##
|
|
163
|
+
## 3D Assets
|
|
182
164
|
|
|
183
|
-
|
|
184
|
-
|
|
165
|
+
The npm package ships **JavaScript only**. GLB models, textures, and HDRI maps
|
|
166
|
+
must be self-hosted (~24 MB). They live in `assets/` in this repository.
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
new EmotiveMascot3D({
|
|
170
|
+
assetBasePath: '/assets', // wherever you host the assets folder
|
|
171
|
+
});
|
|
185
172
|
```
|
|
186
173
|
|
|
187
|
-
|
|
174
|
+
| Hosting Option | `assetBasePath` |
|
|
175
|
+
| --------------------- | --------------------------------------------------- |
|
|
176
|
+
| **Copy to `public/`** | `'/assets'` |
|
|
177
|
+
| **CDN / S3** | `'https://cdn.example.com/emotive-engine/assets'` |
|
|
178
|
+
| **GitHub Pages** | `'https://joshtol.github.io/emotive-engine/assets'` |
|
|
188
179
|
|
|
189
|
-
```bash
|
|
190
|
-
npm install three
|
|
191
180
|
```
|
|
181
|
+
<assetBasePath>/
|
|
182
|
+
├── models/Elements/ # GLB models for elemental effects
|
|
183
|
+
├── textures/ # Crystal, Moon, Sun textures
|
|
184
|
+
└── hdri/ # Environment maps (optional)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
192
188
|
|
|
193
|
-
|
|
189
|
+
## CDN Usage
|
|
194
190
|
|
|
195
191
|
```html
|
|
196
|
-
<!-- 2D
|
|
192
|
+
<!-- 2D (UMD, no dependencies) -->
|
|
197
193
|
<script src="https://unpkg.com/@joshtol/emotive-engine/dist/emotive-mascot.umd.js"></script>
|
|
198
194
|
|
|
199
|
-
<!-- 3D
|
|
195
|
+
<!-- 3D (ESM, requires Three.js import map) -->
|
|
200
196
|
<script type="importmap">
|
|
201
197
|
{
|
|
202
198
|
"imports": {
|
|
@@ -211,343 +207,15 @@ Or via CDN:
|
|
|
211
207
|
|
|
212
208
|
---
|
|
213
209
|
|
|
214
|
-
##
|
|
215
|
-
|
|
216
|
-
The npm package ships **JavaScript only** — GLB models, textures, and HDRI maps
|
|
217
|
-
are **not** included to keep the package lean (~4 MB vs ~28 MB).
|
|
218
|
-
|
|
219
|
-
The assets live in the repository under `assets/models/` and `assets/textures/`.
|
|
220
|
-
To use 3D mode, self-host them and point the engine at your copy:
|
|
221
|
-
|
|
222
|
-
```javascript
|
|
223
|
-
const mascot = new EmotiveMascot3D({
|
|
224
|
-
coreGeometry: 'crystal',
|
|
225
|
-
assetBasePath: '/assets', // wherever you host the assets folder
|
|
226
|
-
});
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Hosting Options
|
|
230
|
-
|
|
231
|
-
| Option | Example `assetBasePath` |
|
|
232
|
-
| --------------------- | ------------------------------------------------------------------------ |
|
|
233
|
-
| **Copy to `public/`** | `'/assets'` |
|
|
234
|
-
| **CDN / S3** | `'https://cdn.example.com/emotive-engine/assets'` |
|
|
235
|
-
| **GitHub Pages** | `'https://joshtol.github.io/emotive-engine/assets'` |
|
|
236
|
-
| **unpkg (repo)** | `'https://raw.githubusercontent.com/joshtol/emotive-engine/main/assets'` |
|
|
237
|
-
|
|
238
|
-
The expected directory structure under your `assetBasePath`:
|
|
239
|
-
|
|
240
|
-
```
|
|
241
|
-
<assetBasePath>/
|
|
242
|
-
├── models/
|
|
243
|
-
│ └── Elements/ # GLB models for elemental effects
|
|
244
|
-
├── textures/
|
|
245
|
-
│ ├── Crystal/ # Crystal & heart geometry textures
|
|
246
|
-
│ ├── Moon/ # Moon geometry textures
|
|
247
|
-
│ └── Sun/ # Sun geometry textures
|
|
248
|
-
└── hdri/ # Environment maps (optional, enhances reflections)
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
> Assets are available in the repository under `assets/` and `public/hdri/`.
|
|
252
|
-
|
|
253
|
-
> **2D mode does not require any external assets** — it works out of the box.
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## Quick Start
|
|
258
|
-
|
|
259
|
-
### 3D Mode (WebGL)
|
|
260
|
-
|
|
261
|
-
```javascript
|
|
262
|
-
import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d';
|
|
263
|
-
|
|
264
|
-
const mascot = new EmotiveMascot3D({
|
|
265
|
-
coreGeometry: 'crystal', // crystal, diamond, heart, moon, rough, sphere, star, sun
|
|
266
|
-
assetBasePath: '/assets', // path to self-hosted assets (see 3D Assets section)
|
|
267
|
-
enableParticles: true,
|
|
268
|
-
enablePostProcessing: true,
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
mascot.init(document.getElementById('container'));
|
|
272
|
-
mascot.start();
|
|
273
|
-
|
|
274
|
-
// Control emotions and gestures
|
|
275
|
-
mascot.setEmotion('joy');
|
|
276
|
-
mascot.express('bounce');
|
|
277
|
-
mascot.morphTo('heart');
|
|
278
|
-
```
|
|
210
|
+
## Documentation
|
|
279
211
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
defaultEmotion: 'neutral',
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
await mascot.init(document.getElementById('container'));
|
|
291
|
-
mascot.start();
|
|
292
|
-
|
|
293
|
-
// Same API as 3D
|
|
294
|
-
mascot.setEmotion('joy');
|
|
295
|
-
mascot.express('bounce');
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
---
|
|
299
|
-
|
|
300
|
-
## LLM Integration with feel()
|
|
301
|
-
|
|
302
|
-
The `feel()` method lets LLMs control the mascot using natural language:
|
|
303
|
-
|
|
304
|
-
```javascript
|
|
305
|
-
// Simple emotion
|
|
306
|
-
mascot.feel('happy');
|
|
307
|
-
|
|
308
|
-
// Emotion with gesture
|
|
309
|
-
mascot.feel('curious, leaning in');
|
|
310
|
-
|
|
311
|
-
// With undertone modifier
|
|
312
|
-
mascot.feel('happy but nervous');
|
|
313
|
-
|
|
314
|
-
// With shape morph
|
|
315
|
-
mascot.feel('loving, heart shape, sparkle');
|
|
316
|
-
|
|
317
|
-
// With intensity
|
|
318
|
-
mascot.feel('very angry, shaking');
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
The engine parses ~1400 synonyms to understand natural expressions. For full
|
|
322
|
-
documentation, see [LLM Integration Guide](./docs/LLM_INTEGRATION.md).
|
|
323
|
-
|
|
324
|
-
### LLM System Prompt Example
|
|
325
|
-
|
|
326
|
-
```
|
|
327
|
-
After each response, output: FEEL: <emotion>, <gesture>
|
|
328
|
-
|
|
329
|
-
Examples:
|
|
330
|
-
- Greeting: FEEL: happy, wave
|
|
331
|
-
- Thinking: FEEL: focused, leaning in
|
|
332
|
-
- Celebrating: FEEL: euphoric, star shape, sparkle
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
## Emotions
|
|
338
|
-
|
|
339
|
-
15 built-in emotional states with unique visual characteristics:
|
|
340
|
-
|
|
341
|
-
| Emotion | Description | Emotion | Description |
|
|
342
|
-
| ----------- | ---------------- | ---------- | -------------- |
|
|
343
|
-
| `neutral` | Default calm | `joy` | Happy, upbeat |
|
|
344
|
-
| `calm` | Peaceful | `love` | Affectionate |
|
|
345
|
-
| `excited` | High energy | `euphoria` | Peak happiness |
|
|
346
|
-
| `sadness` | Melancholy | `anger` | Frustrated |
|
|
347
|
-
| `fear` | Anxious | `surprise` | Startled |
|
|
348
|
-
| `disgust` | Repulsed | `focused` | Concentrated |
|
|
349
|
-
| `suspicion` | Wary | `resting` | Idle/sleep |
|
|
350
|
-
| `glitch` | Digital artifact | | |
|
|
351
|
-
|
|
352
|
-
```javascript
|
|
353
|
-
mascot.setEmotion('joy');
|
|
354
|
-
mascot.setEmotion('calm', 'peaceful'); // with undertone
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
---
|
|
358
|
-
|
|
359
|
-
## Gestures
|
|
360
|
-
|
|
361
|
-
180+ base gestures in multiple categories:
|
|
362
|
-
|
|
363
|
-
**Motion:** `bounce`, `pulse`, `shake`, `nod`, `sway`, `float`, `wiggle`, `lean`
|
|
364
|
-
|
|
365
|
-
**Transform:** `spin`, `spinLeft`, `spinRight`, `jump`, `morph`, `stretch`,
|
|
366
|
-
`tilt`, `twist`
|
|
367
|
-
|
|
368
|
-
**Effects:** `wave`, `flicker`, `burst`, `flash`, `glow`, `breathe`, `expand`
|
|
369
|
-
|
|
370
|
-
**Directional (Dance):**
|
|
371
|
-
|
|
372
|
-
- `stepLeft`, `stepRight`, `stepUp`, `stepDown` - Quick 1-beat weight shifts
|
|
373
|
-
- `slideLeft`, `slideRight` - Smooth 2-beat glides
|
|
374
|
-
- `leanLeft`, `leanRight` - Body tilts
|
|
375
|
-
- `kickLeft`, `kickRight` - Side kicks
|
|
376
|
-
|
|
377
|
-
**Directional (Storytelling):**
|
|
378
|
-
|
|
379
|
-
- `floatUp`, `floatDown`, `floatLeft`, `floatRight` - Ethereal drift
|
|
380
|
-
- `pointUp`, `pointDown`, `pointLeft`, `pointRight` - Indication
|
|
381
|
-
|
|
382
|
-
```javascript
|
|
383
|
-
mascot.express('bounce');
|
|
384
|
-
mascot.express('stepLeft'); // Directional dance move
|
|
385
|
-
mascot.chain('bounce > spin > pulse'); // Sequential
|
|
386
|
-
mascot.chain('sway+breathe+float'); // Simultaneous
|
|
387
|
-
mascot.feel('look to the stars'); // Natural language → pointUp
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
---
|
|
391
|
-
|
|
392
|
-
## Elemental Gestures (3D)
|
|
393
|
-
|
|
394
|
-
The elemental bundle adds **160+ gestures** across 8 elements, each with custom
|
|
395
|
-
GLSL shaders, instanced GPU models, and per-element bloom thresholds:
|
|
396
|
-
|
|
397
|
-
| Element | Gestures | Key Effects |
|
|
398
|
-
| --------------- | -------- | ------------------------------------------ |
|
|
399
|
-
| **Fire** | 19 | Additive flame stacking, decoupled alpha |
|
|
400
|
-
| **Water** | 20 | Splash rings, flow dynamics |
|
|
401
|
-
| **Ice** | 16 | Voronoi cracks, subsurface refraction |
|
|
402
|
-
| **Electricity** | 22 | 3D Voronoi bolts, lightning flash mechanic |
|
|
403
|
-
| **Earth** | 22 | Petrify, rumble, quake effects |
|
|
404
|
-
| **Nature** | 21 | Entangle, bloom, seed burst |
|
|
405
|
-
| **Light** | 23 | Purify, beacon, ascend |
|
|
406
|
-
| **Void** | 17 | Singularity, drain, corruption |
|
|
407
|
-
|
|
408
|
-
```javascript
|
|
409
|
-
// Import from the elementals bundle — includes all 8 elements + 160+ gestures
|
|
410
|
-
import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d-elementals';
|
|
411
|
-
|
|
412
|
-
mascot.express('firecrown');
|
|
413
|
-
mascot.express('icevortex');
|
|
414
|
-
mascot.express('zap');
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
> Elemental gestures require the 3D assets to be self-hosted — see
|
|
418
|
-
> [3D Assets](#3d-assets-models--textures).
|
|
419
|
-
|
|
420
|
-
---
|
|
421
|
-
|
|
422
|
-
## 3D Geometries
|
|
423
|
-
|
|
424
|
-
| Geometry | Description | Shader |
|
|
425
|
-
| --------- | ------------------------- | ------------------------ |
|
|
426
|
-
| `crystal` | Faceted hexagonal crystal | Subsurface scattering |
|
|
427
|
-
| `diamond` | Brilliant-cut diamond | Subsurface scattering |
|
|
428
|
-
| `heart` | Heart-shaped crystal | Subsurface scattering |
|
|
429
|
-
| `moon` | Realistic lunar surface | Custom phase shader |
|
|
430
|
-
| `rough` | Rough organic crystal | Subsurface scattering |
|
|
431
|
-
| `sphere` | Smooth sphere | Standard PBR |
|
|
432
|
-
| `star` | Five-pointed star | Subsurface scattering |
|
|
433
|
-
| `sun` | Solar sphere with corona | Emissive + corona layers |
|
|
434
|
-
|
|
435
|
-
```javascript
|
|
436
|
-
mascot.morphTo('heart'); // Runtime geometry morphing
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### Moon Phase Control
|
|
440
|
-
|
|
441
|
-
```javascript
|
|
442
|
-
import { setMoonPhase, MOON_PHASES } from '@joshtol/emotive-engine/3d';
|
|
443
|
-
|
|
444
|
-
setMoonPhase(mascot.core3D, MOON_PHASES.FULL);
|
|
445
|
-
setMoonPhase(mascot.core3D, MOON_PHASES.CRESCENT_WAXING);
|
|
446
|
-
|
|
447
|
-
// All phases: NEW, CRESCENT_WAXING, FIRST_QUARTER, GIBBOUS_WAXING,
|
|
448
|
-
// FULL, GIBBOUS_WANING, LAST_QUARTER, CRESCENT_WANING
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
### Eclipse Effects
|
|
452
|
-
|
|
453
|
-
```javascript
|
|
454
|
-
// Solar eclipse (animated transition)
|
|
455
|
-
mascot.startSolarEclipse({ type: 'total' }); // 'total' or 'annular'
|
|
456
|
-
|
|
457
|
-
// Lunar eclipse (blood moon)
|
|
458
|
-
mascot.startLunarEclipse({ type: 'total' }); // 'total', 'partial', or 'penumbral'
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
---
|
|
462
|
-
|
|
463
|
-
## Configuration
|
|
464
|
-
|
|
465
|
-
### 3D Options
|
|
466
|
-
|
|
467
|
-
```javascript
|
|
468
|
-
new EmotiveMascot3D({
|
|
469
|
-
// Geometry
|
|
470
|
-
coreGeometry: 'crystal', // crystal, diamond, heart, moon, rough, sphere, star, sun
|
|
471
|
-
assetBasePath: '/assets',
|
|
472
|
-
|
|
473
|
-
// Rendering
|
|
474
|
-
enableParticles: true,
|
|
475
|
-
enablePostProcessing: true, // Bloom effects
|
|
476
|
-
enableShadows: false,
|
|
477
|
-
|
|
478
|
-
// Camera
|
|
479
|
-
enableControls: true, // Orbit controls
|
|
480
|
-
autoRotate: true,
|
|
481
|
-
cameraDistance: 3,
|
|
482
|
-
|
|
483
|
-
// Animation
|
|
484
|
-
enableBlinking: true,
|
|
485
|
-
enableBreathing: true,
|
|
486
|
-
targetFPS: 60,
|
|
487
|
-
});
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
### 2D Options
|
|
491
|
-
|
|
492
|
-
```javascript
|
|
493
|
-
new EmotiveMascot({
|
|
494
|
-
canvasId: 'mascot',
|
|
495
|
-
targetFPS: 60,
|
|
496
|
-
enableParticles: true,
|
|
497
|
-
maxParticles: 300,
|
|
498
|
-
adaptive: true, // Auto quality adjustment
|
|
499
|
-
});
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
---
|
|
503
|
-
|
|
504
|
-
## API Reference
|
|
505
|
-
|
|
506
|
-
### Core Methods (Both Modes)
|
|
507
|
-
|
|
508
|
-
```javascript
|
|
509
|
-
// Lifecycle
|
|
510
|
-
mascot.init(container);
|
|
511
|
-
mascot.start();
|
|
512
|
-
mascot.stop();
|
|
513
|
-
mascot.destroy();
|
|
514
|
-
|
|
515
|
-
// Natural language control (LLM-friendly)
|
|
516
|
-
mascot.feel('happy, bouncing');
|
|
517
|
-
mascot.feel('curious, leaning in');
|
|
518
|
-
|
|
519
|
-
// Emotions
|
|
520
|
-
mascot.setEmotion(name);
|
|
521
|
-
mascot.setEmotion(name, undertone);
|
|
522
|
-
|
|
523
|
-
// Gestures
|
|
524
|
-
mascot.express(gesture);
|
|
525
|
-
mascot.chain('gesture1 > gesture2');
|
|
526
|
-
|
|
527
|
-
// Shapes
|
|
528
|
-
mascot.morphTo(shape);
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
### 3D-Specific Methods
|
|
532
|
-
|
|
533
|
-
```javascript
|
|
534
|
-
// Toggle features
|
|
535
|
-
mascot.enableParticles();
|
|
536
|
-
mascot.disableParticles();
|
|
537
|
-
mascot.enableAutoRotate();
|
|
538
|
-
mascot.disableAutoRotate();
|
|
539
|
-
|
|
540
|
-
// Camera
|
|
541
|
-
mascot.setCameraPreset('front'); // front, side, top, angle
|
|
542
|
-
|
|
543
|
-
// Ambient Groove (rhythm-synced idle animation)
|
|
544
|
-
mascot.setGroove('groove1'); // Subtle, elegant (default)
|
|
545
|
-
mascot.setGroove('groove2'); // Energetic, bouncy
|
|
546
|
-
mascot.setGroove('groove3'); // Smooth, flowing
|
|
547
|
-
mascot.setGroove('groove2', { bars: 2 }); // Morph over 2 bars
|
|
548
|
-
mascot.enableGroove();
|
|
549
|
-
mascot.disableGroove();
|
|
550
|
-
```
|
|
212
|
+
| Doc | Description |
|
|
213
|
+
| ------------------------------------------------ | ------------------------------------------------------------------ |
|
|
214
|
+
| **[API Reference](./docs/API.md)** | All methods, configuration options, emotions, gestures, geometries |
|
|
215
|
+
| **[LLM Integration](./docs/LLM_INTEGRATION.md)** | Natural language `feel()` API, system prompt examples |
|
|
216
|
+
| **[Gestures](./docs/GESTURES.md)** | Full gesture catalog (180+ base + 160+ elemental) |
|
|
217
|
+
| **[Quick Reference](./docs/QUICK_REFERENCE.md)** | Cheat sheet for emotions, undertones, and common patterns |
|
|
218
|
+
| **[Architecture](./docs/ARCHITECTURE.md)** | Internal design and rendering pipeline |
|
|
551
219
|
|
|
552
220
|
---
|
|
553
221
|
|
|
@@ -556,132 +224,15 @@ mascot.disableGroove();
|
|
|
556
224
|
```bash
|
|
557
225
|
git clone https://github.com/joshtol/emotive-engine.git
|
|
558
226
|
cd emotive-engine
|
|
559
|
-
npm install
|
|
560
|
-
|
|
561
|
-
npm run local
|
|
562
|
-
|
|
563
|
-
# Open http://localhost:3001
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
Or view the [live demo gallery](https://joshtol.github.io/emotive-engine).
|
|
567
|
-
|
|
568
|
-
---
|
|
569
|
-
|
|
570
|
-
## Browser Support
|
|
571
|
-
|
|
572
|
-
| Browser | Version |
|
|
573
|
-
| -------------- | ------- |
|
|
574
|
-
| Chrome/Edge | 90+ |
|
|
575
|
-
| Firefox | 88+ |
|
|
576
|
-
| Safari | 14+ |
|
|
577
|
-
| iOS Safari | 14+ |
|
|
578
|
-
| Chrome Android | 90+ |
|
|
579
|
-
|
|
580
|
-
3D mode requires WebGL 2.0 support.
|
|
581
|
-
|
|
582
|
-
---
|
|
583
|
-
|
|
584
|
-
## Multi-Instance Support
|
|
585
|
-
|
|
586
|
-
Multiple mascots can run independently on the same page. Each instance has its
|
|
587
|
-
own animation loop, emotion state, and resources.
|
|
588
|
-
|
|
589
|
-
```javascript
|
|
590
|
-
import { EmotiveMascot3D } from '@joshtol/emotive-engine/3d';
|
|
591
|
-
|
|
592
|
-
// Create two independent mascots
|
|
593
|
-
const mascot1 = new EmotiveMascot3D({ coreGeometry: 'crystal' });
|
|
594
|
-
const mascot2 = new EmotiveMascot3D({ coreGeometry: 'moon' });
|
|
595
|
-
|
|
596
|
-
mascot1.init(document.getElementById('container-1'));
|
|
597
|
-
mascot2.init(document.getElementById('container-2'));
|
|
598
|
-
|
|
599
|
-
mascot1.start();
|
|
600
|
-
mascot2.start();
|
|
601
|
-
|
|
602
|
-
// Control independently
|
|
603
|
-
mascot1.setEmotion('joy');
|
|
604
|
-
mascot2.setEmotion('calm');
|
|
605
|
-
|
|
606
|
-
// Stop one without affecting the other
|
|
607
|
-
mascot1.stop();
|
|
608
|
-
mascot2.express('bounce'); // Still running
|
|
227
|
+
npm install && npm run build && npm run local
|
|
228
|
+
# → http://localhost:3001
|
|
609
229
|
```
|
|
610
230
|
|
|
611
|
-
See the
|
|
612
|
-
[dual mascot demo](https://joshtol.github.io/emotive-engine/examples/3d/dual-mascot-test.html)
|
|
613
|
-
for a live example.
|
|
614
|
-
|
|
615
|
-
---
|
|
616
|
-
|
|
617
|
-
## Server-Side Rendering (SSR)
|
|
618
|
-
|
|
619
|
-
The engine requires a browser environment. For SSR frameworks, use dynamic
|
|
620
|
-
imports:
|
|
621
|
-
|
|
622
|
-
### Next.js
|
|
623
|
-
|
|
624
|
-
```javascript
|
|
625
|
-
import dynamic from 'next/dynamic';
|
|
626
|
-
|
|
627
|
-
const MascotComponent = dynamic(
|
|
628
|
-
() =>
|
|
629
|
-
import('@joshtol/emotive-engine/3d').then(mod => {
|
|
630
|
-
// Initialize after dynamic import
|
|
631
|
-
const mascot = new mod.EmotiveMascot3D({ coreGeometry: 'crystal' });
|
|
632
|
-
return { default: () => <div ref={el => el && mascot.init(el)} /> };
|
|
633
|
-
}),
|
|
634
|
-
{ ssr: false }
|
|
635
|
-
);
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
### Nuxt 3
|
|
639
|
-
|
|
640
|
-
```vue
|
|
641
|
-
<template>
|
|
642
|
-
<ClientOnly>
|
|
643
|
-
<div ref="container" />
|
|
644
|
-
</ClientOnly>
|
|
645
|
-
</template>
|
|
646
|
-
|
|
647
|
-
<script setup>
|
|
648
|
-
const container = ref(null);
|
|
649
|
-
|
|
650
|
-
onMounted(async () => {
|
|
651
|
-
const { EmotiveMascot3D } = await import('@joshtol/emotive-engine/3d');
|
|
652
|
-
const mascot = new EmotiveMascot3D({ coreGeometry: 'crystal' });
|
|
653
|
-
mascot.init(container.value);
|
|
654
|
-
mascot.start();
|
|
655
|
-
});
|
|
656
|
-
</script>
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
### SSR Detection Helper
|
|
660
|
-
|
|
661
|
-
```javascript
|
|
662
|
-
import { isSSR } from '@joshtol/emotive-engine/3d';
|
|
663
|
-
|
|
664
|
-
if (!isSSR()) {
|
|
665
|
-
// Safe to initialize mascot
|
|
666
|
-
}
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
---
|
|
670
|
-
|
|
671
|
-
## Performance Tips
|
|
672
|
-
|
|
673
|
-
- Disable post-processing on mobile for 60fps
|
|
674
|
-
- Use `enableShadows: false` unless needed
|
|
675
|
-
- Lower `maxParticles` on constrained devices
|
|
676
|
-
- 2D mode is lighter weight for simple use cases
|
|
677
|
-
|
|
678
231
|
---
|
|
679
232
|
|
|
680
233
|
## License
|
|
681
234
|
|
|
682
|
-
MIT
|
|
683
|
-
|
|
684
|
-
---
|
|
235
|
+
MIT — see [LICENSE.md](./LICENSE.md)
|
|
685
236
|
|
|
686
237
|
<div align="center">
|
|
687
238
|
|