@norbert_bodziony/bloub 0.3.0 → 0.6.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 +32 -5
- package/dist/package/assets/boule.webp +0 -0
- package/dist/package/assets/cloe-corps.webp +0 -0
- package/dist/package/assets/cloe-oeil0-x.webp +0 -0
- package/dist/package/assets/cloe-oeil0-y.webp +0 -0
- package/dist/package/assets/cloe-oeil1-x.webp +0 -0
- package/dist/package/assets/cloe-oeil1-y.webp +0 -0
- package/dist/package/assets/forme-capsule.webp +0 -0
- package/dist/package/assets/forme-carre.webp +0 -0
- package/dist/package/assets/forme-cercle.webp +0 -0
- package/dist/package/assets/forme-galet.webp +0 -0
- package/dist/package/assets/forme-goutte.webp +0 -0
- package/dist/package/assets/forme-hexagone.webp +0 -0
- package/dist/package/assets/forme-losange.webp +0 -0
- package/dist/package/assets/forme-nuage.webp +0 -0
- package/dist/package/assets/forme-pentagone.webp +0 -0
- package/dist/package/assets/forme-squircle.webp +0 -0
- package/dist/package/assets/forme-triangle.webp +0 -0
- package/dist/package/assets/fred-corps.webp +0 -0
- package/dist/package/assets/fred-oeil0-x.webp +0 -0
- package/dist/package/assets/fred-oeil0-y.webp +0 -0
- package/dist/package/assets/fred-oeil1-x.webp +0 -0
- package/dist/package/assets/fred-oeil1-y.webp +0 -0
- package/dist/package/assets/malu-corps.webp +0 -0
- package/dist/package/assets/malu-oeil0-x.webp +0 -0
- package/dist/package/assets/malu-oeil0-y.webp +0 -0
- package/dist/package/assets/malu-oeil1-x.webp +0 -0
- package/dist/package/assets/malu-oeil1-y.webp +0 -0
- package/dist/package/assets/nexo-corps.webp +0 -0
- package/dist/package/assets/nexo-oeil0-x.webp +0 -0
- package/dist/package/assets/nexo-oeil0-y.webp +0 -0
- package/dist/package/assets/nexo-oeil1-x.webp +0 -0
- package/dist/package/assets/nexo-oeil1-y.webp +0 -0
- package/dist/package/assets/vita-corps.webp +0 -0
- package/dist/package/assets/vita-oeil0-x.webp +0 -0
- package/dist/package/assets/vita-oeil0-y.webp +0 -0
- package/dist/package/assets/vita-oeil1-x.webp +0 -0
- package/dist/package/assets/vita-oeil1-y.webp +0 -0
- package/dist/package/assets/yoshi-corps.webp +0 -0
- package/dist/package/assets/yoshi-oeil0-x.webp +0 -0
- package/dist/package/assets/yoshi-oeil0-y.webp +0 -0
- package/dist/package/assets/yoshi-oeil1-x.webp +0 -0
- package/dist/package/assets/yoshi-oeil1-y.webp +0 -0
- package/dist/package/chunks/BloubBot-_XolrDe1.js +2226 -0
- package/dist/package/chunks/BloubBot-server-V9r0a_k-.js +1 -0
- package/dist/package/index.js +2 -2115
- package/dist/package/plush-server.js +1 -0
- package/dist/package/plush.js +1202 -0
- package/dist/package/server.js +1 -1
- package/dist/package/types/bot/engine.d.ts +57 -1
- package/dist/package/types/bot/skins.d.ts +1 -1
- package/dist/package/types/bot/states.d.ts +2 -0
- package/dist/package/types/components/BloubBot.d.ts +48 -1
- package/dist/package/types/index.d.ts +1 -1
- package/dist/package/types/plush/PlushBot.d.ts +64 -0
- package/dist/package/types/plush/assets.d.ts +1 -0
- package/dist/package/types/plush/body.d.ts +28 -0
- package/dist/package/types/plush/catalogue.d.ts +56 -0
- package/dist/package/types/plush/index.d.ts +5 -0
- package/dist/package/types/plush/layer.d.ts +36 -0
- package/dist/package/types/plush/motion.d.ts +236 -0
- package/dist/package/types/plush/slices.d.ts +49 -0
- package/dist/package/types/plush/tint.d.ts +27 -0
- package/dist/package/types/plush/transition.d.ts +33 -0
- package/dist/package/types/plush/warp.d.ts +10 -0
- package/package.json +13 -2
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { type Look } from '../bot/engine.js';
|
|
2
|
+
import { type BotExpression } from '../bot/expressions.js';
|
|
3
|
+
import { type StateId } from '../bot/states.js';
|
|
4
|
+
import type { GazeScript } from '../ui/gaze.js';
|
|
5
|
+
import type { PlushPad, PlushState } from './catalogue.js';
|
|
6
|
+
/**
|
|
7
|
+
* L'etat du moteur sous un etat de peluche. `thinking`, `asleep` et `failed` gardent le
|
|
8
|
+
* corps au repos : le moteur reste sur `idle`, la peluche ne change que le visage et le decor.
|
|
9
|
+
*/
|
|
10
|
+
export declare const engineState: (state: PlushState) => StateId;
|
|
11
|
+
/**
|
|
12
|
+
* Duree d'arrivee dans un etat : le `morph` de l'etat du moteur du meme nom. `asleep` prend
|
|
13
|
+
* celui de `sleep` (l'endormissement de la video), `failed` celui du repos, qu'il garde.
|
|
14
|
+
*/
|
|
15
|
+
export declare const morphOf: (state: PlushState) => number;
|
|
16
|
+
/**
|
|
17
|
+
* La derive du regard au repos, reduite : c'est celle que les six personnages ont eue
|
|
18
|
+
* pendant tout l'essai, celle que l'utilisateur a validee. `mix` nul : le regard reste
|
|
19
|
+
* celui de la pose (le visage au repos, le regard releve d'un clin d'oeil).
|
|
20
|
+
*/
|
|
21
|
+
export declare const REST_LOOK: Look;
|
|
22
|
+
/**
|
|
23
|
+
* Le regard pendant `thinking` : en haut, du cote des points. CHOISI, pas releve — la video
|
|
24
|
+
* n'a pas de peluche qui reflechit. Sous le tangage du visage `neutre` (28,6°), donc aucun
|
|
25
|
+
* oeil ne passe le limbe.
|
|
26
|
+
*/
|
|
27
|
+
export declare const THINK_LOOK: Look;
|
|
28
|
+
/**
|
|
29
|
+
* Le regard endormi : la derive presque eteinte (les yeux fermes ne cherchent rien) et plus
|
|
30
|
+
* aucun clignement : des yeux fermes ne clignent pas. CHOISI.
|
|
31
|
+
*/
|
|
32
|
+
export declare const ASLEEP_LOOK: Look;
|
|
33
|
+
/** Le regard d'un etat : `thinking` vise les points, `asleep` dort, les autres sont au repos. */
|
|
34
|
+
export declare const lookOf: (state: PlushState) => Look;
|
|
35
|
+
/**
|
|
36
|
+
* Un regard qui glisse de `from` a `to` en `duration`, avec la courbe des morphs du moteur.
|
|
37
|
+
* Le composant applique un script image par image (rattrapage d'1/60 s) : c'est donc au
|
|
38
|
+
* script d'etre continu, et il l'est parce que `from` est le dernier regard rendu.
|
|
39
|
+
*/
|
|
40
|
+
export declare const glide: (from: Look, to: Look, duration: number) => GazeScript;
|
|
41
|
+
/** amplitude du « non », en degres de lacet */
|
|
42
|
+
export declare const SHAKE_YAW = 12;
|
|
43
|
+
/** duree du « non » : deux allers-retours */
|
|
44
|
+
export declare const SHAKE = 0.8;
|
|
45
|
+
export declare const shake: (t: number) => number;
|
|
46
|
+
/**
|
|
47
|
+
* Le script de regard a l'entree dans un etat, depuis le dernier regard rendu : un glissement
|
|
48
|
+
* vers le regard de l'etat, et le « non » de `failed` par-dessus. Le « non » passe par `spin`,
|
|
49
|
+
* qui s'ajoute au lacet quel que soit `mix` : il secoue le regard de la pose, pas une cible.
|
|
50
|
+
*/
|
|
51
|
+
export declare function enter(from: Look, state: PlushState): GazeScript;
|
|
52
|
+
/**
|
|
53
|
+
* Endormi : les deux yeux fermes, avec le regard tombant et l'ecart de `somnolent`, le
|
|
54
|
+
* visage d'avant le sommeil. Pas au catalogue des expressions, comme les visages des
|
|
55
|
+
* personnages.
|
|
56
|
+
*/
|
|
57
|
+
export declare const ASLEEP_FACE: BotExpression;
|
|
58
|
+
/** largeur/hauteur d'un oeil rond aplati par `failed` : juste au-dela de la bande ou une pente se perd */
|
|
59
|
+
export declare const FAILED_ASPECT = 1.8;
|
|
60
|
+
/** l'oeil le plus ouvert d'un visage (aire de la gelule), que `failed` donne aux deux yeux */
|
|
61
|
+
export declare const openEye: (face: BotExpression) => 0 | 1;
|
|
62
|
+
export declare function failedFace(base: BotExpression): BotExpression;
|
|
63
|
+
/** Les patins de `failed` : celui de l'oeil le plus ouvert, chacun a sa place (`dx`, `dy`). */
|
|
64
|
+
export declare function failedPads(pads: readonly [PlushPad, PlushPad], base: BotExpression): readonly [PlushPad, PlushPad];
|
|
65
|
+
/**
|
|
66
|
+
* Le passage d'un patin a l'autre en entrant dans `failed` ou en en sortant : un fondu, sur
|
|
67
|
+
* la duree et la courbe du changement de visage du moteur (`SHAPE_MORPH`, easeOutQuint),
|
|
68
|
+
* pendant que la gelule glisse. Une photo ne se deforme pas en une autre ; sans fondu,
|
|
69
|
+
* l'oeil plisse de Vita doublait de largeur d'une image a l'autre. `start` est le niveau
|
|
70
|
+
* d'ou part le nouveau patin : un aller-retour en plein fondu repart de ce qu'on voit.
|
|
71
|
+
*/
|
|
72
|
+
export interface PadFade {
|
|
73
|
+
from: readonly [PlushPad, PlushPad] | null;
|
|
74
|
+
at: number;
|
|
75
|
+
start: number;
|
|
76
|
+
}
|
|
77
|
+
export declare const NO_PAD_FADE: PadFade;
|
|
78
|
+
/** opacite des patins courants ; ceux de `from` ont le complement */
|
|
79
|
+
export declare const padFadeLevel: (fade: PadFade, t: number) => number;
|
|
80
|
+
export declare const padFadeToggle: (fade: PadFade, from: readonly [PlushPad, PlushPad], t: number) => PadFade;
|
|
81
|
+
/**
|
|
82
|
+
* Agrandir les yeux (`eyeScale`) sans les pousser hors du corps ni les souder. Grandir chacun
|
|
83
|
+
* autour de son centre ne va pas : le regard au repos du moteur porte les yeux contre le bord,
|
|
84
|
+
* en haut a droite, et l'oeil agrandi le traverse ; et des yeux deja proches (`wide`,
|
|
85
|
+
* `notify`, Fred) se touchent. C'est donc le VISAGE entier qui grandit — tailles et ecart
|
|
86
|
+
* ensemble, aucun oeil ne gagne sur l'autre — autour de son point le plus exterieur : le
|
|
87
|
+
* point du visage le plus loin du centre du corps, dans la direction centre -> visage. Ce
|
|
88
|
+
* point reste la ou le moteur l'a pose, avec la marge que le moteur lui a laissee, et le
|
|
89
|
+
* visage gagne sa taille vers l'interieur.
|
|
90
|
+
*
|
|
91
|
+
* `eyes` : la matrice de chaque oeil (a, b, c, d, e, f, e et f deja decales du patin) et la
|
|
92
|
+
* taille de sa gelule. Rend, par oeil, le deplacement de son centre a l'ecran ; sa taille,
|
|
93
|
+
* elle, est multipliee par `scale` dans son repere. Une fonction continue de l'image
|
|
94
|
+
* courante (un `max` de fonctions continues), sans choix ni recherche : rien a faire
|
|
95
|
+
* trembler (cf. `eyefit.ts`).
|
|
96
|
+
*/
|
|
97
|
+
export declare function faceGrowth(eyes: readonly {
|
|
98
|
+
m: readonly number[];
|
|
99
|
+
w: number;
|
|
100
|
+
h: number;
|
|
101
|
+
}[], scale: number): {
|
|
102
|
+
x: number;
|
|
103
|
+
y: number;
|
|
104
|
+
}[];
|
|
105
|
+
/** les six nombres d'une chaine `matrix(a,b,c,d,e,f)` */
|
|
106
|
+
export declare const matrixOf: (transform: string) => number[];
|
|
107
|
+
/**
|
|
108
|
+
* La frange du feutre, hors de la gelule, en petits cotes : `dehors` (30 px) sur la gelule de
|
|
109
|
+
* reference (205 px de petit cote) de `tools/peluche/fit/feutre.py`. Les paupieres se posent
|
|
110
|
+
* au-dela : le patin garde son bord de fibres, qui fait la douceur de la paupiere.
|
|
111
|
+
*/
|
|
112
|
+
export declare const LID_FRANGE: number;
|
|
113
|
+
/**
|
|
114
|
+
* Douceur du bord des paupieres, au-dela de la frange, en petits cotes (CHOISI, juge a 4x sur
|
|
115
|
+
* Yoshi `curieux`, `fier` et `somnolent`) : ce qui reste de l'ombre portee s'y eteint. A 0,25,
|
|
116
|
+
* c'etait un halo translucide autour du patin.
|
|
117
|
+
*/
|
|
118
|
+
export declare const LID_SOFT = 0.1;
|
|
119
|
+
/** le bord doux en paliers : autant de gelules imbriquees (CHOISI) */
|
|
120
|
+
export declare const LID_BANDS = 4;
|
|
121
|
+
/**
|
|
122
|
+
* L'ouverture s'elargit de la gelule a toute l'image (ombre portee) en `l^LID_MARGE` (CHOISI) :
|
|
123
|
+
* a l'ouvert tout est visible, sans saut au debut d'un clignement, mais des que l'oeil se ferme
|
|
124
|
+
* un peu, les paupieres suivent la gelule, comme le trou du moteur. A 4, la marge tenait encore
|
|
125
|
+
* a mi-clignement : une gelule bien plus large que le patin, dont les arcs le coupaient presque
|
|
126
|
+
* a plat, un patin rond (Fred) se fermait en carre.
|
|
127
|
+
*/
|
|
128
|
+
export declare const LID_MARGE = 8;
|
|
129
|
+
/** les paupieres d'un oeil qui cligne */
|
|
130
|
+
export interface LidMask {
|
|
131
|
+
/** le centre de l'oeil (avant le decalage du patin) et l'ecrasement vertical, a l'ecran, autour de lui */
|
|
132
|
+
x: number;
|
|
133
|
+
y: number;
|
|
134
|
+
s: number;
|
|
135
|
+
/**
|
|
136
|
+
* des gelules imbriquees, dans le repere du patin (sous sa correction), de la plus large a
|
|
137
|
+
* l'ouverture elle-meme : demi-largeur, demi-hauteur, rayon et opacite. Peintes l'une sur
|
|
138
|
+
* l'autre, elles montent par paliers egaux de 0 au bord a 1 dans l'ouverture.
|
|
139
|
+
*/
|
|
140
|
+
bands: {
|
|
141
|
+
w: number;
|
|
142
|
+
h: number;
|
|
143
|
+
r: number;
|
|
144
|
+
alpha: number;
|
|
145
|
+
}[];
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Le moteur ferme un oeil en l'ecrasant verticalement A L'ECRAN (`open`, compose en dernier
|
|
149
|
+
* dans la matrice `L = ecrasement . L0`) : c'est la mesure pour le trou du masque plat, mais
|
|
150
|
+
* ecraser une photo de feutre en fait un baton. Le patin est donc pose avec `L0` : cette
|
|
151
|
+
* matrice, `L^-1 . L0`, se met SOUS celle de l'oeil et lui retire l'ecrasement. Oeil
|
|
152
|
+
* ouvert, `undefined` : rien a retirer.
|
|
153
|
+
*/
|
|
154
|
+
export declare function unsquash(m: readonly number[], open: number): string | undefined;
|
|
155
|
+
/**
|
|
156
|
+
* La gelule d'un oeil mi-clos AU REPOS (`rest` < 1 : `somnolent`, « paupieres a moitie
|
|
157
|
+
* tombees »), posee sous `L0` : chacun de ses axes est raccourci de ce que l'ecrasement de
|
|
158
|
+
* repos raccourcit son image a l'ecran. C'est une gelule plus courte, recomposee en morceaux
|
|
159
|
+
* comme celle de toute expression, jamais une image ecrasee. Des paupieres qui la coupaient au
|
|
160
|
+
* repos en laissaient un carre, les cotes droits et le haut et le bas fondus.
|
|
161
|
+
*/
|
|
162
|
+
export declare function restCapsule(m: readonly number[], open: number, rest: number, w: number, h: number): {
|
|
163
|
+
w: number;
|
|
164
|
+
h: number;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Un patin qui cligne garde sa forme : la fourrure du corps se ferme dessus, comme des paupieres.
|
|
168
|
+
* Amincir le patin en gelule faisait une autre gelule, pas un oeil qui se ferme ; c'est bon pour
|
|
169
|
+
* une expression au repos (`restCapsule`), pas pour le geste.
|
|
170
|
+
*
|
|
171
|
+
* L'ouverture est la gelule de l'oeil, ecrasee verticalement A L'ECRAN autour de son centre,
|
|
172
|
+
* comme le moteur ecrase le trou du masque plat : ses paupieres sont courbes et suivent
|
|
173
|
+
* l'inclinaison de l'oeil. Une bande horizontale coupait un oeil incline (`curieux`) en
|
|
174
|
+
* parallelogramme flou. L'ecrasement `s` va de 1 (`open` = `rest`, l'oeil de l'expression) a 0
|
|
175
|
+
* (`open` = `blinkScale(0)`) : le moteur garde un trait a l'oeil ferme, une fente de feutre s'y
|
|
176
|
+
* lisait comme un oeil ouvert. La gelule est elargie de la frange du feutre (`LID_FRANGE`) ; a
|
|
177
|
+
* l'ouvert, jusqu'a couvrir toute l'image, ombre comprise, une marge qui part en `l^LID_MARGE`.
|
|
178
|
+
* Bord doux sur `LID_SOFT` petit cote, au-dela. `m` : la matrice de l'oeil ; `gelule` : la demi-taille de la gelule dessinee
|
|
179
|
+
* (`restCapsule`) ; `image` : la demi-etendue de ses morceaux (`padExtent`). Hors clignement,
|
|
180
|
+
* `null` : pas de masque.
|
|
181
|
+
*/
|
|
182
|
+
export declare function lidMask(m: readonly number[], open: number, rest: number, gelule: {
|
|
183
|
+
x: number;
|
|
184
|
+
y: number;
|
|
185
|
+
}, image: {
|
|
186
|
+
x: number;
|
|
187
|
+
y: number;
|
|
188
|
+
}): LidMask | null;
|
|
189
|
+
/**
|
|
190
|
+
* Le visage qu'impose un etat, ou `null` quand il laisse celui de la peluche. `base` est le
|
|
191
|
+
* visage propre de la peluche (celui du personnage, `neutre` pour une forme).
|
|
192
|
+
*/
|
|
193
|
+
export declare const faceOf: (state: PlushState, base: BotExpression) => BotExpression | null;
|
|
194
|
+
export declare const THINK_X = 0.62;
|
|
195
|
+
export declare const THINK_Y = -1.3;
|
|
196
|
+
export declare const THINK_SCALE = 0.6;
|
|
197
|
+
/** emergence des points, celle de l'etat `thinking` */
|
|
198
|
+
export declare const EMERGE = 0.3;
|
|
199
|
+
/**
|
|
200
|
+
* Histoire des points, datee sur l'horloge du bot. Les fondus repartent du niveau atteint,
|
|
201
|
+
* et la pulsation n'est pas remise a zero tant que les points sont encore visibles : un
|
|
202
|
+
* aller-retour rapide ne fait sauter ni l'opacite ni les rayons.
|
|
203
|
+
*/
|
|
204
|
+
export interface DotsTrack {
|
|
205
|
+
/** origine de la pulsation */
|
|
206
|
+
phase: number;
|
|
207
|
+
/** entree (ou sortie) la plus recente, et la visibilite d'ou elle part */
|
|
208
|
+
at: number;
|
|
209
|
+
from: number;
|
|
210
|
+
on: boolean;
|
|
211
|
+
/** duree de la sortie : le morph de l'etat d'arrivee */
|
|
212
|
+
exit: number;
|
|
213
|
+
}
|
|
214
|
+
export declare const NO_DOTS: DotsTrack;
|
|
215
|
+
export declare function dotsVisibility(track: DotsTrack, t: number): number;
|
|
216
|
+
/** Entree dans `thinking` (`on`) ou sortie vers `next`, a l'instant `t`. */
|
|
217
|
+
export declare function dotsToggle(track: DotsTrack, on: boolean, t: number, next: PlushState): DotsTrack;
|
|
218
|
+
export interface PlushDot {
|
|
219
|
+
x: number;
|
|
220
|
+
y: number;
|
|
221
|
+
r: number;
|
|
222
|
+
opacity: number;
|
|
223
|
+
}
|
|
224
|
+
/** Les trois points a l'instant `t`, en unites de rayon. Vide quand ils sont invisibles. */
|
|
225
|
+
export declare function thinkingDots(track: DotsTrack, t: number): PlushDot[];
|
|
226
|
+
/** vie d'un « z », en secondes */
|
|
227
|
+
export declare const Z_LIFE = 3;
|
|
228
|
+
export interface PlushZ {
|
|
229
|
+
x: number;
|
|
230
|
+
y: number;
|
|
231
|
+
/** cote du « z », en unites de rayon */
|
|
232
|
+
size: number;
|
|
233
|
+
opacity: number;
|
|
234
|
+
}
|
|
235
|
+
/** Les « z » a l'instant `t`, en unites de rayon. Vide quand ils sont invisibles. */
|
|
236
|
+
export declare function sleepZs(track: DotsTrack, t: number): PlushZ[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PlushPad } from './catalogue.js';
|
|
2
|
+
/**
|
|
3
|
+
* Le patin sur une gelule de `w` x `h` px : des morceaux d'une gelule de feutre, jamais etiree.
|
|
4
|
+
*
|
|
5
|
+
* Le feutre (`tools/peluche/fit/feutre.py`) a un grain et une frange : etire, chaque fibre
|
|
6
|
+
* devenait une raie. Chaque patin est donc cuit en gelule, couchee (`x`) et debout (`y`) : le
|
|
7
|
+
* patin rond (la gelule ajustee sans sa partie droite) allonge d'une partie droite de
|
|
8
|
+
* `2 BARRE` petits cotes, le feutre lu sur le patin rond et prolonge dans la partie droite. Les
|
|
9
|
+
* deux bouts sont le patin rond tel quel ; la partie droite est SYMETRIQUE (et a la meme
|
|
10
|
+
* lumiere partout). Sur une gelule longue de `2 e` de plus que large, a l'echelle `u` du
|
|
11
|
+
* petit cote, chaque moitie montre son bout et `e` de partie droite :
|
|
12
|
+
* - jusqu'a `BARRE`, d'un seul morceau. Les deux moities se rejoignent au centre sur deux
|
|
13
|
+
* colonnes symetriques de l'image : la meme matiere ;
|
|
14
|
+
* - au-dela, par troncons de `BARRE` : l'image lue jusqu'a son milieu, puis au-dela de son
|
|
15
|
+
* milieu (le reflet de ce qui precede), et ainsi de suite. Jusqu'a `BARRES` troncons ; plus
|
|
16
|
+
* loin, ils s'etirent (aucun oeil du catalogue n'y va).
|
|
17
|
+
*
|
|
18
|
+
* Aucune coupe ne tombe sur le bord d'une image (le bord d'un `<image>` est antialiase en plus
|
|
19
|
+
* de la coupe : un liseré). Toutes sont paralleles, et les morceaux s'additionnent
|
|
20
|
+
* (`plus-lighter`) dans un groupe isole : leurs couvertures antialiasees se completent a 1.
|
|
21
|
+
* Tout est continu en `w`, `h`, l'image elle-meme comprise quand l'oeil passe de couche a
|
|
22
|
+
* debout : sur une gelule ronde, les deux images montrent le MEME patin rond (`matiere.py`).
|
|
23
|
+
*/
|
|
24
|
+
export interface PadPiece {
|
|
25
|
+
/** l'image : la gelule couchee (`x`) ou debout (`y`) */
|
|
26
|
+
src: 'x' | 'y';
|
|
27
|
+
/** le rectangle ou le morceau est pose, centre sur l'oeil */
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
w: number;
|
|
31
|
+
h: number;
|
|
32
|
+
/** ce qu'il montre de son image (0 a 1) : le `viewBox` de l'`<svg>` imbrique */
|
|
33
|
+
viewBox: string;
|
|
34
|
+
}
|
|
35
|
+
/** un troncon de partie droite, en petits cotes : la moitie de celle de l'image (`barre` de `matiere.py`) */
|
|
36
|
+
export declare const BARRE = 0.5;
|
|
37
|
+
/**
|
|
38
|
+
* Au-dela de ce nombre de troncons de chaque cote, ils s'etirent plutot que de se multiplier
|
|
39
|
+
* (CHOISI) : aucun oeil du catalogue ne va si loin ; le plus long (Vita, 3,8 fois plus long que
|
|
40
|
+
* large) en demande trois.
|
|
41
|
+
*/
|
|
42
|
+
export declare const BARRES = 3;
|
|
43
|
+
/** Les morceaux du patin `pad` pose sur une gelule de `w` x `h` px. */
|
|
44
|
+
export declare function padPieces(pad: PlushPad, w: number, h: number): PadPiece[];
|
|
45
|
+
/** La demi-etendue des morceaux, centres sur l'oeil : ce que couvrent les images, frange et ombre comprises. */
|
|
46
|
+
export declare function padExtent(pieces: readonly PadPiece[]): {
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** la mediane de l'interieur d'un corps gris (`GRIS_CIBLE` de `forme.py`) */
|
|
2
|
+
export declare const GRIS = 0.55;
|
|
3
|
+
/**
|
|
4
|
+
* Courbe de la teinte, ajustee (`tools/peluche/mesure/teinte.py`) sur les quantiles des
|
|
5
|
+
* corps cuits de Nexo, Malu, Yoshi, Vita et Fred, chaque forme grise teinte de l'encre du
|
|
6
|
+
* personnage : ecart moyen par canal 14,3 sur 255, contre 18,8 pour la courbe d'avant.
|
|
7
|
+
* `gamma` creuse les ombres, `sheen` blanchit les fibres au-dessus de la mediane.
|
|
8
|
+
* La mediane reste la couleur demandee : un facteur d'exposition gagnait encore un peu,
|
|
9
|
+
* mais seulement parce que le corps cuit de Malu est plus sombre que son encre, ce qui
|
|
10
|
+
* tient a sa generation et pas a la matiere (celui de Yoshi est plus clair que la sienne).
|
|
11
|
+
*/
|
|
12
|
+
export declare const TINT: {
|
|
13
|
+
gamma: number;
|
|
14
|
+
sheen: number;
|
|
15
|
+
};
|
|
16
|
+
export declare function parseHex(hex: string): [number, number, number];
|
|
17
|
+
/**
|
|
18
|
+
* La table : pour chaque gris 0..255, la couleur RGB 0..255. Pure, donc testable, et
|
|
19
|
+
* c'est elle qu'on etalonne. En lumiere lineaire : la couleur, multipliee par l'ecart de
|
|
20
|
+
* luminance a la mediane (puissance `gamma`), puis melangee vers le blanc au-dessus.
|
|
21
|
+
*/
|
|
22
|
+
export declare function tintRamp(hex: string, { gamma, sheen }?: {
|
|
23
|
+
gamma: number;
|
|
24
|
+
sheen: number;
|
|
25
|
+
}): Uint8ClampedArray;
|
|
26
|
+
/** L'URL d'objet du corps `url` teint en `hex`, calculee une fois. Navigateur seulement. */
|
|
27
|
+
export declare function tinted(url: string, hex: string): Promise<string>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const PLUSH_TRANSITIONS: readonly ["flip", "pop", "warp", "dissolve", "cut"];
|
|
2
|
+
export type PlushTransition = (typeof PLUSH_TRANSITIONS)[number];
|
|
3
|
+
export declare const DEFAULT_TRANSITION: PlushTransition;
|
|
4
|
+
export declare const popCourbe: (t: number) => number;
|
|
5
|
+
export declare const POP: number;
|
|
6
|
+
/** le rapetissement avant le pop : la moitie du morph de forme */
|
|
7
|
+
export declare const RETRAIT: number;
|
|
8
|
+
export declare const DUREE: Record<PlushTransition, number>;
|
|
9
|
+
/** Ce qu'une transition dessine a un instant donne. */
|
|
10
|
+
export interface Rendu {
|
|
11
|
+
/** quel(s) corps : l'ancien, le nouveau, ou les deux melanges */
|
|
12
|
+
corps: 'avant' | 'apres' | 'deux';
|
|
13
|
+
/** poids du nouveau corps quand il y en a deux (fondu, seuil de dissolution) */
|
|
14
|
+
melange: number;
|
|
15
|
+
/** echelle du groupe corps + yeux, autour du centre */
|
|
16
|
+
sx: number;
|
|
17
|
+
sy: number;
|
|
18
|
+
/** la forme que le moteur doit avoir : il y place les yeux */
|
|
19
|
+
bascule: boolean;
|
|
20
|
+
fini: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare const REPOS_AVANT: Rendu;
|
|
23
|
+
export declare const REPOS_APRES: Rendu;
|
|
24
|
+
/**
|
|
25
|
+
* `s` : secondes depuis le changement. Avant (s < 0) on dessine l'ancien corps ; une fois
|
|
26
|
+
* la duree passee, le nouveau, a l'echelle 1.
|
|
27
|
+
*/
|
|
28
|
+
export declare function rendu(transition: PlushTransition, s: number): Rendu;
|
|
29
|
+
/**
|
|
30
|
+
* Les rayons du contour pendant `warp`, a `s` secondes du changement : exactement ceux
|
|
31
|
+
* que le moteur donne au corps (`shapeAtTime`), pour que le feutre reste sous les yeux.
|
|
32
|
+
*/
|
|
33
|
+
export declare function rayonsWarp(avant: readonly number[], apres: readonly number[], s: number): number[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface Warp {
|
|
2
|
+
/** charge les deux corps ; la promesse se resout quand ils sont prets */
|
|
3
|
+
corps(avant: string, apres: string): Promise<void>;
|
|
4
|
+
dessine(ra: readonly number[], rb: readonly number[], rc: readonly number[], melange: number): void;
|
|
5
|
+
detruit(): void;
|
|
6
|
+
}
|
|
7
|
+
/** `null` sans WebGL 2 : la peluche retombe alors sur `cut`. */
|
|
8
|
+
export declare function creeWarp(canvas: HTMLCanvasElement): Warp | null;
|
|
9
|
+
/** le canvas couvre le viewBox du bot : `DEMI_VIEWBOX` de chaque cote du centre */
|
|
10
|
+
export declare const COTE_VIEWBOX: number;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@norbert_bodziony/bloub",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "SVG recreation of the x.ai bot avatar. One shape morphing through 14 states, measured off the reference video frame by frame.",
|
|
7
7
|
"license": "MIT",
|
|
@@ -19,12 +19,17 @@
|
|
|
19
19
|
"animation",
|
|
20
20
|
"avatar",
|
|
21
21
|
"solid-js",
|
|
22
|
-
"morphing"
|
|
22
|
+
"morphing",
|
|
23
|
+
"plush"
|
|
23
24
|
],
|
|
24
25
|
"packageManager": "bun@1.4.0",
|
|
25
26
|
"files": [
|
|
26
27
|
"dist/package/index.js",
|
|
27
28
|
"dist/package/server.js",
|
|
29
|
+
"dist/package/plush.js",
|
|
30
|
+
"dist/package/plush-server.js",
|
|
31
|
+
"dist/package/chunks",
|
|
32
|
+
"dist/package/assets",
|
|
28
33
|
"dist/package/types"
|
|
29
34
|
],
|
|
30
35
|
"types": "./dist/package/types/index.d.ts",
|
|
@@ -34,6 +39,12 @@
|
|
|
34
39
|
"browser": "./dist/package/index.js",
|
|
35
40
|
"import": "./dist/package/server.js",
|
|
36
41
|
"default": "./dist/package/server.js"
|
|
42
|
+
},
|
|
43
|
+
"./plush": {
|
|
44
|
+
"types": "./dist/package/types/plush/index.d.ts",
|
|
45
|
+
"browser": "./dist/package/plush.js",
|
|
46
|
+
"import": "./dist/package/plush-server.js",
|
|
47
|
+
"default": "./dist/package/plush-server.js"
|
|
37
48
|
}
|
|
38
49
|
},
|
|
39
50
|
"sideEffects": false,
|