@usenavii/core 0.1.0 → 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/dist/index.cjs +65 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +132 -5
- package/dist/index.d.ts +132 -5
- package/dist/index.js +63 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as AvatarOptions, c as AvatarSpec } from './types-BlMtdWZf.cjs';
|
|
2
|
-
export {
|
|
1
|
+
import { b as AvatarOptions, c as AvatarSpec, d as BodyShapeId, E as EyeStyleId, M as MouthStyleId, a as AntennaStyleId, A as AccessoryId, B as BackgroundId, T as TopperId } from './types-BlMtdWZf.cjs';
|
|
2
|
+
export { P as Palette } from './types-BlMtdWZf.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Seed → stable PRNG stream.
|
|
@@ -72,9 +72,136 @@ interface GroupOptions extends AvatarOptions {
|
|
|
72
72
|
declare function renderGroup(seeds: string[], options?: GroupOptions): string;
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
75
|
+
* Seed helper — composes the most stable identifier from a user-shaped
|
|
76
|
+
* object into a single string for `createAvatar`.
|
|
77
|
+
*
|
|
78
|
+
* Priority: `id` → `email` → `name + createdAt` → `name` alone.
|
|
79
|
+
*
|
|
80
|
+
* The whole point: stop devs accidentally passing a display name. Names
|
|
81
|
+
* collide; ids and emails don't. When only a name is available, composing
|
|
82
|
+
* it with `createdAt` makes the result globally unique while remaining
|
|
83
|
+
* stable across renders (assuming `createdAt` is set once at signup).
|
|
84
|
+
*/
|
|
85
|
+
interface SeedFields {
|
|
86
|
+
/** Stable primary key (database id, UUID, OAuth sub). Best choice. */
|
|
87
|
+
id?: string | number | null | undefined;
|
|
88
|
+
/** Email. Stable + unique. Good fallback when id isn't available client-side. */
|
|
89
|
+
email?: string | null | undefined;
|
|
90
|
+
/** Display name. Collision-prone — only acceptable composed with `createdAt`. */
|
|
91
|
+
name?: string | null | undefined;
|
|
92
|
+
/** Account creation time. Combined with `name` to bake uniqueness in at signup. */
|
|
93
|
+
createdAt?: string | number | Date | null | undefined;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Compose a stable seed string from the most unique field available.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* const s = seed({ id: user.id, email: user.email, name: user.name });
|
|
101
|
+
* createAvatar(s);
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @example If only a name exists, pass `createdAt` to avoid collisions:
|
|
105
|
+
* ```ts
|
|
106
|
+
* seed({ name: 'Alice', createdAt: user.createdAt });
|
|
107
|
+
* // → "Alice|1700000000000"
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @throws if no usable field is provided.
|
|
111
|
+
*/
|
|
112
|
+
declare function seed(fields: SeedFields): string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Direct construction of an avatar from explicit part choices — no seed.
|
|
116
|
+
*
|
|
117
|
+
* Use when you need a SPECIFIC mascot rather than a deterministic one
|
|
118
|
+
* derived from a user id. Common uses: brand mascots, logo marks, fixed
|
|
119
|
+
* tests, designer curation, gallery hero shots.
|
|
120
|
+
*
|
|
121
|
+
* Any field left unspecified falls back to its first variant (mostly the
|
|
122
|
+
* neutral / "none" option). Continuous params default to 0 / 1 (no tweak).
|
|
123
|
+
*/
|
|
124
|
+
interface BuildSpec {
|
|
125
|
+
palette?: string;
|
|
126
|
+
body?: BodyShapeId;
|
|
127
|
+
eyes?: EyeStyleId;
|
|
128
|
+
mouth?: MouthStyleId;
|
|
129
|
+
antenna?: AntennaStyleId;
|
|
130
|
+
accessory?: AccessoryId;
|
|
131
|
+
background?: BackgroundId;
|
|
132
|
+
topper?: TopperId;
|
|
133
|
+
hueShift?: number;
|
|
134
|
+
bodyScale?: number;
|
|
135
|
+
eyeGapShift?: number;
|
|
136
|
+
mouthCurveScale?: number;
|
|
137
|
+
antennaTilt?: number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Build an SVG avatar from explicit part choices.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const svg = build({
|
|
145
|
+
* body: 'tall',
|
|
146
|
+
* eyes: 'star',
|
|
147
|
+
* mouth: 'grin',
|
|
148
|
+
* palette: 'violet',
|
|
149
|
+
* topper: 'crown',
|
|
150
|
+
* }, { size: 192 });
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* Pass `AvatarOptions` (size, title, animated, tileBg) as the second arg —
|
|
154
|
+
* same shape as `createAvatar`'s options.
|
|
155
|
+
*/
|
|
156
|
+
declare function build(spec?: BuildSpec, options?: AvatarOptions): string;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Render a deterministic mascot avatar from a seed.
|
|
160
|
+
*
|
|
161
|
+
* Same seed in → same SVG out, byte-identical, forever.
|
|
162
|
+
*
|
|
163
|
+
* @param seed Stable unique identifier per user. Recommended order: `user.id`
|
|
164
|
+
* → UUID → `user.email`. **Avoid display names** — two users called "Alice"
|
|
165
|
+
* would get the same avatar. **Never pass `Date.now()`** or any value that
|
|
166
|
+
* changes between renders; the avatar would change every refresh.
|
|
167
|
+
* See {@link seed} for a helper that picks the right field automatically.
|
|
168
|
+
*
|
|
169
|
+
* @param options.size Output size in px. Default 96. Range 16–1024.
|
|
170
|
+
* @param options.paletteId Force a color family (e.g. `'mint'`).
|
|
171
|
+
* @param options.background `'none' | 'solid' | 'ring'` or `{ color }`.
|
|
172
|
+
* @param options.tileBg Opaque disc behind the avatar. Color or `'auto'`.
|
|
173
|
+
* @param options.title Accessible label (sets `<title>` + `aria-label`).
|
|
174
|
+
* @param options.animated Emit idle motion (float, blink, sway, twinkle).
|
|
175
|
+
*
|
|
176
|
+
* @returns Self-contained `<svg>` string. Safe to embed via `<img src="data:image/svg+xml;...">`
|
|
177
|
+
* or to insert into the DOM directly.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* const svg = createAvatar(user.id, { size: 96, animated: true });
|
|
182
|
+
* ```
|
|
77
183
|
*/
|
|
78
184
|
declare function createAvatar(seed: string, options?: AvatarOptions): string;
|
|
185
|
+
/**
|
|
186
|
+
* Convenience namespace — bundles every public function under one import.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* import { Navii } from '@usenavii/core';
|
|
191
|
+
*
|
|
192
|
+
* Navii.create(user.id);
|
|
193
|
+
* Navii.seed({ id: user.id, email: user.email });
|
|
194
|
+
* Navii.build({ body: 'tall', eyes: 'star', palette: 'violet' });
|
|
195
|
+
* Navii.group([user1.id, user2.id, user3.id]);
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
declare const Navii: {
|
|
199
|
+
readonly create: typeof createAvatar;
|
|
200
|
+
readonly render: typeof renderAvatar;
|
|
201
|
+
readonly select: typeof selectAvatar;
|
|
202
|
+
readonly group: typeof renderGroup;
|
|
203
|
+
readonly seed: typeof seed;
|
|
204
|
+
readonly build: typeof build;
|
|
205
|
+
};
|
|
79
206
|
|
|
80
|
-
export { AvatarOptions, AvatarSpec, type GroupOptions, createAvatar, createRng, cyrb53, renderAvatar, renderAvatarInner, renderGroup, selectAvatar };
|
|
207
|
+
export { AccessoryId, AntennaStyleId, AvatarOptions, AvatarSpec, BackgroundId, BodyShapeId, type BuildSpec, EyeStyleId, type GroupOptions, MouthStyleId, Navii, type SeedFields, TopperId, build, createAvatar, createRng, cyrb53, renderAvatar, renderAvatarInner, renderGroup, seed, selectAvatar };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as AvatarOptions, c as AvatarSpec } from './types-BlMtdWZf.js';
|
|
2
|
-
export {
|
|
1
|
+
import { b as AvatarOptions, c as AvatarSpec, d as BodyShapeId, E as EyeStyleId, M as MouthStyleId, a as AntennaStyleId, A as AccessoryId, B as BackgroundId, T as TopperId } from './types-BlMtdWZf.js';
|
|
2
|
+
export { P as Palette } from './types-BlMtdWZf.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Seed → stable PRNG stream.
|
|
@@ -72,9 +72,136 @@ interface GroupOptions extends AvatarOptions {
|
|
|
72
72
|
declare function renderGroup(seeds: string[], options?: GroupOptions): string;
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
75
|
+
* Seed helper — composes the most stable identifier from a user-shaped
|
|
76
|
+
* object into a single string for `createAvatar`.
|
|
77
|
+
*
|
|
78
|
+
* Priority: `id` → `email` → `name + createdAt` → `name` alone.
|
|
79
|
+
*
|
|
80
|
+
* The whole point: stop devs accidentally passing a display name. Names
|
|
81
|
+
* collide; ids and emails don't. When only a name is available, composing
|
|
82
|
+
* it with `createdAt` makes the result globally unique while remaining
|
|
83
|
+
* stable across renders (assuming `createdAt` is set once at signup).
|
|
84
|
+
*/
|
|
85
|
+
interface SeedFields {
|
|
86
|
+
/** Stable primary key (database id, UUID, OAuth sub). Best choice. */
|
|
87
|
+
id?: string | number | null | undefined;
|
|
88
|
+
/** Email. Stable + unique. Good fallback when id isn't available client-side. */
|
|
89
|
+
email?: string | null | undefined;
|
|
90
|
+
/** Display name. Collision-prone — only acceptable composed with `createdAt`. */
|
|
91
|
+
name?: string | null | undefined;
|
|
92
|
+
/** Account creation time. Combined with `name` to bake uniqueness in at signup. */
|
|
93
|
+
createdAt?: string | number | Date | null | undefined;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Compose a stable seed string from the most unique field available.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* const s = seed({ id: user.id, email: user.email, name: user.name });
|
|
101
|
+
* createAvatar(s);
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @example If only a name exists, pass `createdAt` to avoid collisions:
|
|
105
|
+
* ```ts
|
|
106
|
+
* seed({ name: 'Alice', createdAt: user.createdAt });
|
|
107
|
+
* // → "Alice|1700000000000"
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @throws if no usable field is provided.
|
|
111
|
+
*/
|
|
112
|
+
declare function seed(fields: SeedFields): string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Direct construction of an avatar from explicit part choices — no seed.
|
|
116
|
+
*
|
|
117
|
+
* Use when you need a SPECIFIC mascot rather than a deterministic one
|
|
118
|
+
* derived from a user id. Common uses: brand mascots, logo marks, fixed
|
|
119
|
+
* tests, designer curation, gallery hero shots.
|
|
120
|
+
*
|
|
121
|
+
* Any field left unspecified falls back to its first variant (mostly the
|
|
122
|
+
* neutral / "none" option). Continuous params default to 0 / 1 (no tweak).
|
|
123
|
+
*/
|
|
124
|
+
interface BuildSpec {
|
|
125
|
+
palette?: string;
|
|
126
|
+
body?: BodyShapeId;
|
|
127
|
+
eyes?: EyeStyleId;
|
|
128
|
+
mouth?: MouthStyleId;
|
|
129
|
+
antenna?: AntennaStyleId;
|
|
130
|
+
accessory?: AccessoryId;
|
|
131
|
+
background?: BackgroundId;
|
|
132
|
+
topper?: TopperId;
|
|
133
|
+
hueShift?: number;
|
|
134
|
+
bodyScale?: number;
|
|
135
|
+
eyeGapShift?: number;
|
|
136
|
+
mouthCurveScale?: number;
|
|
137
|
+
antennaTilt?: number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Build an SVG avatar from explicit part choices.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const svg = build({
|
|
145
|
+
* body: 'tall',
|
|
146
|
+
* eyes: 'star',
|
|
147
|
+
* mouth: 'grin',
|
|
148
|
+
* palette: 'violet',
|
|
149
|
+
* topper: 'crown',
|
|
150
|
+
* }, { size: 192 });
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* Pass `AvatarOptions` (size, title, animated, tileBg) as the second arg —
|
|
154
|
+
* same shape as `createAvatar`'s options.
|
|
155
|
+
*/
|
|
156
|
+
declare function build(spec?: BuildSpec, options?: AvatarOptions): string;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Render a deterministic mascot avatar from a seed.
|
|
160
|
+
*
|
|
161
|
+
* Same seed in → same SVG out, byte-identical, forever.
|
|
162
|
+
*
|
|
163
|
+
* @param seed Stable unique identifier per user. Recommended order: `user.id`
|
|
164
|
+
* → UUID → `user.email`. **Avoid display names** — two users called "Alice"
|
|
165
|
+
* would get the same avatar. **Never pass `Date.now()`** or any value that
|
|
166
|
+
* changes between renders; the avatar would change every refresh.
|
|
167
|
+
* See {@link seed} for a helper that picks the right field automatically.
|
|
168
|
+
*
|
|
169
|
+
* @param options.size Output size in px. Default 96. Range 16–1024.
|
|
170
|
+
* @param options.paletteId Force a color family (e.g. `'mint'`).
|
|
171
|
+
* @param options.background `'none' | 'solid' | 'ring'` or `{ color }`.
|
|
172
|
+
* @param options.tileBg Opaque disc behind the avatar. Color or `'auto'`.
|
|
173
|
+
* @param options.title Accessible label (sets `<title>` + `aria-label`).
|
|
174
|
+
* @param options.animated Emit idle motion (float, blink, sway, twinkle).
|
|
175
|
+
*
|
|
176
|
+
* @returns Self-contained `<svg>` string. Safe to embed via `<img src="data:image/svg+xml;...">`
|
|
177
|
+
* or to insert into the DOM directly.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* const svg = createAvatar(user.id, { size: 96, animated: true });
|
|
182
|
+
* ```
|
|
77
183
|
*/
|
|
78
184
|
declare function createAvatar(seed: string, options?: AvatarOptions): string;
|
|
185
|
+
/**
|
|
186
|
+
* Convenience namespace — bundles every public function under one import.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* import { Navii } from '@usenavii/core';
|
|
191
|
+
*
|
|
192
|
+
* Navii.create(user.id);
|
|
193
|
+
* Navii.seed({ id: user.id, email: user.email });
|
|
194
|
+
* Navii.build({ body: 'tall', eyes: 'star', palette: 'violet' });
|
|
195
|
+
* Navii.group([user1.id, user2.id, user3.id]);
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
declare const Navii: {
|
|
199
|
+
readonly create: typeof createAvatar;
|
|
200
|
+
readonly render: typeof renderAvatar;
|
|
201
|
+
readonly select: typeof selectAvatar;
|
|
202
|
+
readonly group: typeof renderGroup;
|
|
203
|
+
readonly seed: typeof seed;
|
|
204
|
+
readonly build: typeof build;
|
|
205
|
+
};
|
|
79
206
|
|
|
80
|
-
export { AvatarOptions, AvatarSpec, type GroupOptions, createAvatar, createRng, cyrb53, renderAvatar, renderAvatarInner, renderGroup, selectAvatar };
|
|
207
|
+
export { AccessoryId, AntennaStyleId, AvatarOptions, AvatarSpec, BackgroundId, BodyShapeId, type BuildSpec, EyeStyleId, type GroupOptions, MouthStyleId, Navii, type SeedFields, TopperId, build, createAvatar, createRng, cyrb53, renderAvatar, renderAvatarInner, renderGroup, seed, selectAvatar };
|
package/dist/index.js
CHANGED
|
@@ -13,9 +13,9 @@ function cyrb53(input, salt = 0) {
|
|
|
13
13
|
h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
14
14
|
return [h1 >>> 0, h2 >>> 0];
|
|
15
15
|
}
|
|
16
|
-
function createRng(
|
|
17
|
-
const [a, b] = cyrb53(
|
|
18
|
-
const [c, d] = cyrb53(
|
|
16
|
+
function createRng(seed2) {
|
|
17
|
+
const [a, b] = cyrb53(seed2, 0);
|
|
18
|
+
const [c, d] = cyrb53(seed2, 1);
|
|
19
19
|
let s0 = a >>> 0;
|
|
20
20
|
let s1 = b >>> 0;
|
|
21
21
|
let s2 = c >>> 0;
|
|
@@ -621,8 +621,8 @@ var TOPPER_IDS = [
|
|
|
621
621
|
];
|
|
622
622
|
|
|
623
623
|
// src/select.ts
|
|
624
|
-
function selectAvatar(
|
|
625
|
-
const rng = createRng(
|
|
624
|
+
function selectAvatar(seed2, options = {}) {
|
|
625
|
+
const rng = createRng(seed2);
|
|
626
626
|
const paletteOverride = options.paletteId ? PALETTE_BY_ID[options.paletteId] : void 0;
|
|
627
627
|
const palette = paletteOverride ?? rng.pick(PALETTES);
|
|
628
628
|
const body = rng.pick(BODY_IDS);
|
|
@@ -646,7 +646,7 @@ function selectAvatar(seed, options = {}) {
|
|
|
646
646
|
const mouthCurveScale = Number(rng.range(0.85, 1.15).toFixed(3));
|
|
647
647
|
const antennaTilt = Math.round(rng.range(-8, 8));
|
|
648
648
|
return {
|
|
649
|
-
seed,
|
|
649
|
+
seed: seed2,
|
|
650
650
|
palette,
|
|
651
651
|
body,
|
|
652
652
|
eyes,
|
|
@@ -775,9 +775,9 @@ function wrap(cls, inner) {
|
|
|
775
775
|
if (!inner) return inner;
|
|
776
776
|
return `<g class="${cls}">${inner}</g>`;
|
|
777
777
|
}
|
|
778
|
-
function stableId(
|
|
778
|
+
function stableId(seed2) {
|
|
779
779
|
let h = 5381;
|
|
780
|
-
for (let i = 0; i <
|
|
780
|
+
for (let i = 0; i < seed2.length; i++) h = (h << 5) + h + seed2.charCodeAt(i) | 0;
|
|
781
781
|
return (h >>> 0).toString(36);
|
|
782
782
|
}
|
|
783
783
|
function escapeXml(s) {
|
|
@@ -801,9 +801,9 @@ function renderGroup(seeds, options = {}) {
|
|
|
801
801
|
const tileCount = visibleSeeds.length + (overflow > 0 ? 1 : 0);
|
|
802
802
|
const step = size * (1 - overlap);
|
|
803
803
|
const totalWidth = tileCount > 0 ? step * (tileCount - 1) + size : 0;
|
|
804
|
-
const tiles = visibleSeeds.map((
|
|
804
|
+
const tiles = visibleSeeds.map((seed2, i) => {
|
|
805
805
|
const x = i * step;
|
|
806
|
-
const spec = selectAvatar(
|
|
806
|
+
const spec = selectAvatar(seed2, options);
|
|
807
807
|
const bgCircle = tileBg !== "transparent" ? `<circle cx="50" cy="50" r="50" fill="${tileBg}" />` : "";
|
|
808
808
|
return `<svg x="${x}" y="0" width="${size}" height="${size}" viewBox="0 0 100 100" overflow="visible">
|
|
809
809
|
<defs><clipPath id="navii-clip"><circle cx="50" cy="50" r="50" /></clipPath></defs>
|
|
@@ -825,14 +825,63 @@ function clamp(n, lo, hi) {
|
|
|
825
825
|
return Math.max(lo, Math.min(hi, n));
|
|
826
826
|
}
|
|
827
827
|
|
|
828
|
+
// src/seed.ts
|
|
829
|
+
function seed(fields) {
|
|
830
|
+
if (fields.id !== null && fields.id !== void 0 && String(fields.id).length > 0) {
|
|
831
|
+
return String(fields.id);
|
|
832
|
+
}
|
|
833
|
+
if (fields.email && fields.email.length > 0) {
|
|
834
|
+
return fields.email;
|
|
835
|
+
}
|
|
836
|
+
if (fields.name && fields.name.length > 0) {
|
|
837
|
+
if (fields.createdAt !== null && fields.createdAt !== void 0) {
|
|
838
|
+
const ts = fields.createdAt instanceof Date ? fields.createdAt.getTime() : typeof fields.createdAt === "number" ? fields.createdAt : Date.parse(fields.createdAt);
|
|
839
|
+
if (Number.isFinite(ts)) return `${fields.name}|${ts}`;
|
|
840
|
+
return `${fields.name}|${fields.createdAt}`;
|
|
841
|
+
}
|
|
842
|
+
return fields.name;
|
|
843
|
+
}
|
|
844
|
+
throw new Error("navii: seed() requires at least one of { id, email, name }");
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// src/build.ts
|
|
848
|
+
function build(spec = {}, options = {}) {
|
|
849
|
+
const palette = spec.palette ? PALETTE_BY_ID[spec.palette] ?? PALETTES[0] : PALETTES[0];
|
|
850
|
+
const resolved = {
|
|
851
|
+
seed: "__build__",
|
|
852
|
+
palette,
|
|
853
|
+
body: spec.body ?? "orb",
|
|
854
|
+
eyes: spec.eyes ?? "round",
|
|
855
|
+
mouth: spec.mouth ?? "smile",
|
|
856
|
+
antenna: spec.antenna ?? "none",
|
|
857
|
+
accessory: spec.accessory ?? "none",
|
|
858
|
+
background: spec.background ?? "none",
|
|
859
|
+
topper: spec.topper ?? "none",
|
|
860
|
+
hueShift: spec.hueShift ?? 0,
|
|
861
|
+
bodyScale: spec.bodyScale ?? 1,
|
|
862
|
+
eyeGapShift: spec.eyeGapShift ?? 0,
|
|
863
|
+
mouthCurveScale: spec.mouthCurveScale ?? 1,
|
|
864
|
+
antennaTilt: spec.antennaTilt ?? 0
|
|
865
|
+
};
|
|
866
|
+
return renderAvatar(resolved, options);
|
|
867
|
+
}
|
|
868
|
+
|
|
828
869
|
// src/index.ts
|
|
829
|
-
function createAvatar(
|
|
830
|
-
if (typeof
|
|
870
|
+
function createAvatar(seed2, options = {}) {
|
|
871
|
+
if (typeof seed2 !== "string" || seed2.length === 0) {
|
|
831
872
|
throw new Error("navii: seed must be a non-empty string");
|
|
832
873
|
}
|
|
833
|
-
return renderAvatar(selectAvatar(
|
|
874
|
+
return renderAvatar(selectAvatar(seed2, options), options);
|
|
834
875
|
}
|
|
876
|
+
var Navii = {
|
|
877
|
+
create: createAvatar,
|
|
878
|
+
render: renderAvatar,
|
|
879
|
+
select: selectAvatar,
|
|
880
|
+
group: renderGroup,
|
|
881
|
+
seed,
|
|
882
|
+
build
|
|
883
|
+
};
|
|
835
884
|
|
|
836
|
-
export { createAvatar, createRng, cyrb53, renderAvatar, renderAvatarInner, renderGroup, selectAvatar };
|
|
885
|
+
export { Navii, build, createAvatar, createRng, cyrb53, renderAvatar, renderAvatarInner, renderGroup, seed, selectAvatar };
|
|
837
886
|
//# sourceMappingURL=index.js.map
|
|
838
887
|
//# sourceMappingURL=index.js.map
|