mochikao 0.1.2 → 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 +26 -0
- package/README.md +26 -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 +2 -2
package/README.fr.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) · **Français**
|
|
4
4
|
|
|
5
|
+
[Site](https://mochikao.alexvolkihar.ovh) · [npm](https://www.npmjs.com/package/mochikao) · [GitHub](https://github.com/Alexvolkihar/mochikao)
|
|
6
|
+
|
|
5
7
|
Un visage pour chaque nom. `mochikao` transforme n'importe quelle chaîne (pseudo, e-mail, id) en un petit personnage SVG. Le même nom donne toujours le même mochikao.
|
|
6
8
|
|
|
7
9
|

|
|
@@ -130,6 +132,28 @@ mochikao({ name: 'alex', family: produce, shape: 'lemon' });
|
|
|
130
132
|
|
|
131
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.
|
|
132
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
|
+
|
|
133
157
|
Une famille, c'est un objet `ShapeFamily` (`name`, `shapes`, `silhouette`, et en option `decorate` et `hue`) : `src/families/` montre comment en écrire une.
|
|
134
158
|
|
|
135
159
|
### Transition entre expressions
|
|
@@ -157,6 +181,8 @@ Mêmes attributs que les options ; `gaze` fait suivre le pointeur aux yeux.
|
|
|
157
181
|
GET /api/<nom>.svg?size=&bg=&hue=&tone=&color=&expression=&animate=&family=&shape=&eyes=&mouth=&extra=
|
|
158
182
|
```
|
|
159
183
|
|
|
184
|
+
Instance hébergée : `https://mochikao.alexvolkihar.ovh/api/<nom>.svg`. À essayer dans l'[éditeur](https://mochikao.alexvolkihar.ovh/editor.html).
|
|
185
|
+
|
|
160
186
|
Réponse `image/svg+xml` avec `Cache-Control: immutable` (même entrée → même sortie). Les paramètres invalides sont ignorés. Le handler (`api/handler.ts`) est une simple fonction `(req, res)` de `node:http`, à brancher où tu veux.
|
|
161
187
|
|
|
162
188
|
### CLI
|
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
**English** · [Français](README.fr.md)
|
|
4
4
|
|
|
5
|
+
[Website](https://mochikao.alexvolkihar.ovh) · [npm](https://www.npmjs.com/package/mochikao) · [GitHub](https://github.com/Alexvolkihar/mochikao)
|
|
6
|
+
|
|
5
7
|
A face for every name. `mochikao` turns any string (username, email, ID) into a little SVG character. The same name always gives the same mochikao.
|
|
6
8
|
|
|
7
9
|

|
|
@@ -130,6 +132,28 @@ mochikao({ name: 'alex', family: produce, shape: 'lemon' });
|
|
|
130
132
|
|
|
131
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.
|
|
132
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
|
+
|
|
133
157
|
A family is a `ShapeFamily` object (`name`, `shapes`, `silhouette`, and optionally `decorate` and `hue`): `src/families/` shows how to write one.
|
|
134
158
|
|
|
135
159
|
### Transitions between expressions
|
|
@@ -157,6 +181,8 @@ Same attributes as the options; `gaze` makes the eyes follow the pointer.
|
|
|
157
181
|
GET /api/<name>.svg?size=&bg=&hue=&tone=&color=&expression=&animate=&family=&shape=&eyes=&mouth=&extra=
|
|
158
182
|
```
|
|
159
183
|
|
|
184
|
+
Hosted instance: `https://mochikao.alexvolkihar.ovh/api/<name>.svg`. Try it in the [editor](https://mochikao.alexvolkihar.ovh/editor.html).
|
|
185
|
+
|
|
160
186
|
Responds with `image/svg+xml` and `Cache-Control: immutable` (same input → same output). Invalid parameters are ignored. The handler (`api/handler.ts`) is a plain `node:http` `(req, res)` function you can mount anywhere.
|
|
161
187
|
|
|
162
188
|
### CLI
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mochikao",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Deterministic avatars: any string becomes a cute, unique SVG character. Zero dependencies, React / Vue / Svelte / Solid / web component.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"avatar",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"type": "git",
|
|
23
23
|
"url": "git+https://github.com/Alexvolkihar/mochikao.git"
|
|
24
24
|
},
|
|
25
|
-
"homepage": "https://
|
|
25
|
+
"homepage": "https://mochikao.alexvolkihar.ovh",
|
|
26
26
|
"bugs": {
|
|
27
27
|
"url": "https://github.com/Alexvolkihar/mochikao/issues"
|
|
28
28
|
},
|