wissive 0.1.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/LICENSE +21 -0
- package/README.md +193 -0
- package/dist/index.d.ts +695 -0
- package/dist/react.cjs +2 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.ts +52 -0
- package/dist/react.js +17 -0
- package/dist/react.js.map +1 -0
- package/dist/vue.cjs +2 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.ts +78 -0
- package/dist/vue.js +22 -0
- package/dist/vue.js.map +1 -0
- package/dist/wissive.cjs +187 -0
- package/dist/wissive.cjs.map +1 -0
- package/dist/wissive.js +2687 -0
- package/dist/wissive.js.map +1 -0
- package/dist/wissive.umd.js +187 -0
- package/dist/wissive.umd.js.map +1 -0
- package/package.json +86 -0
- package/src/astro/Wissive.astro +79 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
/** Todos los estados, sin repetidos, en orden de grupo */
|
|
2
|
+
export declare const ALL_STATES: InteractionState[];
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Todo estado que un emoji podría "visitar" al deambular — es decir, todos
|
|
6
|
+
* menos los de Interacción (idle/near/hover/click no se "visitan", los
|
|
7
|
+
* decide la interacción real del usuario). A diferencia de AUTONOMOUS_STATES,
|
|
8
|
+
* esto SÍ incluye Ciclo de producto/Morfos de agente: sirve como el universo
|
|
9
|
+
* de opciones cuando alguien elige el banco a mano (p.ej. el picker del
|
|
10
|
+
* emoji personalizado) — ahí ya no es la librería "mintiendo" por su cuenta,
|
|
11
|
+
* es una elección explícita del usuario para su propio emoji.
|
|
12
|
+
*/
|
|
13
|
+
export declare const ALL_WANDERABLE_STATES: InteractionState[];
|
|
14
|
+
|
|
15
|
+
declare class AnimationLoop {
|
|
16
|
+
private callbacks;
|
|
17
|
+
private handle;
|
|
18
|
+
private lastTime;
|
|
19
|
+
add(cb: FrameCallback): void;
|
|
20
|
+
remove(cb: FrameCallback): void;
|
|
21
|
+
get size(): number;
|
|
22
|
+
private tick;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Aplica la animación idle correspondiente al perfil de movimiento.
|
|
27
|
+
* `intensity` reduce la amplitud sin apagarla — los estados near/hover/click
|
|
28
|
+
* siguen respirando en vez de quedarse congelados.
|
|
29
|
+
*/
|
|
30
|
+
export declare function applyIdleMotion(motionType: MotionType, p: FaceParameters, t: number, speed: number, amp: number, intensity?: number): void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Aplica el movimiento propio de un estado.
|
|
34
|
+
* Devuelve `false` si el estado no tiene firma propia — en ese caso el llamador
|
|
35
|
+
* debe recurrir a la animación de personalidad del emoji.
|
|
36
|
+
*/
|
|
37
|
+
export declare function applyStateMotion(state: string, p: FaceParameters, t: number, speed: number, amp: number): boolean;
|
|
38
|
+
|
|
39
|
+
export declare function attachEventListeners(element: HTMLElement, callbacks: EventCallbacks, nearRadius?: number): () => void;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Estados que el emoji puede visitar por su cuenta en reposo (deambular
|
|
43
|
+
* autónomo) — solo "Reacciones": son expresión pura, sin significado de
|
|
44
|
+
* aplicación. Deliberadamente NO incluye "Ciclo de producto" ni "Morfos de
|
|
45
|
+
* agente" (uploading, thinking, orbit…): esos los debe fijar la app anfitriona
|
|
46
|
+
* porque comunican un estado real, y mostrarlos al azar sería mentir.
|
|
47
|
+
*/
|
|
48
|
+
export declare const AUTONOMOUS_STATES: InteractionState[];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Interpola suavemente entre dos colores HEX
|
|
52
|
+
*/
|
|
53
|
+
export declare function blendColors(colorA: string, colorB: string, factor: number): string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Construye una definición de emoji personalizado: base neutra (Cota),
|
|
57
|
+
* silueta a elección (circle por default), con ojos/boca/animación tomados
|
|
58
|
+
* opcionalmente de cualquier otro emoji del catálogo.
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildCustomEmoji(name: string, options?: CustomEmojiOptions): EmojiDefinition;
|
|
61
|
+
|
|
62
|
+
export declare function buildFace(silhouette: SilhouetteType, baseColor: string, params: FaceParameters, size: number, renderOptions?: RenderOptions, time?: number): string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Verifica si el ratio de contraste cumple con los criterios mínimos de WCAG (3:1 para componentes gráficos).
|
|
66
|
+
*/
|
|
67
|
+
export declare function checkContrast(bgColor: string, fgColor: string, minRatio?: number): {
|
|
68
|
+
ratio: number;
|
|
69
|
+
passes: boolean;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export declare type CoreInteractionState = 'idle' | 'near' | 'hover' | 'click';
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Construye (o reconstruye) un emoji personalizado, lo persiste en localStorage
|
|
76
|
+
* y lo registra en LIB para poder usarlo directamente con createEmoji(name, ...).
|
|
77
|
+
*/
|
|
78
|
+
export declare function createCustomEmoji(name: string, options?: CustomEmojiOptions): EmojiDefinition;
|
|
79
|
+
|
|
80
|
+
export declare function createEmoji(name: string, options: WissiveOptions): WissiveInstance;
|
|
81
|
+
|
|
82
|
+
export declare function createEmojiGroup(instances?: WissiveInstance[], options?: EmojiGroupOptions): EmojiGroup;
|
|
83
|
+
|
|
84
|
+
export declare function createMultiSpring<T extends Record<string, number>>(initialValues: T, config?: Partial<SpringConfig>): MultiSpring<T>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Encadena expresiones en una línea de tiempo.
|
|
88
|
+
*
|
|
89
|
+
* No toca resortes ni DOM: recibe `resolveStep` (paso → parámetros) y
|
|
90
|
+
* `applyStep` (parámetros → destino), de modo que la interpolación entre pasos
|
|
91
|
+
* la sigue haciendo el motor de resortes que ya existe.
|
|
92
|
+
*/
|
|
93
|
+
export declare function createSequencePlayer(hooks: {
|
|
94
|
+
resolveStep: (step: SequenceStep) => Partial<FaceParameters>;
|
|
95
|
+
applyStep: (params: Partial<FaceParameters>) => void;
|
|
96
|
+
}): SequencePlayer;
|
|
97
|
+
|
|
98
|
+
export declare type CueSoundType = 'chime' | 'sparkle' | 'droplet' | 'bloom' | 'whisper' | 'tick' | 'press' | 'release' | 'toggle' | 'success' | 'error' | 'page' | 'loading' | 'ready' | 'pulse' | 'scan' | 'arrival';
|
|
99
|
+
|
|
100
|
+
export declare interface CustomEmojiOptions {
|
|
101
|
+
/** Color base, ej. '#F2A9B8' */
|
|
102
|
+
baseColor?: string;
|
|
103
|
+
/** Silueta base — cualquiera de las 22 que soporta getSilhouettePath() en
|
|
104
|
+
* render/svg.ts (las 14 de los personajes del catálogo + 8 sin usar
|
|
105
|
+
* todavía por ninguno). Default 'circle'. */
|
|
106
|
+
silhouette?: SilhouetteType;
|
|
107
|
+
/** Nombre de un emoji del catálogo (LIB) del que tomar el tipo/tamaño de ojos */
|
|
108
|
+
eyesFrom?: string;
|
|
109
|
+
/** Nombre de un emoji del catálogo del que tomar el tipo/curva/ancho de boca */
|
|
110
|
+
mouthFrom?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Tipo de ojo crudo (ver el switch(eyeType) en render/svg.ts, 0-23) — para
|
|
113
|
+
* los tipos nuevos que ningún personaje del catálogo usa todavía (estrella,
|
|
114
|
+
* reojo, guiño). Gana sobre `eyesFrom` si se especifican los dos.
|
|
115
|
+
*/
|
|
116
|
+
eyeTypeOverride?: number;
|
|
117
|
+
/** Tipo de boca crudo (0-16), mismo caso que eyeTypeOverride. Gana sobre `mouthFrom`. */
|
|
118
|
+
mouthTypeOverride?: number;
|
|
119
|
+
/** Nombre de un emoji del catálogo del que tomar la animación idle (motion) */
|
|
120
|
+
motionFrom?: string;
|
|
121
|
+
/** Nombre de un emoji del catálogo del que tomar el estilo de partículas (burst) */
|
|
122
|
+
particlesFrom?: string;
|
|
123
|
+
/** Nombre de un emoji del catálogo del que tomar el set de sonidos */
|
|
124
|
+
soundFrom?: string;
|
|
125
|
+
/**
|
|
126
|
+
* Banco de estados que este emoji puede realizar por su cuenta en reposo
|
|
127
|
+
* (deambular autónomo) — cualquier subconjunto de ALL_WANDERABLE_STATES
|
|
128
|
+
* (todos menos idle/near/hover/click). Elegido a mano por quien arma el
|
|
129
|
+
* emoji, así que aquí sí se permiten los de "Ciclo de producto"/"Morfos
|
|
130
|
+
* de agente" — es una decisión explícita, no la librería inventando.
|
|
131
|
+
* Sin especificar, usa el banco genérico (AUTONOMOUS_STATES, 16 "Reacciones").
|
|
132
|
+
*/
|
|
133
|
+
stateBank?: InteractionState[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export declare const DEFAULT_STEP_MS = 600;
|
|
137
|
+
|
|
138
|
+
export declare class DragPhysics {
|
|
139
|
+
private posX;
|
|
140
|
+
private posY;
|
|
141
|
+
private velX;
|
|
142
|
+
private velY;
|
|
143
|
+
private dragging;
|
|
144
|
+
private startPointerX;
|
|
145
|
+
private startPointerY;
|
|
146
|
+
private lastPointerX;
|
|
147
|
+
private lastPointerY;
|
|
148
|
+
private lastPointerTime;
|
|
149
|
+
private velocitySamples;
|
|
150
|
+
private readonly MAX_SAMPLES;
|
|
151
|
+
private readonly springK;
|
|
152
|
+
private readonly springD;
|
|
153
|
+
private readonly tossDecay;
|
|
154
|
+
private readonly maxStretch;
|
|
155
|
+
private animating;
|
|
156
|
+
private rafId;
|
|
157
|
+
private onUpdate;
|
|
158
|
+
private onDragStart?;
|
|
159
|
+
private onDragEnd?;
|
|
160
|
+
private el;
|
|
161
|
+
constructor(element: HTMLElement, onUpdate: (state: DragPhysicsState) => void, options?: {
|
|
162
|
+
onDragStart?: () => void;
|
|
163
|
+
onDragEnd?: () => void;
|
|
164
|
+
});
|
|
165
|
+
private handlePointerDown;
|
|
166
|
+
private handlePointerMove;
|
|
167
|
+
private handlePointerUp;
|
|
168
|
+
private handleTouchDown;
|
|
169
|
+
private handleTouchMove;
|
|
170
|
+
private handleTouchUp;
|
|
171
|
+
private startDrag;
|
|
172
|
+
private moveDrag;
|
|
173
|
+
private endDrag;
|
|
174
|
+
private startPhysicsLoop;
|
|
175
|
+
private physicsTick;
|
|
176
|
+
private emitState;
|
|
177
|
+
destroy(): void;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Drag & Toss physics with elastic Squash & Stretch deformation.
|
|
182
|
+
*
|
|
183
|
+
* The user can grab an emoji and drag it around. While dragging, the body
|
|
184
|
+
* stretches in the direction of movement. When released, it flies away with
|
|
185
|
+
* the accumulated velocity and bounces back to its origin like jelly.
|
|
186
|
+
*/
|
|
187
|
+
export declare interface DragPhysicsState {
|
|
188
|
+
/** Current visual offset from origin (px) */
|
|
189
|
+
offsetX: number;
|
|
190
|
+
offsetY: number;
|
|
191
|
+
/** Squash & Stretch deformation for CSS transform */
|
|
192
|
+
scaleX: number;
|
|
193
|
+
scaleY: number;
|
|
194
|
+
/** Rotation from drag inertia (rad) */
|
|
195
|
+
rotation: number;
|
|
196
|
+
/** true while the user is actively dragging */
|
|
197
|
+
isDragging: boolean;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export declare const EMOJI_BRIX: EmojiDefinition;
|
|
201
|
+
|
|
202
|
+
export declare const EMOJI_COTA: EmojiDefinition;
|
|
203
|
+
|
|
204
|
+
export declare const EMOJI_DOZY: EmojiDefinition;
|
|
205
|
+
|
|
206
|
+
export declare const EMOJI_FIDGE: EmojiDefinition;
|
|
207
|
+
|
|
208
|
+
export declare const EMOJI_KNOT: EmojiDefinition;
|
|
209
|
+
|
|
210
|
+
export declare const EMOJI_LUMO: EmojiDefinition;
|
|
211
|
+
|
|
212
|
+
export declare const EMOJI_MOCHI: EmojiDefinition;
|
|
213
|
+
|
|
214
|
+
export declare const EMOJI_NIMA: EmojiDefinition;
|
|
215
|
+
|
|
216
|
+
export declare const EMOJI_PIP: EmojiDefinition;
|
|
217
|
+
|
|
218
|
+
export declare const EMOJI_SNUG: EmojiDefinition;
|
|
219
|
+
|
|
220
|
+
export declare const EMOJI_SURI: EmojiDefinition;
|
|
221
|
+
|
|
222
|
+
export declare const EMOJI_VOID: EmojiDefinition;
|
|
223
|
+
|
|
224
|
+
export declare const EMOJI_WILT: EmojiDefinition;
|
|
225
|
+
|
|
226
|
+
export declare const EMOJI_ZUMI: EmojiDefinition;
|
|
227
|
+
|
|
228
|
+
export declare interface EmojiDefinition {
|
|
229
|
+
name: string;
|
|
230
|
+
emotion: string;
|
|
231
|
+
baseColor: string;
|
|
232
|
+
silhouette: SilhouetteType;
|
|
233
|
+
motion: MotionProfile;
|
|
234
|
+
expressions: EmojiExpressionPool;
|
|
235
|
+
/** Emoción cuyo set de partículas usar en bursts (por defecto: `emotion`) */
|
|
236
|
+
particleEmotion?: string;
|
|
237
|
+
/** Emoción cuyo set de sonidos usar (por defecto: `emotion`) */
|
|
238
|
+
soundEmotion?: string;
|
|
239
|
+
/**
|
|
240
|
+
* Banco de estados que este emoji puede visitar por su cuenta en reposo
|
|
241
|
+
* (deambular autónomo). Por defecto: `AUTONOMOUS_STATES` (todo el grupo
|
|
242
|
+
* "Reacciones"). Lo usan sobre todo los emojis personalizados, para elegir
|
|
243
|
+
* su propio repertorio en vez del genérico.
|
|
244
|
+
*/
|
|
245
|
+
autonomousStatePool?: InteractionState[];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export declare type EmojiExpressionPool = Record<string, FaceParameters[]>;
|
|
249
|
+
|
|
250
|
+
export declare class EmojiGroup {
|
|
251
|
+
private instances;
|
|
252
|
+
private options;
|
|
253
|
+
private connectedPairs;
|
|
254
|
+
private isRunning;
|
|
255
|
+
constructor(instances?: WissiveInstance[], options?: EmojiGroupOptions);
|
|
256
|
+
add(instance: WissiveInstance): void;
|
|
257
|
+
remove(instance: WissiveInstance): void;
|
|
258
|
+
start(): void;
|
|
259
|
+
stop(): void;
|
|
260
|
+
private getPairKey;
|
|
261
|
+
private update;
|
|
262
|
+
/**
|
|
263
|
+
* Reacción de sinergia entre dos emojis según sus emociones
|
|
264
|
+
*/
|
|
265
|
+
private triggerSynergy;
|
|
266
|
+
destroy(): void;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export declare interface EmojiGroupOptions {
|
|
270
|
+
proximityThreshold?: number;
|
|
271
|
+
enableGazeSync?: boolean;
|
|
272
|
+
enableSynergies?: boolean;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export declare interface EmojiTheme {
|
|
276
|
+
baseColor: string;
|
|
277
|
+
strokeColor?: string;
|
|
278
|
+
glowColor?: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export declare interface EventCallbacks {
|
|
282
|
+
onHoverStart: () => void;
|
|
283
|
+
onHoverEnd: () => void;
|
|
284
|
+
onClickStart: () => void;
|
|
285
|
+
onClickEnd: () => void;
|
|
286
|
+
onNearChange: (isNear: boolean) => void;
|
|
287
|
+
onGazeMove?: (gazeX: number, gazeY: number) => void;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export declare interface FaceParameters {
|
|
291
|
+
[key: string]: number;
|
|
292
|
+
/** Eye scale/openness [0..1] */
|
|
293
|
+
eyeOpen: number;
|
|
294
|
+
/** Overall eye size multiplier [0.5..2.0] */
|
|
295
|
+
eyeScale: number;
|
|
296
|
+
/**
|
|
297
|
+
* Eye type selector, 0-31 — ver el switch(eyeType) en render/svg.ts, es
|
|
298
|
+
* la fuente de verdad real (este comentario se desactualizó una vez, no
|
|
299
|
+
* confiar en él a ciegas si volvés a tocar el switch).
|
|
300
|
+
* [0: dot, 1: happy-arc ^, 2: wedge-squint >, 3/4: diagonal-wink-mirrored,
|
|
301
|
+
* 5: pupil-in-white, 6: heart, 7: X, 8: double-line squint, 9: eyebrows-only,
|
|
302
|
+
* 10/11: asymmetric-wink-oval, 12: cat-pupil, 13: big-pupil, 14: closed-serene-arc,
|
|
303
|
+
* 15: droopy-lid, 16: vertical-line (crying), 17: angry-diagonal-brow,
|
|
304
|
+
* 18: spiral (Knot), 19: sleepy-ring, 20: hollow-ring, 21: star,
|
|
305
|
+
* 22: side-eye, 23: single-wink, 24: anime-highlight, 25: sleepy-lash,
|
|
306
|
+
* 26: googly, 27: waterfall-cry ⊓⊓, 28: blank-stare, 29: worried-brow,
|
|
307
|
+
* 30: angry-zigzag-brow, 31: content-ring]
|
|
308
|
+
*/
|
|
309
|
+
eyeType: number;
|
|
310
|
+
/** Horizontal distance between both eyes (default 32) */
|
|
311
|
+
eyeGap: number;
|
|
312
|
+
/** Vertical position of the eye line (default 45) */
|
|
313
|
+
eyeY: number;
|
|
314
|
+
/** Vertical position of the mouth (default 63) */
|
|
315
|
+
mouthY: number;
|
|
316
|
+
/** Mouth curvature [-1..1] where 1 is happy curve, -1 is sad curve */
|
|
317
|
+
mouthCurve: number;
|
|
318
|
+
/** Mouth width relative [0.5..1.5] */
|
|
319
|
+
mouthWidth: number;
|
|
320
|
+
/** Mouth opening vertical factor [0..1] for open mouth/surprised */
|
|
321
|
+
mouthOpen: number;
|
|
322
|
+
/**
|
|
323
|
+
* Mouth type selector, 0-24 — ver el switch(mouthType) en render/svg.ts.
|
|
324
|
+
* [0: curve/line (sigue mouthCurve), 1: open-oval, 2: zigzag, 3: flat-line,
|
|
325
|
+
* 4: teeth-clench, 5: teeth-grin, 6: wide-happy-open, 7: X, 8: mask-cover,
|
|
326
|
+
* 9: wavy-w, 10: dot, 11: diagonal-line, 12: frown-curve, 13: hollow-circle,
|
|
327
|
+
* 14: none, 15: tongue-out, 16: smirk, 17: triangle-kitten, 18: cat-three (>3<),
|
|
328
|
+
* 19: box-open, 20: pursed, 21: teeth-row, 22: side-tongue, 23: mega-tongue,
|
|
329
|
+
* 24: cat-cup-smirk]
|
|
330
|
+
*/
|
|
331
|
+
mouthType: number;
|
|
332
|
+
/** Eyebrow Y offset */
|
|
333
|
+
browY: number;
|
|
334
|
+
/** Eyebrow tilt angle in degrees (+ is angry \ /, - is sad / \) */
|
|
335
|
+
browTilt: number;
|
|
336
|
+
/** Cheek opacity [0..1] */
|
|
337
|
+
cheek: number;
|
|
338
|
+
/** Vertical head bob offset in pixels */
|
|
339
|
+
bob: number;
|
|
340
|
+
/** Horizontal shift in pixels */
|
|
341
|
+
shiftX: number;
|
|
342
|
+
/** Teardrop opacity/scale [0..1] (Lumo) */
|
|
343
|
+
tears: number;
|
|
344
|
+
/** Horizontal gaze shift [-13.2..13.2] */
|
|
345
|
+
gazeX: number;
|
|
346
|
+
/** Vertical gaze shift [-8.4..8.4] */
|
|
347
|
+
gazeY: number;
|
|
348
|
+
/** 3D Head rotation angle in radians [-PI..PI] */
|
|
349
|
+
turnAngle: number;
|
|
350
|
+
/** Opacidad/intensidad del accesorio "Zzz" flotante [0..1] */
|
|
351
|
+
zzz: number;
|
|
352
|
+
/** Opacidad/intensidad de la gota de sudor [0..1] */
|
|
353
|
+
sweat: number;
|
|
354
|
+
/** Nubes de tormenta encima de la cabeza (enfado) [0..1] */
|
|
355
|
+
storm: number;
|
|
356
|
+
/** Garabato/espiral de confusión encima de la cabeza [0..1] */
|
|
357
|
+
scribble: number;
|
|
358
|
+
/** Nubecita de resoplido saliendo de la boca (agotamiento) [0..1] */
|
|
359
|
+
puff: number;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export declare type FrameCallback = (dt: number) => void;
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Calcula el ratio de contraste entre dos colores (e.g. 3:1, 4.5:1).
|
|
366
|
+
*/
|
|
367
|
+
export declare function getContrastRatio(color1: string, color2: string): number;
|
|
368
|
+
|
|
369
|
+
export declare function getEmojiDefinition(nameOrEmotion: string): EmojiDefinition;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Obtiene el volumen global actual (0.0 a 1.0).
|
|
373
|
+
*/
|
|
374
|
+
export declare function getGlobalVolume(): number;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Calcula la luminancia relativa de un color según la norma WCAG 2.1.
|
|
378
|
+
*/
|
|
379
|
+
export declare function getLuminance(color: string): number;
|
|
380
|
+
|
|
381
|
+
export declare function getSilhouettePath(silhouette: SilhouetteType): string;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Obtiene el tema sugerido para un estado dado, con fallback a la paleta predeterminada del emoji.
|
|
385
|
+
*/
|
|
386
|
+
export declare function getThemeForState(_state: InteractionState, defaultBaseColor: string): EmojiTheme;
|
|
387
|
+
|
|
388
|
+
export declare const IDLE_MOTIONS: Record<MotionType, IdleMotionFn>;
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Animación idle por personalidad.
|
|
392
|
+
*
|
|
393
|
+
* Cada emoji tiene una firma de movimiento propia. La clave para que se sienta
|
|
394
|
+
* "vivo" no es el desplazamiento principal (bob/shiftX) sino el movimiento
|
|
395
|
+
* secundario: inclinación de cabeza desfasada, respiración leída en eyeScale,
|
|
396
|
+
* micro-expresión (cejas/boca/mejillas) y acentos irregulares que rompen el
|
|
397
|
+
* bucle senoidal perfecto.
|
|
398
|
+
*
|
|
399
|
+
* Todas las funciones son ADITIVAS sobre los valores del resorte.
|
|
400
|
+
*/
|
|
401
|
+
export declare type IdleMotionFn = (p: FaceParameters, t: number, speed: number, amp: number) => void;
|
|
402
|
+
|
|
403
|
+
export declare type InteractionState = CoreInteractionState | LifecycleState | ReactionState | MorphState | ProductCycleState | (string & {});
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Consulta si el sonido está habilitado globalmente.
|
|
407
|
+
*/
|
|
408
|
+
export declare function isGlobalSoundEnabled(): boolean;
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Utilidades de accesibilidad (A11y) para Wissive:
|
|
412
|
+
* - Detección y subscripción a prefers-reduced-motion
|
|
413
|
+
* - Cálculo de luminancia relativa y ratio de contraste WCAG 2.1
|
|
414
|
+
*/
|
|
415
|
+
/**
|
|
416
|
+
* Detecta si el usuario prefiere movimiento reducido en su sistema operativo.
|
|
417
|
+
*/
|
|
418
|
+
export declare function isReducedMotionPreferred(): boolean;
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Detecta si el entorno es primariamente táctil (pantallas táctiles sin hover).
|
|
422
|
+
*/
|
|
423
|
+
export declare function isTouchDevice(): boolean;
|
|
424
|
+
|
|
425
|
+
export declare const LIB: Record<string, EmojiDefinition>;
|
|
426
|
+
|
|
427
|
+
export declare type LifecycleState = 'sleeping' | 'waking' | 'idle' | 'listening' | 'thinking' | 'searching' | 'working';
|
|
428
|
+
|
|
429
|
+
export declare function loadCustomEmoji(name: string): EmojiDefinition | null;
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Motor de resorte amortiguado (damped spring physics).
|
|
433
|
+
* Utiliza integrador numérico sub-stepped para máxima estabilidad.
|
|
434
|
+
*/
|
|
435
|
+
export declare function makeSpring(initialValue: number, config?: Partial<SpringConfig>): SpringInstance;
|
|
436
|
+
|
|
437
|
+
export declare type MorphState = 'orbit' | 'radar' | 'progress';
|
|
438
|
+
|
|
439
|
+
export declare interface MotionProfile {
|
|
440
|
+
stiffness: number;
|
|
441
|
+
damping: number;
|
|
442
|
+
idleSpeed: number;
|
|
443
|
+
idleAmplitude: number;
|
|
444
|
+
idleIntervalMin: number;
|
|
445
|
+
idleIntervalMax: number;
|
|
446
|
+
motionType: MotionType;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/** Firma de movimiento idle — una por personalidad, ver `core/motion.ts` */
|
|
450
|
+
export declare type MotionType = 'bouncy' | 'flutter' | 'serene' | 'float' | 'calm' | 'droop' | 'sob' | 'jitter' | 'fiery' | 'wilt' | 'dizzy' | 'snooze' | 'pop' | 'drift';
|
|
451
|
+
|
|
452
|
+
export declare interface MultiSpring<T extends Record<string, number>> {
|
|
453
|
+
getValues: () => T;
|
|
454
|
+
setTargets: (targets: Partial<T>) => void;
|
|
455
|
+
setValues: (values: Partial<T>) => void;
|
|
456
|
+
update: (dt: number) => boolean;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export declare class ParticleEmitter {
|
|
460
|
+
private particles;
|
|
461
|
+
private canvas;
|
|
462
|
+
private ctx;
|
|
463
|
+
private animating;
|
|
464
|
+
private rafId;
|
|
465
|
+
private size;
|
|
466
|
+
private dpr;
|
|
467
|
+
constructor(container: HTMLElement, size: number);
|
|
468
|
+
private setupCanvas;
|
|
469
|
+
resize(newSize: number): void;
|
|
470
|
+
burst(emotion: string, count?: number, originX?: number, originY?: number): void;
|
|
471
|
+
private createParticle;
|
|
472
|
+
private tick;
|
|
473
|
+
private drawParticle;
|
|
474
|
+
destroy(): void;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
export declare type ParticleShape = 'heart' | 'star' | 'sparkle' | 'drop' | 'diamond' | 'zigzag' | 'circle' | 'ring' | 'zzz' | 'petal' | 'spiral' | 'bubble' | 'ember' | 'shard' | 'burst' | 'dot' | 'glitch';
|
|
478
|
+
|
|
479
|
+
/** Estados cuya animación la pone la personalidad del emoji, no el estado */
|
|
480
|
+
export declare const PERSONALITY_DRIVEN_STATES: InteractionState[];
|
|
481
|
+
|
|
482
|
+
/** Elige uno al azar de `pool`, evitando repetir `previous` cuando hay más de una opción */
|
|
483
|
+
export declare function pickWithoutRepeat<T>(pool: T[], previous: T | null): T;
|
|
484
|
+
|
|
485
|
+
export declare type ProductCycleState = 'spawning' | 'humming' | 'loading' | 'dictating' | 'writing' | 'sending' | 'receiving' | 'uploading' | 'notifying' | 'alerting' | 'dragging' | 'bouncing' | 'powering-down';
|
|
486
|
+
|
|
487
|
+
export declare type ReactionState = 'excited' | 'surprised' | 'suspicious' | 'angry' | 'drowsy' | 'happy' | 'curious' | 'confused' | 'bored' | 'proud' | 'shy' | 'sad' | 'laughing' | 'scared' | 'playful' | 'celebrate';
|
|
488
|
+
|
|
489
|
+
export declare interface RenderOptions {
|
|
490
|
+
flipX?: boolean;
|
|
491
|
+
emphasis?: boolean;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export declare function renderSvgElement(silhouette: SilhouetteType, baseColor: string, params: FaceParameters, size: number, renderOptions?: RenderOptions): string;
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Resuelve qué banco de estados usar para deambular, en orden de prioridad:
|
|
498
|
+
* opción explícita del llamador > banco propio del emoji (p.ej. un custom
|
|
499
|
+
* con `stateBank`) > banco genérico. Función pura para poder testear la
|
|
500
|
+
* prioridad sin tener que instanciar un emoji real (createEmoji necesita DOM).
|
|
501
|
+
*/
|
|
502
|
+
export declare function resolveAutonomousStatePool(explicitPool: InteractionState[] | undefined, definitionPool: InteractionState[] | undefined): InteractionState[];
|
|
503
|
+
|
|
504
|
+
export declare function resolveSize(size?: WissiveSize): number;
|
|
505
|
+
|
|
506
|
+
export declare function saveCustomEmoji(name: string, def: EmojiDefinition): void;
|
|
507
|
+
|
|
508
|
+
export declare type SequenceMode = 'loop' | 'once' | 'ping-pong';
|
|
509
|
+
|
|
510
|
+
export declare interface SequenceOptions {
|
|
511
|
+
mode?: SequenceMode;
|
|
512
|
+
onComplete?: () => void;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export declare interface SequencePlayer {
|
|
516
|
+
play: (steps: SequenceStep[], options?: SequenceOptions) => void;
|
|
517
|
+
stop: () => void;
|
|
518
|
+
isPlaying: () => boolean;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
export declare interface SequenceStep {
|
|
522
|
+
/** Nombre de un estado del emoji (usa su pool de expresiones) */
|
|
523
|
+
state?: string;
|
|
524
|
+
/** Parámetros crudos — se aplican encima si además hay `state` */
|
|
525
|
+
params?: Partial<FaceParameters>;
|
|
526
|
+
/** ms que dura este paso antes de pasar al siguiente */
|
|
527
|
+
duration?: number;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Control global del sonido para todas las instancias de Wissive en la página.
|
|
532
|
+
*/
|
|
533
|
+
export declare function setGlobalSound(enabled: boolean): void;
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Ajusta el nivel de volumen global (0.0 a 1.0) para todos los sonidos de Wissive.
|
|
537
|
+
*/
|
|
538
|
+
export declare function setGlobalVolume(volume: number): void;
|
|
539
|
+
|
|
540
|
+
export declare const sharedLoop: AnimationLoop;
|
|
541
|
+
|
|
542
|
+
export declare type SilhouetteType = 'circle' | 'capsule' | 'rounded-squircle' | 'pear-blob' | 'egg-oval' | 'starburst-puff' | 'pill-vertical' | 'heart' | 'round-blob' | 'ghost-blob' | 'oval' | 'elongated-oval' | 'teardrop-blob' | 'flame-blob' | 'droopy-blob' | 'bear-blob' | 'spiky-blob' | 'cloud-blob' | 'wide-oval' | 'soft-round' | 'octopus-blob' | 'wave-blob';
|
|
543
|
+
|
|
544
|
+
export declare const SIZE_PRESETS: Record<WissivePresetSize, number>;
|
|
545
|
+
|
|
546
|
+
export declare class SoundEngine {
|
|
547
|
+
private enabled;
|
|
548
|
+
private volume;
|
|
549
|
+
constructor();
|
|
550
|
+
setEnabled(enabled: boolean): void;
|
|
551
|
+
isEnabled(): boolean;
|
|
552
|
+
setVolumeLevel(vol: number): void;
|
|
553
|
+
getVolumeLevel(): number;
|
|
554
|
+
playCue(cueName: CueSoundType, options?: {
|
|
555
|
+
volume?: number;
|
|
556
|
+
}): void;
|
|
557
|
+
playSound(emotion: string, action: 'hover' | 'click' | 'bounce'): void;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export declare const soundEngine: SoundEngine;
|
|
561
|
+
|
|
562
|
+
export declare interface SpringConfig {
|
|
563
|
+
stiffness: number;
|
|
564
|
+
damping: number;
|
|
565
|
+
mass: number;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export declare interface SpringInstance {
|
|
569
|
+
state: SpringState;
|
|
570
|
+
setTarget: (target: number) => void;
|
|
571
|
+
setCurrent: (value: number) => void;
|
|
572
|
+
update: (dt: number) => boolean;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export declare interface SpringState {
|
|
576
|
+
current: number;
|
|
577
|
+
target: number;
|
|
578
|
+
velocity: number;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
export declare const STATE_GROUPS: StateGroup[];
|
|
582
|
+
|
|
583
|
+
export declare const STATE_MOTIONS: Record<string, IdleMotionFn>;
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Mapeo de paleta de colores por estado de emoción/actividad
|
|
587
|
+
*/
|
|
588
|
+
export declare const STATE_THEME_MAP: Partial<Record<InteractionState, EmojiTheme>>;
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Registro de estados en runtime — fuente única de verdad.
|
|
592
|
+
*
|
|
593
|
+
* Los tipos de `types.ts` solo existen en compilación, así que la UI se
|
|
594
|
+
* inventaba su propia lista y quedó desincronizada: `idle` duplicado,
|
|
595
|
+
* etiquetas en francés y un recuento de 39 que no cuadraba con la realidad.
|
|
596
|
+
*/
|
|
597
|
+
export declare interface StateGroup {
|
|
598
|
+
label: string;
|
|
599
|
+
states: InteractionState[];
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export declare class StateManager {
|
|
603
|
+
private currentState;
|
|
604
|
+
private lastIndices;
|
|
605
|
+
getState(): InteractionState;
|
|
606
|
+
setState(newState: InteractionState): boolean;
|
|
607
|
+
resolvePool(expressions: Record<string, FaceParameters[]>, state?: InteractionState): FaceParameters[];
|
|
608
|
+
pickVariant(pool: FaceParameters[], state?: InteractionState): FaceParameters;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Se suscribe a los cambios de la preferencia prefers-reduced-motion del sistema.
|
|
613
|
+
*/
|
|
614
|
+
export declare function subscribeToReducedMotion(onChange: (reduced: boolean) => void): () => void;
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Detecta si el dispositivo actual soporta hover real (puntero fino como mouse o trackpad).
|
|
618
|
+
* Devuelve false en dispositivos táctiles primarios (smartphones, tablets sin mouse).
|
|
619
|
+
*/
|
|
620
|
+
export declare function supportsHover(): boolean;
|
|
621
|
+
|
|
622
|
+
export declare type ThemeOption = 'auto' | EmojiTheme;
|
|
623
|
+
|
|
624
|
+
declare const Wissive: {
|
|
625
|
+
create: typeof createEmoji;
|
|
626
|
+
createGroup: typeof createEmojiGroup;
|
|
627
|
+
setGlobalSound: typeof setGlobalSound;
|
|
628
|
+
isGlobalSoundEnabled: typeof isGlobalSoundEnabled;
|
|
629
|
+
setGlobalVolume: typeof setGlobalVolume;
|
|
630
|
+
getGlobalVolume: typeof getGlobalVolume;
|
|
631
|
+
supportsHover: typeof supportsHover;
|
|
632
|
+
isTouchDevice: typeof isTouchDevice;
|
|
633
|
+
};
|
|
634
|
+
export { Wissive }
|
|
635
|
+
export default Wissive;
|
|
636
|
+
|
|
637
|
+
export declare interface WissiveInstance {
|
|
638
|
+
id: string;
|
|
639
|
+
name: string;
|
|
640
|
+
emotionCategory: string;
|
|
641
|
+
getElement: () => HTMLElement;
|
|
642
|
+
getPosition: () => {
|
|
643
|
+
x: number;
|
|
644
|
+
y: number;
|
|
645
|
+
};
|
|
646
|
+
getCurrentState: () => InteractionState;
|
|
647
|
+
setEmotion: (state: InteractionState) => void;
|
|
648
|
+
spin: (turns?: number) => void;
|
|
649
|
+
bounce: () => void;
|
|
650
|
+
setGaze: (gaze: {
|
|
651
|
+
x: number;
|
|
652
|
+
y: number;
|
|
653
|
+
}) => void;
|
|
654
|
+
setGazeTracking: (enabled: boolean) => void;
|
|
655
|
+
setSound: (enabled: boolean) => void;
|
|
656
|
+
setDraggable: (enabled: boolean) => void;
|
|
657
|
+
setFlipX: (flip: boolean) => void;
|
|
658
|
+
setEmphasis: (emphasis: boolean) => void;
|
|
659
|
+
setAmbientParticles: (enabled: boolean) => void;
|
|
660
|
+
setAutonomousStates: (enabled: boolean) => void;
|
|
661
|
+
setAutonomousStatePool: (pool: InteractionState[]) => void;
|
|
662
|
+
setReducedMotion: (setting: 'auto' | boolean) => void;
|
|
663
|
+
setTheme: (theme: ThemeOption) => void;
|
|
664
|
+
setSize: (size: WissiveSize) => void;
|
|
665
|
+
triggerParticles: (count?: number) => void;
|
|
666
|
+
playSequence: (steps: SequenceStep[], options?: SequenceOptions) => void;
|
|
667
|
+
stopSequence: () => void;
|
|
668
|
+
isSequencePlaying: () => boolean;
|
|
669
|
+
destroy: () => void;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
export declare interface WissiveOptions {
|
|
673
|
+
target: HTMLElement;
|
|
674
|
+
size?: WissiveSize;
|
|
675
|
+
sound?: boolean;
|
|
676
|
+
interactive?: boolean;
|
|
677
|
+
draggable?: boolean;
|
|
678
|
+
nearRadius?: number;
|
|
679
|
+
flipX?: boolean;
|
|
680
|
+
emphasis?: boolean;
|
|
681
|
+
gazeTracking?: boolean;
|
|
682
|
+
ambientParticles?: boolean;
|
|
683
|
+
/** Visita reacciones al azar cuando está en reposo, para que se sienta vivo (default: true) */
|
|
684
|
+
autonomousStates?: boolean;
|
|
685
|
+
/** Qué estados puede visitar al deambular (default: `definition.autonomousStatePool` o AUTONOMOUS_STATES) */
|
|
686
|
+
autonomousStatePool?: InteractionState[];
|
|
687
|
+
reducedMotion?: 'auto' | boolean;
|
|
688
|
+
theme?: ThemeOption;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
export declare type WissivePresetSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl';
|
|
692
|
+
|
|
693
|
+
export declare type WissiveSize = WissivePresetSize | number;
|
|
694
|
+
|
|
695
|
+
export { }
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),t=require("react"),i=require("./wissive.cjs");function o({name:n,...s}){const e=t.useRef(null),r=t.useRef(null);return t.useEffect(()=>{if(e.current)return r.current=i.createEmoji(n,{target:e.current,...s}),()=>{var u;(u=r.current)==null||u.destroy(),r.current=null}},[n]),c.jsx("div",{ref:e})}exports.Wissive=o;
|
|
2
|
+
//# sourceMappingURL=react.cjs.map
|