pixelpeeps 1.0.1 → 1.0.2
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.d.mts +2 -17
- package/dist/index.d.ts +2 -17
- package/dist/index.js +59 -380
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59 -380
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
@@ -11,14 +11,7 @@ type FaceProps = {
|
|
11
11
|
r: number;
|
12
12
|
color: string;
|
13
13
|
eyeShape?: "circle" | "ellipse" | "line" | "wink" | "sleepy" | "surprised" | "random";
|
14
|
-
mouthShape?: "smile" | "frown" | "flat" | "zigzag" | "
|
15
|
-
glasses?: "none" | "round" | "square" | "random";
|
16
|
-
eyebrows?: boolean | "random";
|
17
|
-
blush?: boolean | "random";
|
18
|
-
freckles?: boolean | "random";
|
19
|
-
ears?: boolean | "random";
|
20
|
-
hat?: "none" | "beanie" | "cap" | "random";
|
21
|
-
outline?: boolean;
|
14
|
+
mouthShape?: "smile" | "frown" | "flat" | "zigzag" | "random";
|
22
15
|
pupilColor?: string | "auto";
|
23
16
|
eyeShine?: boolean | "random";
|
24
17
|
rand: () => number;
|
@@ -30,7 +23,6 @@ type AvatarProps = {
|
|
30
23
|
mirrored?: boolean;
|
31
24
|
bg?: [string, string] | string | "random";
|
32
25
|
headShape?: HeadShape;
|
33
|
-
square?: boolean;
|
34
26
|
alignX?: AlignX;
|
35
27
|
alignY?: AlignY;
|
36
28
|
padding?: number;
|
@@ -38,19 +30,12 @@ type AvatarProps = {
|
|
38
30
|
variant?: Variant;
|
39
31
|
eyeShape?: FaceProps["eyeShape"];
|
40
32
|
mouthShape?: FaceProps["mouthShape"];
|
41
|
-
glasses?: FaceProps["glasses"];
|
42
|
-
eyebrows?: FaceProps["eyebrows"];
|
43
|
-
blush?: FaceProps["blush"];
|
44
|
-
freckles?: FaceProps["freckles"];
|
45
|
-
ears?: FaceProps["ears"];
|
46
|
-
hat?: FaceProps["hat"];
|
47
|
-
outline?: boolean;
|
48
33
|
pupilColor?: string | "auto";
|
49
34
|
eyeShine?: boolean;
|
50
35
|
className?: string;
|
51
36
|
style?: React.CSSProperties;
|
52
37
|
title?: string;
|
53
38
|
};
|
54
|
-
declare function Avatar({ name, size,
|
39
|
+
declare function Avatar({ name, size, bg, colors }: AvatarProps): react_jsx_runtime.JSX.Element;
|
55
40
|
|
56
41
|
export { Avatar, Avatar as default };
|
package/dist/index.d.ts
CHANGED
@@ -11,14 +11,7 @@ type FaceProps = {
|
|
11
11
|
r: number;
|
12
12
|
color: string;
|
13
13
|
eyeShape?: "circle" | "ellipse" | "line" | "wink" | "sleepy" | "surprised" | "random";
|
14
|
-
mouthShape?: "smile" | "frown" | "flat" | "zigzag" | "
|
15
|
-
glasses?: "none" | "round" | "square" | "random";
|
16
|
-
eyebrows?: boolean | "random";
|
17
|
-
blush?: boolean | "random";
|
18
|
-
freckles?: boolean | "random";
|
19
|
-
ears?: boolean | "random";
|
20
|
-
hat?: "none" | "beanie" | "cap" | "random";
|
21
|
-
outline?: boolean;
|
14
|
+
mouthShape?: "smile" | "frown" | "flat" | "zigzag" | "random";
|
22
15
|
pupilColor?: string | "auto";
|
23
16
|
eyeShine?: boolean | "random";
|
24
17
|
rand: () => number;
|
@@ -30,7 +23,6 @@ type AvatarProps = {
|
|
30
23
|
mirrored?: boolean;
|
31
24
|
bg?: [string, string] | string | "random";
|
32
25
|
headShape?: HeadShape;
|
33
|
-
square?: boolean;
|
34
26
|
alignX?: AlignX;
|
35
27
|
alignY?: AlignY;
|
36
28
|
padding?: number;
|
@@ -38,19 +30,12 @@ type AvatarProps = {
|
|
38
30
|
variant?: Variant;
|
39
31
|
eyeShape?: FaceProps["eyeShape"];
|
40
32
|
mouthShape?: FaceProps["mouthShape"];
|
41
|
-
glasses?: FaceProps["glasses"];
|
42
|
-
eyebrows?: FaceProps["eyebrows"];
|
43
|
-
blush?: FaceProps["blush"];
|
44
|
-
freckles?: FaceProps["freckles"];
|
45
|
-
ears?: FaceProps["ears"];
|
46
|
-
hat?: FaceProps["hat"];
|
47
|
-
outline?: boolean;
|
48
33
|
pupilColor?: string | "auto";
|
49
34
|
eyeShine?: boolean;
|
50
35
|
className?: string;
|
51
36
|
style?: React.CSSProperties;
|
52
37
|
title?: string;
|
53
38
|
};
|
54
|
-
declare function Avatar({ name, size,
|
39
|
+
declare function Avatar({ name, size, bg, colors }: AvatarProps): react_jsx_runtime.JSX.Element;
|
55
40
|
|
56
41
|
export { Avatar, Avatar as default };
|
package/dist/index.js
CHANGED
@@ -35,7 +35,6 @@ __export(index_exports, {
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
36
36
|
|
37
37
|
// src/Avatar.tsx
|
38
|
-
var React = __toESM(require("react"));
|
39
38
|
var import_nice_color_palettes = __toESM(require("nice-color-palettes"));
|
40
39
|
var import_jsx_runtime = require("react/jsx-runtime");
|
41
40
|
function cyrb128(str) {
|
@@ -99,9 +98,6 @@ function yiq(hex) {
|
|
99
98
|
const { r, g, b } = hexToRgb(hex);
|
100
99
|
return (r * 299 + g * 587 + b * 114) / 1e3;
|
101
100
|
}
|
102
|
-
function bestFeatureColor(base) {
|
103
|
-
return yiq(base) > 150 ? "#111827" : "#ffffff";
|
104
|
-
}
|
105
101
|
var NICE_PALETTES = import_nice_color_palettes.default && Array.isArray(import_nice_color_palettes.default) ? import_nice_color_palettes.default : [["#73a9ff", "#fef3c7", "#ffd6a5", "#d4b4ff", "#a7f3d0"]];
|
106
102
|
function resolveBg(rand, bg) {
|
107
103
|
if (!bg || bg === "random") {
|
@@ -133,13 +129,6 @@ function Face({
|
|
133
129
|
color,
|
134
130
|
eyeShape: eyeShapeProp,
|
135
131
|
mouthShape: mouthShapeProp,
|
136
|
-
glasses: glassesProp,
|
137
|
-
eyebrows: eyebrowsProp,
|
138
|
-
blush: blushProp,
|
139
|
-
freckles: frecklesProp,
|
140
|
-
ears: earsProp,
|
141
|
-
hat: hatProp,
|
142
|
-
outline,
|
143
132
|
pupilColor,
|
144
133
|
eyeShine: eyeShineProp,
|
145
134
|
rand
|
@@ -149,387 +138,77 @@ function Face({
|
|
149
138
|
return prop;
|
150
139
|
};
|
151
140
|
const eyeShape = decide(eyeShapeProp ?? "random", ["circle", "ellipse", "line", "wink", "sleepy", "surprised"]);
|
152
|
-
const mouthShape = decide(mouthShapeProp ?? "random", ["smile", "frown", "flat", "zigzag"
|
153
|
-
const glasses = decide(glassesProp ?? "random", ["none", "round", "square"]);
|
154
|
-
const eyebrows = decide(eyebrowsProp ?? "random", [true, false]);
|
155
|
-
const blush = decide(blushProp ?? "random", [true, false]);
|
156
|
-
const freckles = decide(frecklesProp ?? "random", [true, false]);
|
157
|
-
const ears = decide(earsProp ?? "random", [true, false]);
|
158
|
-
const hat = decide(hatProp ?? "random", ["none", "beanie", "cap"]);
|
141
|
+
const mouthShape = decide(mouthShapeProp ?? "random", ["smile", "frown", "flat", "zigzag"]);
|
159
142
|
const eyeShine = decide(eyeShineProp ?? "random", [true, false]);
|
160
|
-
const eyeOffsetX = r *
|
161
|
-
const eyeOffsetY = r *
|
162
|
-
const eyeR = Math.max(2,
|
163
|
-
const pupilR =
|
164
|
-
const mouthWidth = r *
|
165
|
-
const mouthLift = r *
|
143
|
+
const eyeOffsetX = r * 0.36;
|
144
|
+
const eyeOffsetY = r * 0.22;
|
145
|
+
const eyeR = Math.max(2, r * 0.08);
|
146
|
+
const pupilR = eyeR * 0.5;
|
147
|
+
const mouthWidth = r * 0.7;
|
148
|
+
const mouthLift = r * 0.2;
|
166
149
|
const mouthStroke = Math.max(1, Math.round(r * 0.06));
|
167
|
-
|
168
|
-
if (pupilColor && pupilColor !== "auto") finalPupilColor = pupilColor;
|
169
|
-
else finalPupilColor = yiq(color) > 150 ? "#111827" : "#ffffff";
|
150
|
+
const finalPupilColor = pupilColor && pupilColor !== "auto" ? pupilColor : yiq(color) > 150 ? "#111827" : "#ffffff";
|
170
151
|
const x0 = cx - mouthWidth / 2;
|
171
152
|
const x1 = cx + mouthWidth / 2;
|
172
153
|
const my = cy + mouthLift;
|
173
|
-
const
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
return `M ${x0} ${my} Q ${cxQ} ${cyQ} ${x1} ${my}`;
|
186
|
-
})();
|
187
|
-
const mouthPathZigzag = (() => {
|
188
|
-
const segs = 6;
|
189
|
-
const step = mouthWidth / (segs - 1);
|
190
|
-
let d = `M ${x0} ${my}`;
|
191
|
-
for (let i = 1; i < segs; i++) {
|
192
|
-
const px = x0 + step * i;
|
193
|
-
const py = my + (i % 2 === 0 ? -r * 0.08 : r * 0.08);
|
194
|
-
d += ` L ${px} ${py}`;
|
195
|
-
}
|
196
|
-
return d;
|
197
|
-
})();
|
198
|
-
const mouthOpen = (() => {
|
199
|
-
const w = mouthWidth;
|
200
|
-
const h = r * 0.26;
|
201
|
-
const rx = w / 2;
|
202
|
-
const ry = h / 2;
|
203
|
-
return { rx, ry, cy: my + ry * 0.25 };
|
204
|
-
})();
|
205
|
-
const frecklesCoords = [
|
206
|
-
{ x: cx - eyeOffsetX * 1.1, y: cy + eyeOffsetY * 0.4 },
|
207
|
-
{ x: cx - eyeOffsetX * 0.6, y: cy + eyeOffsetY * 0.6 },
|
208
|
-
{ x: cx + eyeOffsetX * 1.1, y: cy + eyeOffsetY * 0.4 },
|
209
|
-
{ x: cx + eyeOffsetX * 0.6, y: cy + eyeOffsetY * 0.6 }
|
210
|
-
];
|
211
|
-
const eyes = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
212
|
-
(() => {
|
213
|
-
const ex = cx - eyeOffsetX;
|
214
|
-
const ey = cy - eyeOffsetY;
|
215
|
-
switch (eyeShape) {
|
216
|
-
case "ellipse":
|
217
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.1, ry: eyeR * 0.7, fill: color }, "le");
|
218
|
-
case "line":
|
219
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: ex - eyeR, y1: ey, x2: ex + eyeR, y2: ey, stroke: color, strokeWidth: Math.max(1, Math.round(eyeR * 0.4)), strokeLinecap: "round" }, "ll");
|
220
|
-
case "wink":
|
221
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: ex - eyeR, y1: ey, x2: ex + eyeR, y2: ey, stroke: color, strokeWidth: Math.max(1, Math.round(eyeR * 0.4)), strokeLinecap: "round" }, "lw");
|
222
|
-
case "sleepy":
|
223
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.05, ry: eyeR * 0.45, fill: color }, "ls") });
|
224
|
-
case "surprised":
|
225
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR * 1.1, fill: color }, "lsp");
|
226
|
-
default:
|
227
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR, fill: color }, "lc");
|
228
|
-
}
|
229
|
-
})(),
|
230
|
-
(() => {
|
231
|
-
const ex = cx - eyeOffsetX;
|
232
|
-
const ey = cy - eyeOffsetY;
|
233
|
-
if (eyeShape === "line" || eyeShape === "wink") return null;
|
234
|
-
if (eyeShape === "sleepy") {
|
235
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: Math.max(1, pupilR * 0.6), fill: finalPupilColor }, "lps");
|
236
|
-
}
|
237
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
238
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: pupilR, fill: finalPupilColor }, "lp"),
|
239
|
-
eyeShine ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex - pupilR * 0.4, cy: ey - pupilR * 0.6, r: Math.max(0.6, pupilR * 0.35), fill: "#ffffff", opacity: 0.8 }, "lshine") : null
|
240
|
-
] });
|
241
|
-
})(),
|
242
|
-
(() => {
|
243
|
-
const ex = cx + eyeOffsetX;
|
244
|
-
const ey = cy - eyeOffsetY;
|
245
|
-
switch (eyeShape) {
|
246
|
-
case "ellipse":
|
247
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.1, ry: eyeR * 0.7, fill: color }, "re");
|
248
|
-
case "line":
|
249
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: ex - eyeR, y1: ey, x2: ex + eyeR, y2: ey, stroke: color, strokeWidth: Math.max(1, Math.round(eyeR * 0.4)), strokeLinecap: "round" }, "rl");
|
250
|
-
case "wink":
|
251
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR, fill: color }, "rw");
|
252
|
-
case "sleepy":
|
253
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.05, ry: eyeR * 0.45, fill: color }, "rs");
|
254
|
-
case "surprised":
|
255
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR * 1.1, fill: color }, "rsp");
|
256
|
-
default:
|
257
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR, fill: color }, "rc");
|
154
|
+
const mouthPaths = {
|
155
|
+
smile: `M ${x0} ${my} Q ${cx} ${my - r * 0.2} ${x1} ${my}`,
|
156
|
+
frown: `M ${x0} ${my} Q ${cx} ${my + r * 0.2} ${x1} ${my}`,
|
157
|
+
flat: `M ${x0} ${my} L ${x1} ${my}`,
|
158
|
+
zigzag: (() => {
|
159
|
+
const segs = 6;
|
160
|
+
const step = mouthWidth / (segs - 1);
|
161
|
+
let d = `M ${x0} ${my}`;
|
162
|
+
for (let i = 1; i < segs; i++) {
|
163
|
+
const px = x0 + step * i;
|
164
|
+
const py = my + (i % 2 === 0 ? -r * 0.08 : r * 0.08);
|
165
|
+
d += ` L ${px} ${py}`;
|
258
166
|
}
|
259
|
-
|
260
|
-
(() => {
|
261
|
-
const ex = cx + eyeOffsetX;
|
262
|
-
const ey = cy - eyeOffsetY;
|
263
|
-
if (eyeShape === "line" || eyeShape === "wink" && rand() > 0.2) {
|
264
|
-
if (eyeShape === "line") return null;
|
265
|
-
}
|
266
|
-
if (eyeShape === "sleepy") {
|
267
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: Math.max(1, pupilR * 0.6), fill: finalPupilColor }, "rps");
|
268
|
-
}
|
269
|
-
if (eyeShape === "wink") {
|
270
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
271
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: pupilR, fill: finalPupilColor }, "rp"),
|
272
|
-
eyeShine ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex - pupilR * 0.4, cy: ey - pupilR * 0.6, r: Math.max(0.6, pupilR * 0.35), fill: "#ffffff", opacity: 0.8 }, "rshine") : null
|
273
|
-
] });
|
274
|
-
}
|
275
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
276
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: pupilR, fill: finalPupilColor }, "rp"),
|
277
|
-
eyeShine ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex - pupilR * 0.4, cy: ey - pupilR * 0.6, r: Math.max(0.6, pupilR * 0.35), fill: "#ffffff", opacity: 0.8 }, "rshine2") : null
|
278
|
-
] });
|
167
|
+
return d;
|
279
168
|
})()
|
280
|
-
|
281
|
-
const
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
294
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx - gx, cy: gy, r: frameW / 2, fill: "transparent", stroke: finalPupilColor, strokeWidth: Math.max(1, Math.round(eyeR * 0.35)) }),
|
295
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx + gx, cy: gy, r: frameW / 2, fill: "transparent", stroke: finalPupilColor, strokeWidth: Math.max(1, Math.round(eyeR * 0.35)) }),
|
296
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: cx - bridgeW / 2, y1: gy, x2: cx + bridgeW / 2, y2: gy, stroke: finalPupilColor, strokeWidth: Math.max(1, Math.round(eyeR * 0.25)), strokeLinecap: "round" })
|
297
|
-
] });
|
298
|
-
}
|
299
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
300
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: cx - gx - frameW / 2, y: gy - frameH / 2, width: frameW, height: frameH, rx: Math.max(1, eyeR * 0.25), fill: "transparent", stroke: finalPupilColor, strokeWidth: Math.max(1, Math.round(eyeR * 0.35)) }),
|
301
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: cx + gx - frameW / 2, y: gy - frameH / 2, width: frameW, height: frameH, rx: Math.max(1, eyeR * 0.25), fill: "transparent", stroke: finalPupilColor, strokeWidth: Math.max(1, Math.round(eyeR * 0.35)) }),
|
302
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: cx - bridgeW / 2, y1: gy, x2: cx + bridgeW / 2, y2: gy, stroke: finalPupilColor, strokeWidth: Math.max(1, Math.round(eyeR * 0.25)), strokeLinecap: "round" })
|
303
|
-
] });
|
304
|
-
})();
|
305
|
-
const mouth = (() => {
|
306
|
-
switch (mouthShape) {
|
307
|
-
case "frown":
|
308
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: mouthPathFrown, stroke: color, strokeWidth: mouthStroke, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" });
|
309
|
-
case "flat":
|
310
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: x0, y1: my, x2: x1, y2: my, stroke: color, strokeWidth: Math.max(1, Math.round(mouthStroke * 0.9)), strokeLinecap: "round" });
|
311
|
-
case "zigzag":
|
312
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: mouthPathZigzag, stroke: color, strokeWidth: Math.max(1, Math.round(mouthStroke * 0.9)), fill: "none", strokeLinecap: "round", strokeLinejoin: "round" });
|
313
|
-
case "open":
|
314
|
-
const open = mouthOpen;
|
315
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
316
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx, cy: open.cy, rx: open.rx, ry: open.ry, fill: shade(color, -0.6) }),
|
317
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx, cy: open.cy, rx: open.rx, ry: open.ry, fill: "none", stroke: color, strokeWidth: Math.max(1, Math.round(mouthStroke * 0.5)) }),
|
318
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: cx - open.rx * 0.6, y: open.cy, width: open.rx * 1.2, height: Math.max(1, open.ry * 0.25), rx: 1, fill: shade(color, -0.2) })
|
319
|
-
] });
|
169
|
+
};
|
170
|
+
const drawEye = (ex, ey, key) => {
|
171
|
+
switch (eyeShape) {
|
172
|
+
case "ellipse":
|
173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.1, ry: eyeR * 0.7, fill: color }, key);
|
174
|
+
case "line":
|
175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: ex - eyeR, y1: ey, x2: ex + eyeR, y2: ey, stroke: color, strokeWidth: eyeR * 0.5, strokeLinecap: "round" }, key);
|
176
|
+
case "wink":
|
177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: ex - eyeR, y1: ey, x2: ex + eyeR, y2: ey, stroke: color, strokeWidth: eyeR * 0.5, strokeLinecap: "round" }, key);
|
178
|
+
case "sleepy":
|
179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.05, ry: eyeR * 0.45, fill: color }, key);
|
180
|
+
case "surprised":
|
181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR * 1.1, fill: color }, key);
|
320
182
|
default:
|
321
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR, fill: color }, key);
|
322
184
|
}
|
323
|
-
}
|
324
|
-
const
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx
|
185
|
+
};
|
186
|
+
const leftEye = drawEye(cx - eyeOffsetX, cy - eyeOffsetY, "le");
|
187
|
+
const rightEye = drawEye(cx + eyeOffsetX, cy - eyeOffsetY, "re");
|
188
|
+
const pupils = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
189
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx - eyeOffsetX, cy: cy - eyeOffsetY, r: pupilR, fill: finalPupilColor }),
|
190
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx + eyeOffsetX, cy: cy - eyeOffsetY, r: pupilR, fill: finalPupilColor })
|
191
|
+
] });
|
192
|
+
const shine = eyeShine ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
193
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx - eyeOffsetX - pupilR * 0.4, cy: cy - eyeOffsetY - pupilR * 0.6, r: pupilR * 0.3, fill: "#fff", opacity: 0.8 }),
|
194
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx + eyeOffsetX - pupilR * 0.4, cy: cy - eyeOffsetY - pupilR * 0.6, r: pupilR * 0.3, fill: "#fff", opacity: 0.8 })
|
332
195
|
] }) : null;
|
333
|
-
const
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: `M ${cx - r * 0.6} ${cy - r * 0.3} Q ${cx} ${cy - r * 0.05} ${cx + r * 0.6} ${cy - r * 0.3} L ${cx + r * 0.6} ${cy - r * 0.15} Q ${cx} ${cy - r * 0.02} ${cx - r * 0.6} ${cy - r * 0.15} Z`, fill: shade(color, -0.08) })
|
341
|
-
] });
|
342
|
-
})();
|
343
|
-
const outlineStroke = outline ? { stroke: shade(color, -0.24), strokeWidth: Math.max(1, Math.round(r * 0.06)) } : {};
|
344
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [
|
345
|
-
earsEl,
|
346
|
-
hatEl,
|
347
|
-
blushEl,
|
348
|
-
frecklesEl,
|
349
|
-
brows,
|
350
|
-
eyes,
|
351
|
-
glassesEl,
|
352
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { children: mouth })
|
196
|
+
const mouth = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: mouthPaths[mouthShape], stroke: color, strokeWidth: mouthStroke, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" });
|
197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
198
|
+
leftEye,
|
199
|
+
rightEye,
|
200
|
+
pupils,
|
201
|
+
shine,
|
202
|
+
mouth
|
353
203
|
] });
|
354
204
|
}
|
355
|
-
function
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
shape,
|
363
|
-
rand
|
364
|
-
}) {
|
365
|
-
const x0 = cx - r, y0 = cy - r, x1 = cx + r, y1 = cy + r;
|
366
|
-
const left = rand() > 0.5;
|
367
|
-
const tlbr = rand() > 0.5;
|
368
|
-
const horiz = rand() > 0.5;
|
369
|
-
const cornerTL = rand() > 0.5;
|
370
|
-
switch (variant) {
|
371
|
-
case "plain":
|
372
|
-
return null;
|
373
|
-
case "split":
|
374
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: left ? x0 : cx, y: y0, width: r, height: 2 * r, fill: a1 });
|
375
|
-
case "diagonal":
|
376
|
-
return tlbr ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: `${x0},${y0} ${x1},${y0} ${x1},${y1}`, fill: a1 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: `${x0},${y0} ${x0},${y1} ${x1},${y1}`, fill: a1 });
|
377
|
-
case "cap":
|
378
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: `M ${x0} ${y0 + r * 0.25} L ${x1} ${y0} L ${x1} ${y0 + r * 0.6} Q ${cx} ${y0 + r * 0.85} ${x0} ${y0 + r * 0.6} Z`, fill: a1 });
|
379
|
-
case "swoop":
|
380
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: `M ${x0} ${cy - r * 0.55} Q ${cx} ${cy - r * 1.1} ${x1} ${cy - r * 0.35} L ${x1} ${y1} Q ${cx} ${cy + r * 0.95} ${x0} ${y1} Z`, fill: a1 });
|
381
|
-
case "crescent":
|
382
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
383
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: left ? cx - r * 0.55 : cx + r * 0.55, cy, r: r * 0.95, fill: a2 }),
|
384
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: left ? cx - r * 0.52 : cx + r * 0.52, cy, r: r * 0.75, fill: "transparent", stroke: shade(a2, -0.25), strokeWidth: r * 0.08 })
|
385
|
-
] });
|
386
|
-
case "band":
|
387
|
-
return horiz ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: x0, y: cy - r * 0.35, width: 2 * r, height: r * 0.5, fill: a1 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: cx - r * 0.35, y: y0, width: r * 0.5, height: 2 * r, fill: a1 });
|
388
|
-
case "corner":
|
389
|
-
return cornerTL ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: `${x0},${y0} ${x0 + r * 0.9},${y0} ${x0},${y0 + r * 0.9}`, fill: a1 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: `${x1},${y0} ${x1 - r * 0.9},${y0} ${x1},${y0 + r * 0.9}`, fill: a1 });
|
390
|
-
case "ring":
|
391
|
-
return shape === "circle" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx, cy, r: r * 0.86, fill: "none", stroke: a1, strokeWidth: r * 0.18 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: cx - r * 0.86, y: cy - r * 0.86, width: 2 * r * 0.86, height: 2 * r * 0.86, rx: r * 0.18, fill: "none", stroke: a1, strokeWidth: r * 0.18 });
|
392
|
-
case "arc":
|
393
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: `M ${x0} ${cy - r * 0.2} A ${r} ${r} 0 0 1 ${x1} ${cy - r * 0.2} L ${x1} ${cy + r * 0.15} A ${r} ${r} 0 0 0 ${x0} ${cy + r * 0.15} Z`, fill: a1 });
|
394
|
-
case "wave":
|
395
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: `M ${x0} ${cy - r * 0.3} C ${cx - r * 0.6} ${cy - r * 0.8}, ${cx - r * 0.2} ${cy + r * 0.1}, ${cx} ${cy} S ${cx + r * 0.6} ${cy + r * 0.8}, ${x1} ${cy + r * 0.3} L ${x1} ${y1} L ${x0} ${y1} Z`, fill: a1 });
|
396
|
-
case "half": {
|
397
|
-
const diag = rand() > 0.4;
|
398
|
-
if (diag) {
|
399
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: `${x0},${y0} ${x1},${y0} ${x1},${cy + (left ? r * 0.1 : -r * 0.1)}`, fill: a1 });
|
400
|
-
} else {
|
401
|
-
const offset = left ? -r * 0.18 : r * 0.18;
|
402
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx + offset, cy, r: r * 0.95, fill: a1 });
|
403
|
-
}
|
404
|
-
}
|
405
|
-
default:
|
406
|
-
return null;
|
407
|
-
}
|
408
|
-
}
|
409
|
-
function Avatar({
|
410
|
-
name,
|
411
|
-
size = 128,
|
412
|
-
pixelSize = 12,
|
413
|
-
mirrored = true,
|
414
|
-
bg,
|
415
|
-
colors,
|
416
|
-
headShape,
|
417
|
-
square,
|
418
|
-
alignX = "center",
|
419
|
-
alignY = "center",
|
420
|
-
padding,
|
421
|
-
variant = "auto",
|
422
|
-
className,
|
423
|
-
style,
|
424
|
-
title,
|
425
|
-
// new feature props (pass these to control face features)
|
426
|
-
eyeShape,
|
427
|
-
mouthShape,
|
428
|
-
glasses,
|
429
|
-
eyebrows,
|
430
|
-
blush,
|
431
|
-
freckles,
|
432
|
-
ears,
|
433
|
-
hat,
|
434
|
-
outline = false,
|
435
|
-
pupilColor,
|
436
|
-
eyeShine
|
437
|
-
}) {
|
438
|
-
const shape = headShape ?? (square ? "square" : "circle");
|
439
|
-
const rand = React.useMemo(() => rngFromSeed(String(name)), [name]);
|
440
|
-
const [bg1, bg2] = React.useMemo(() => resolveBg(rand, bg), [rand, bg]);
|
441
|
-
const [base, a1, a2] = React.useMemo(() => resolveCharColors(rand, colors), [rand, colors]);
|
442
|
-
const faceColor = bestFeatureColor(base);
|
443
|
-
const grid = Math.max(6, Math.floor(size / pixelSize));
|
444
|
-
const tile = Math.ceil(size / grid);
|
445
|
-
const autoPad = Math.max(4, Math.round(size * (0.06 + rand() * 0.02)));
|
446
|
-
const pad = padding ?? autoPad;
|
447
|
-
const baseR = Math.floor(size * (0.36 + rand() * 0.04));
|
448
|
-
const maxR = Math.floor(size / 2 - pad);
|
449
|
-
const r = Math.max(8, Math.min(baseR, maxR));
|
450
|
-
let cx = size / 2;
|
451
|
-
let cy = size / 2;
|
452
|
-
if (alignX === "left") cx = r + pad;
|
453
|
-
if (alignX === "right") cx = size - (r + pad);
|
454
|
-
if (alignY === "top") cy = r + pad;
|
455
|
-
if (alignY === "bottom") cy = size - (r + pad);
|
456
|
-
const cells = [];
|
457
|
-
const cols = mirrored ? Math.ceil(grid / 2) : grid;
|
458
|
-
for (let y = 0; y < grid; y++) {
|
459
|
-
for (let x = 0; x < cols; x++) {
|
460
|
-
const use = rand() > 0.5;
|
461
|
-
const fill = use ? bg1 : bg2;
|
462
|
-
const px = x * tile;
|
463
|
-
const py = y * tile;
|
464
|
-
cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: px, y: py, width: tile, height: tile, fill }, `L${x},${y}`));
|
465
|
-
if (mirrored) {
|
466
|
-
const mx = grid - x - 1;
|
467
|
-
const mpx = mx * tile;
|
468
|
-
cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: mpx, y: py, width: tile, height: tile, fill }, `R${mx},${y}`));
|
469
|
-
}
|
470
|
-
}
|
471
|
-
}
|
472
|
-
const variants = ["split", "swoop", "diagonal", "cap", "crescent", "band", "corner", "ring", "arc", "wave", "plain", "half"];
|
473
|
-
const chosenVariant = variant === "auto" ? pick(rand, variants) : variant;
|
474
|
-
const clipId = React.useMemo(() => {
|
475
|
-
const [a, b, c, d] = cyrb128(`pp-shape-${name}-${shape}-${r}`);
|
476
|
-
return `pps-${a.toString(16)}${b.toString(16)}${c.toString(16)}${d.toString(16)}`;
|
477
|
-
}, [name, shape, r]);
|
478
|
-
const headStrokeProps = outline ? { stroke: shade(base, -0.25), strokeWidth: Math.max(1, Math.round(r * 0.06)) } : {};
|
479
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
480
|
-
"svg",
|
481
|
-
{
|
482
|
-
width: size,
|
483
|
-
height: size,
|
484
|
-
viewBox: `0 0 ${size} ${size}`,
|
485
|
-
xmlns: "http://www.w3.org/2000/svg",
|
486
|
-
role: "img",
|
487
|
-
"aria-label": title ?? `Avatar ${name}`,
|
488
|
-
className,
|
489
|
-
style: { display: "inline-block", borderRadius: 12, ...style },
|
490
|
-
children: [
|
491
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: size, height: size, fill: bg1 }),
|
492
|
-
cells,
|
493
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("clipPath", { id: clipId, children: shape === "square" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: cx - r, y: cy - r, width: 2 * r, height: 2 * r, rx: Math.max(4, r * 0.12) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx, cy, r }) }) }),
|
494
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { clipPath: `url(#${clipId})`, children: [
|
495
|
-
shape === "square" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
496
|
-
"rect",
|
497
|
-
{
|
498
|
-
x: cx - r,
|
499
|
-
y: cy - r,
|
500
|
-
width: 2 * r,
|
501
|
-
height: 2 * r,
|
502
|
-
rx: Math.max(4, r * 0.12),
|
503
|
-
fill: base,
|
504
|
-
...outline ? { stroke: shade(base, -0.25), strokeWidth: Math.max(1, Math.round(r * 0.06)) } : {}
|
505
|
-
}
|
506
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx, cy, r, fill: base, ...outline ? { stroke: shade(base, -0.25), strokeWidth: Math.max(1, Math.round(r * 0.06)) } : {} }),
|
507
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Overlays, { cx, cy, r, a1, a2, variant: chosenVariant, shape, rand })
|
508
|
-
] }),
|
509
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
510
|
-
Face,
|
511
|
-
{
|
512
|
-
cx,
|
513
|
-
cy,
|
514
|
-
r,
|
515
|
-
color: faceColor,
|
516
|
-
eyeShape,
|
517
|
-
mouthShape,
|
518
|
-
glasses,
|
519
|
-
eyebrows,
|
520
|
-
blush,
|
521
|
-
freckles,
|
522
|
-
ears,
|
523
|
-
hat,
|
524
|
-
outline,
|
525
|
-
pupilColor: pupilColor ?? "auto",
|
526
|
-
eyeShine,
|
527
|
-
rand
|
528
|
-
}
|
529
|
-
)
|
530
|
-
]
|
531
|
-
}
|
532
|
-
);
|
205
|
+
function Avatar({ name, size = 120, bg = "random", colors = "random" }) {
|
206
|
+
const rand = rngFromSeed(name);
|
207
|
+
const [bg1, bg2] = resolveBg(rand, bg);
|
208
|
+
const [base] = resolveCharColors(rand, colors);
|
209
|
+
const cx = size / 2;
|
210
|
+
const cy = size / 2;
|
211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, style: { borderRadius: "50%", background: `linear-gradient(135deg, ${bg1}, ${bg2})` }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Face, { cx, cy, r: size / 3, color: base, rand }) });
|
533
212
|
}
|
534
213
|
// Annotate the CommonJS export names for ESM import in node:
|
535
214
|
0 && (module.exports = {
|