mochikao 0.1.3 → 0.2.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.fr.md +22 -0
- package/README.md +22 -0
- package/dist/bin/mochikao.js +1 -1
- package/dist/src/family.d.ts +13 -0
- package/dist/src/family.js +33 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/params.d.ts +3 -1
- package/dist/src/params.js +18 -1
- package/package.json +1 -1
package/README.fr.md
CHANGED
|
@@ -132,6 +132,28 @@ mochikao({ name: 'alex', family: produce, shape: 'lemon' });
|
|
|
132
132
|
|
|
133
133
|
Choisir une famille ne change que la forme : yeux, bouche, accessoire et réglages restent ceux du nom. Là où les options arrivent en texte (attributs HTML, URL, CLI), on déclare les familles disponibles une fois : `defineMochikao({ families: [animals] })` puis `<mochikao-avatar family="animals">`, ou `parseParams(nom, params, [animals, produce])`. L'API et la CLI fournies acceptent les deux.
|
|
134
134
|
|
|
135
|
+
**Mélanger des familles.** `mix()` combine plusieurs familles : le nom choisit alors parmi toutes leurs formes, chacune avec la même chance.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { mochikao, blobs, mix } from 'mochikao';
|
|
139
|
+
|
|
140
|
+
mochikao({ name: 'alex', family: mix(blobs, animals) }); // blobs + animaux
|
|
141
|
+
mochikao({ name: 'alex', family: mix(animals, produce) }); // animaux + fruits & légumes
|
|
142
|
+
mochikao({ name: 'alex', family: mix(blobs, animals, produce) }); // tout
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
| Mode | `family=` | Formes |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| Blobs (défaut) | `blob` | 10 |
|
|
148
|
+
| Animaux | `animals` | 6 |
|
|
149
|
+
| Fruits & légumes | `produce` | 6 |
|
|
150
|
+
| Blobs + animaux | `animals+blob` | 16 |
|
|
151
|
+
| Blobs + fruits & légumes | `blob+produce` | 16 |
|
|
152
|
+
| Animaux + fruits & légumes | `animals+produce` | 12 |
|
|
153
|
+
| Tout | `all` (ou `animals+blob+produce`) | 22 |
|
|
154
|
+
|
|
155
|
+
Dans les URL, attributs HTML et la CLI, on joint les noms avec `+` (`?family=blob+animals`) ; `all` prend toutes les familles déclarées plus les blobs. L'ordre n'a pas d'importance, et un mélange des mêmes familles donne toujours le même avatar pour un nom.
|
|
156
|
+
|
|
135
157
|
Une famille, c'est un objet `ShapeFamily` (`name`, `shapes`, `silhouette`, et en option `decorate` et `hue`) : `src/families/` montre comment en écrire une.
|
|
136
158
|
|
|
137
159
|
### Transition entre expressions
|
package/README.md
CHANGED
|
@@ -132,6 +132,28 @@ mochikao({ name: 'alex', family: produce, shape: 'lemon' });
|
|
|
132
132
|
|
|
133
133
|
Picking a family only changes the shape: eyes, mouth, accessory and settings still come from the name. Where options arrive as text (HTML attributes, URLs, CLI), declare the available families once: `defineMochikao({ families: [animals] })` then `<mochikao-avatar family="animals">`, or `parseParams(name, params, [animals, produce])`. The bundled API and CLI accept both.
|
|
134
134
|
|
|
135
|
+
**Mixing families.** `mix()` combines several families: the name then picks among all their shapes, each shape equally likely.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { mochikao, blobs, mix } from 'mochikao';
|
|
139
|
+
|
|
140
|
+
mochikao({ name: 'alex', family: mix(blobs, animals) }); // blobs + animals
|
|
141
|
+
mochikao({ name: 'alex', family: mix(animals, produce) }); // animals + fruits & veggies
|
|
142
|
+
mochikao({ name: 'alex', family: mix(blobs, animals, produce) }); // everything
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
| Mode | `family=` | Shapes |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| Blobs (default) | `blob` | 10 |
|
|
148
|
+
| Animals | `animals` | 6 |
|
|
149
|
+
| Fruits & veggies | `produce` | 6 |
|
|
150
|
+
| Blobs + animals | `animals+blob` | 16 |
|
|
151
|
+
| Blobs + fruits & veggies | `blob+produce` | 16 |
|
|
152
|
+
| Animals + fruits & veggies | `animals+produce` | 12 |
|
|
153
|
+
| Everything | `all` (or `animals+blob+produce`) | 22 |
|
|
154
|
+
|
|
155
|
+
In URLs, HTML attributes and the CLI, join names with `+` (`?family=blob+animals`); `all` takes every family you declared plus the blobs. The order doesn't matter, and a mix with the same families always gives the same avatar for a given name.
|
|
156
|
+
|
|
135
157
|
A family is a `ShapeFamily` object (`name`, `shapes`, `silhouette`, and optionally `decorate` and `hue`): `src/families/` shows how to write one.
|
|
136
158
|
|
|
137
159
|
### Transitions between expressions
|
package/dist/bin/mochikao.js
CHANGED
|
@@ -14,7 +14,7 @@ const USAGE = `usage : mochikao <nom> [options]
|
|
|
14
14
|
--tone <0-1> luminosité
|
|
15
15
|
--expression <e> idle | happy | sad | mad | love | shy | sick | thinking
|
|
16
16
|
--animate <a> none | hover | always
|
|
17
|
-
--family <f> blob | animals | produce
|
|
17
|
+
--family <f> blob | animals | produce | all, ou un mélange : blob+animals, animals+produce...
|
|
18
18
|
--color <c> pastel | pale | mid | deep | bright | ink
|
|
19
19
|
--shape --eyes --mouth --extra épingle un trait
|
|
20
20
|
--info affiche les traits au lieu du SVG`;
|
package/dist/src/family.d.ts
CHANGED
|
@@ -49,3 +49,16 @@ export interface ShapeFamily<S extends string = string> {
|
|
|
49
49
|
hue?(shape: S): number | undefined;
|
|
50
50
|
}
|
|
51
51
|
export declare function isFamily(value: unknown): value is ShapeFamily;
|
|
52
|
+
/**
|
|
53
|
+
* Combine plusieurs familles en une : le nom choisit parmi toutes leurs formes.
|
|
54
|
+
*
|
|
55
|
+
* mix(blobs, animals) // blobs et animaux
|
|
56
|
+
* mix(blobs, animals, produce) // tout
|
|
57
|
+
*
|
|
58
|
+
* Chaque forme a la même chance d'être tirée, donc une famille pèse selon son
|
|
59
|
+
* nombre de formes. L'ordre des arguments ne compte pas : les familles sont
|
|
60
|
+
* triées par nom (le résultat s'appelle `animals+blob`), ce qui fixe la liste
|
|
61
|
+
* des formes et donc quel avatar sort pour quel nom. Si deux familles ont une
|
|
62
|
+
* forme du même nom, la première (dans l'ordre trié) l'emporte.
|
|
63
|
+
*/
|
|
64
|
+
export declare function mix(...families: ShapeFamily[]): ShapeFamily;
|
package/dist/src/family.js
CHANGED
|
@@ -3,3 +3,36 @@ export function isFamily(value) {
|
|
|
3
3
|
return typeof f === 'object' && f !== null && typeof f.name === 'string' &&
|
|
4
4
|
Array.isArray(f.shapes) && f.shapes.length > 0 && typeof f.silhouette === 'function';
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Combine plusieurs familles en une : le nom choisit parmi toutes leurs formes.
|
|
8
|
+
*
|
|
9
|
+
* mix(blobs, animals) // blobs et animaux
|
|
10
|
+
* mix(blobs, animals, produce) // tout
|
|
11
|
+
*
|
|
12
|
+
* Chaque forme a la même chance d'être tirée, donc une famille pèse selon son
|
|
13
|
+
* nombre de formes. L'ordre des arguments ne compte pas : les familles sont
|
|
14
|
+
* triées par nom (le résultat s'appelle `animals+blob`), ce qui fixe la liste
|
|
15
|
+
* des formes et donc quel avatar sort pour quel nom. Si deux familles ont une
|
|
16
|
+
* forme du même nom, la première (dans l'ordre trié) l'emporte.
|
|
17
|
+
*/
|
|
18
|
+
export function mix(...families) {
|
|
19
|
+
const unique = [...new Map(families.filter(isFamily).map((f) => [f.name, f])).values()]
|
|
20
|
+
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
21
|
+
if (unique.length === 0)
|
|
22
|
+
throw new TypeError('mix() attend au moins une famille');
|
|
23
|
+
if (unique.length === 1)
|
|
24
|
+
return unique[0];
|
|
25
|
+
const owner = new Map();
|
|
26
|
+
for (const f of unique)
|
|
27
|
+
for (const s of f.shapes)
|
|
28
|
+
if (!owner.has(s))
|
|
29
|
+
owner.set(s, f);
|
|
30
|
+
const of = (shape) => owner.get(shape) ?? unique[0];
|
|
31
|
+
return {
|
|
32
|
+
name: unique.map((f) => f.name).join('+'),
|
|
33
|
+
shapes: [...owner.keys()],
|
|
34
|
+
silhouette: (shape, traits) => of(shape).silhouette(shape, traits),
|
|
35
|
+
decorate: (shape, body, colors, eyeY) => of(shape).decorate?.(shape, body, colors, eyeY) ?? {},
|
|
36
|
+
hue: (shape) => of(shape).hue?.(shape),
|
|
37
|
+
};
|
|
38
|
+
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type ShapeFamily } from './family.ts';
|
|
|
3
3
|
import { type Animation, type Background, type ColorPreset, type Expression, type ExtraName, type EyesName, type MouthName, type Traits } from './traits.ts';
|
|
4
4
|
export * from './traits.ts';
|
|
5
5
|
export { blobs } from './shape.ts';
|
|
6
|
-
export { isFamily } from './family.ts';
|
|
6
|
+
export { isFamily, mix } from './family.ts';
|
|
7
7
|
export type { Decoration, ShapeDef, ShapeFamily } from './family.ts';
|
|
8
8
|
export { palette, contrast, hslToRgb } from './color.ts';
|
|
9
9
|
export type { Palette } from './color.ts';
|
package/dist/src/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { blobs, buildBody, superellipsePath } from "./shape.js";
|
|
|
6
6
|
import { ANIMATIONS, BACKGROUNDS, COLORS, EXPRESSIONS, EXTRAS, EYES, MOUTHS, deriveTraits, pick, positionOf, } from "./traits.js";
|
|
7
7
|
export * from "./traits.js";
|
|
8
8
|
export { blobs } from "./shape.js";
|
|
9
|
-
export { isFamily } from "./family.js";
|
|
9
|
+
export { isFamily, mix } from "./family.js";
|
|
10
10
|
export { palette, contrast, hslToRgb } from "./color.js";
|
|
11
11
|
/** Ce que le nom donne, sans dessiner. */
|
|
12
12
|
export function resolve(options) {
|
package/dist/src/params.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MochikaoOptions } from './index.ts';
|
|
2
|
-
import type
|
|
2
|
+
import { type ShapeFamily } from './family.ts';
|
|
3
3
|
type Source = {
|
|
4
4
|
get(key: string): string | null | undefined;
|
|
5
5
|
};
|
|
@@ -8,6 +8,8 @@ type Source = {
|
|
|
8
8
|
* Les valeurs invalides sont ignorées plutôt que de faire échouer le rendu.
|
|
9
9
|
* `families` liste les familles qu'on accepte de désigner par leur nom
|
|
10
10
|
* (`?family=animals`) ; sans elles, seuls les blobs sont disponibles.
|
|
11
|
+
* Plusieurs familles se combinent avec « + » (`?family=blob+animals`), et
|
|
12
|
+
* `family=all` prend toutes celles qu'on fournit.
|
|
11
13
|
*/
|
|
12
14
|
export declare function parseParams(name: string, src: Source, families?: readonly ShapeFamily[]): MochikaoOptions;
|
|
13
15
|
/**
|
package/dist/src/params.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mix } from "./family.js";
|
|
1
2
|
import { blobs } from "./shape.js";
|
|
2
3
|
import { ANIMATIONS, BACKGROUNDS, COLORS, CONTINUOUS_AXES, EXPRESSIONS, EXTRAS, EYES, MOUTHS } from "./traits.js";
|
|
3
4
|
const oneOf = (list, v) => v != null && list.includes(v) ? v : undefined;
|
|
@@ -7,11 +8,27 @@ const num = (v, min, max) => {
|
|
|
7
8
|
const n = Number(v);
|
|
8
9
|
return Number.isFinite(n) ? Math.min(max, Math.max(min, n)) : undefined;
|
|
9
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* `animals`, `blob`, ou un mode combiné : `blob+animals`, `animals+produce`...
|
|
13
|
+
* `all` prend les blobs et toutes les familles fournies. Les noms inconnus
|
|
14
|
+
* sont ignorés ; sans aucun nom valide, on n'a pas de famille.
|
|
15
|
+
*/
|
|
16
|
+
function findFamily(value, families) {
|
|
17
|
+
if (!value)
|
|
18
|
+
return undefined;
|
|
19
|
+
const known = [blobs, ...families];
|
|
20
|
+
if (value === 'all')
|
|
21
|
+
return mix(...known);
|
|
22
|
+
const found = value.split(/[+ ]/).map((n) => known.find((f) => f.name === n)).filter((f) => f !== undefined);
|
|
23
|
+
return found.length ? mix(...found) : undefined;
|
|
24
|
+
}
|
|
10
25
|
/**
|
|
11
26
|
* Options depuis des paramètres texte (query string, attributs HTML, flags CLI).
|
|
12
27
|
* Les valeurs invalides sont ignorées plutôt que de faire échouer le rendu.
|
|
13
28
|
* `families` liste les familles qu'on accepte de désigner par leur nom
|
|
14
29
|
* (`?family=animals`) ; sans elles, seuls les blobs sont disponibles.
|
|
30
|
+
* Plusieurs familles se combinent avec « + » (`?family=blob+animals`), et
|
|
31
|
+
* `family=all` prend toutes celles qu'on fournit.
|
|
15
32
|
*/
|
|
16
33
|
export function parseParams(name, src, families = []) {
|
|
17
34
|
const options = { name };
|
|
@@ -26,7 +43,7 @@ export function parseParams(name, src, families = []) {
|
|
|
26
43
|
set('expression', oneOf(EXPRESSIONS, src.get('expression')));
|
|
27
44
|
set('animate', oneOf(ANIMATIONS, src.get('animate')));
|
|
28
45
|
// `family` désigne une famille par son nom, parmi celles qu'on nous a confiées.
|
|
29
|
-
const family =
|
|
46
|
+
const family = findFamily(src.get('family'), families);
|
|
30
47
|
set('family', family);
|
|
31
48
|
set('shape', oneOf((family ?? blobs).shapes, src.get('shape')));
|
|
32
49
|
set('eyes', oneOf(EYES, src.get('eyes')));
|
package/package.json
CHANGED