pixelpeeps 1.0.0 → 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 +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +80 -155
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -155
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.d.mts
CHANGED
@@ -5,6 +5,17 @@ type HeadShape = "circle" | "square";
|
|
5
5
|
type Variant = "auto" | "plain" | "split" | "swoop" | "diagonal" | "cap" | "crescent" | "band" | "corner" | "ring" | "arc" | "wave" | "half";
|
6
6
|
type AlignX = "left" | "center" | "right";
|
7
7
|
type AlignY = "top" | "center" | "bottom";
|
8
|
+
type FaceProps = {
|
9
|
+
cx: number;
|
10
|
+
cy: number;
|
11
|
+
r: number;
|
12
|
+
color: string;
|
13
|
+
eyeShape?: "circle" | "ellipse" | "line" | "wink" | "sleepy" | "surprised" | "random";
|
14
|
+
mouthShape?: "smile" | "frown" | "flat" | "zigzag" | "random";
|
15
|
+
pupilColor?: string | "auto";
|
16
|
+
eyeShine?: boolean | "random";
|
17
|
+
rand: () => number;
|
18
|
+
};
|
8
19
|
type AvatarProps = {
|
9
20
|
name: string;
|
10
21
|
size?: number;
|
@@ -12,16 +23,19 @@ type AvatarProps = {
|
|
12
23
|
mirrored?: boolean;
|
13
24
|
bg?: [string, string] | string | "random";
|
14
25
|
headShape?: HeadShape;
|
15
|
-
square?: boolean;
|
16
26
|
alignX?: AlignX;
|
17
27
|
alignY?: AlignY;
|
18
28
|
padding?: number;
|
19
29
|
colors?: string | [string, string] | [string, string, string] | "random";
|
20
30
|
variant?: Variant;
|
31
|
+
eyeShape?: FaceProps["eyeShape"];
|
32
|
+
mouthShape?: FaceProps["mouthShape"];
|
33
|
+
pupilColor?: string | "auto";
|
34
|
+
eyeShine?: boolean;
|
21
35
|
className?: string;
|
22
36
|
style?: React.CSSProperties;
|
23
37
|
title?: string;
|
24
38
|
};
|
25
|
-
declare function Avatar({ name, size,
|
39
|
+
declare function Avatar({ name, size, bg, colors }: AvatarProps): react_jsx_runtime.JSX.Element;
|
26
40
|
|
27
41
|
export { Avatar, Avatar as default };
|
package/dist/index.d.ts
CHANGED
@@ -5,6 +5,17 @@ type HeadShape = "circle" | "square";
|
|
5
5
|
type Variant = "auto" | "plain" | "split" | "swoop" | "diagonal" | "cap" | "crescent" | "band" | "corner" | "ring" | "arc" | "wave" | "half";
|
6
6
|
type AlignX = "left" | "center" | "right";
|
7
7
|
type AlignY = "top" | "center" | "bottom";
|
8
|
+
type FaceProps = {
|
9
|
+
cx: number;
|
10
|
+
cy: number;
|
11
|
+
r: number;
|
12
|
+
color: string;
|
13
|
+
eyeShape?: "circle" | "ellipse" | "line" | "wink" | "sleepy" | "surprised" | "random";
|
14
|
+
mouthShape?: "smile" | "frown" | "flat" | "zigzag" | "random";
|
15
|
+
pupilColor?: string | "auto";
|
16
|
+
eyeShine?: boolean | "random";
|
17
|
+
rand: () => number;
|
18
|
+
};
|
8
19
|
type AvatarProps = {
|
9
20
|
name: string;
|
10
21
|
size?: number;
|
@@ -12,16 +23,19 @@ type AvatarProps = {
|
|
12
23
|
mirrored?: boolean;
|
13
24
|
bg?: [string, string] | string | "random";
|
14
25
|
headShape?: HeadShape;
|
15
|
-
square?: boolean;
|
16
26
|
alignX?: AlignX;
|
17
27
|
alignY?: AlignY;
|
18
28
|
padding?: number;
|
19
29
|
colors?: string | [string, string] | [string, string, string] | "random";
|
20
30
|
variant?: Variant;
|
31
|
+
eyeShape?: FaceProps["eyeShape"];
|
32
|
+
mouthShape?: FaceProps["mouthShape"];
|
33
|
+
pupilColor?: string | "auto";
|
34
|
+
eyeShine?: boolean;
|
21
35
|
className?: string;
|
22
36
|
style?: React.CSSProperties;
|
23
37
|
title?: string;
|
24
38
|
};
|
25
|
-
declare function Avatar({ name, size,
|
39
|
+
declare function Avatar({ name, size, bg, colors }: AvatarProps): react_jsx_runtime.JSX.Element;
|
26
40
|
|
27
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,13 +98,7 @@ function yiq(hex) {
|
|
99
98
|
const { r, g, b } = hexToRgb(hex);
|
100
99
|
return (r * 299 + g * 587 + b * 114) / 1e3;
|
101
100
|
}
|
102
|
-
|
103
|
-
return yiq(base) > 150 ? "#111827" : "#ffffff";
|
104
|
-
}
|
105
|
-
var NICE_PALETTES = import_nice_color_palettes.default && Array.isArray(import_nice_color_palettes.default) ? import_nice_color_palettes.default : [
|
106
|
-
// fallback single palette
|
107
|
-
["#73a9ff", "#fef3c7", "#ffd6a5", "#d4b4ff", "#a7f3d0"]
|
108
|
-
];
|
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"]];
|
109
102
|
function resolveBg(rand, bg) {
|
110
103
|
if (!bg || bg === "random") {
|
111
104
|
return pick(rand, NICE_PALETTES).slice(0, 2);
|
@@ -129,161 +122,93 @@ function resolveCharColors(rand, colors) {
|
|
129
122
|
const a2 = colors[2] ?? shade(base, -0.2);
|
130
123
|
return [base, a1, a2];
|
131
124
|
}
|
132
|
-
function Face({
|
133
|
-
const eyeOffsetX = r * (0.34 + rand() * 0.06);
|
134
|
-
const eyeOffsetY = r * (0.2 + rand() * 0.06);
|
135
|
-
const eyeR = Math.max(2, Math.round(r * (0.08 + rand() * 0.02)));
|
136
|
-
const mouthWidth = r * (0.7 + rand() * 0.3);
|
137
|
-
const mouthLift = r * (0.18 + rand() * 0.16);
|
138
|
-
const mouthCurve = (rand() - 0.5) * 0.8;
|
139
|
-
const mouthStroke = Math.max(1, Math.round(r * 0.06));
|
140
|
-
const x0 = cx - mouthWidth / 2;
|
141
|
-
const x1 = cx + mouthWidth / 2;
|
142
|
-
const my = cy + mouthLift;
|
143
|
-
const cxQ = cx;
|
144
|
-
const cyQ = my + r * (-0.25 * mouthCurve - 0.1);
|
145
|
-
const d = `M ${x0} ${my} Q ${cxQ} ${cyQ} ${x1} ${my}`;
|
146
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
147
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx - eyeOffsetX, cy: cy - eyeOffsetY, r: eyeR, fill: color }),
|
148
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx + eyeOffsetX, cy: cy - eyeOffsetY, r: eyeR, fill: color }),
|
149
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d, stroke: color, strokeWidth: mouthStroke, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" })
|
150
|
-
] });
|
151
|
-
}
|
152
|
-
function Overlays({
|
125
|
+
function Face({
|
153
126
|
cx,
|
154
127
|
cy,
|
155
128
|
r,
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
129
|
+
color,
|
130
|
+
eyeShape: eyeShapeProp,
|
131
|
+
mouthShape: mouthShapeProp,
|
132
|
+
pupilColor,
|
133
|
+
eyeShine: eyeShineProp,
|
160
134
|
rand
|
161
135
|
}) {
|
162
|
-
const
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
const
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
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 });
|
193
|
-
// NEW variant: large half/diagonal cut (looks like attached image)
|
194
|
-
case "half": {
|
195
|
-
const diag = rand() > 0.4;
|
196
|
-
if (diag) {
|
197
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: `${x0},${y0} ${x1},${y0} ${x1},${cy + (left ? r * 0.1 : -r * 0.1)}`, fill: a1 });
|
198
|
-
} else {
|
199
|
-
const offset = left ? -r * 0.18 : r * 0.18;
|
200
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: cx + offset, cy, r: r * 0.95, fill: a1 });
|
136
|
+
const decide = (prop, opts) => {
|
137
|
+
if (prop === void 0 || prop === "random") return pick(rand, opts);
|
138
|
+
return prop;
|
139
|
+
};
|
140
|
+
const eyeShape = decide(eyeShapeProp ?? "random", ["circle", "ellipse", "line", "wink", "sleepy", "surprised"]);
|
141
|
+
const mouthShape = decide(mouthShapeProp ?? "random", ["smile", "frown", "flat", "zigzag"]);
|
142
|
+
const eyeShine = decide(eyeShineProp ?? "random", [true, false]);
|
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;
|
149
|
+
const mouthStroke = Math.max(1, Math.round(r * 0.06));
|
150
|
+
const finalPupilColor = pupilColor && pupilColor !== "auto" ? pupilColor : yiq(color) > 150 ? "#111827" : "#ffffff";
|
151
|
+
const x0 = cx - mouthWidth / 2;
|
152
|
+
const x1 = cx + mouthWidth / 2;
|
153
|
+
const my = cy + mouthLift;
|
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}`;
|
201
166
|
}
|
167
|
+
return d;
|
168
|
+
})()
|
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);
|
182
|
+
default:
|
183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: ex, cy: ey, r: eyeR, fill: color }, key);
|
202
184
|
}
|
203
|
-
|
204
|
-
|
205
|
-
|
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 })
|
195
|
+
] }) : null;
|
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
|
203
|
+
] });
|
206
204
|
}
|
207
|
-
function Avatar({
|
208
|
-
name
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
headShape,
|
215
|
-
square,
|
216
|
-
alignX = "center",
|
217
|
-
alignY = "center",
|
218
|
-
padding,
|
219
|
-
variant = "auto",
|
220
|
-
className,
|
221
|
-
style,
|
222
|
-
title
|
223
|
-
}) {
|
224
|
-
const shape = headShape ?? (square ? "square" : "circle");
|
225
|
-
const rand = React.useMemo(() => rngFromSeed(String(name)), [name]);
|
226
|
-
const [bg1, bg2] = React.useMemo(() => resolveBg(rand, bg), [rand, bg]);
|
227
|
-
const [base, a1, a2] = React.useMemo(() => resolveCharColors(rand, colors), [rand, colors]);
|
228
|
-
const faceColor = bestFeatureColor(base);
|
229
|
-
const grid = Math.max(6, Math.floor(size / pixelSize));
|
230
|
-
const tile = Math.ceil(size / grid);
|
231
|
-
const autoPad = Math.max(4, Math.round(size * (0.06 + rand() * 0.02)));
|
232
|
-
const pad = padding ?? autoPad;
|
233
|
-
const baseR = Math.floor(size * (0.36 + rand() * 0.04));
|
234
|
-
const maxR = Math.floor(size / 2 - pad);
|
235
|
-
const r = Math.max(8, Math.min(baseR, maxR));
|
236
|
-
let cx = size / 2;
|
237
|
-
let cy = size / 2;
|
238
|
-
if (alignX === "left") cx = r + pad;
|
239
|
-
if (alignX === "right") cx = size - (r + pad);
|
240
|
-
if (alignY === "top") cy = r + pad;
|
241
|
-
if (alignY === "bottom") cy = size - (r + pad);
|
242
|
-
const cells = [];
|
243
|
-
const cols = mirrored ? Math.ceil(grid / 2) : grid;
|
244
|
-
for (let y = 0; y < grid; y++) {
|
245
|
-
for (let x = 0; x < cols; x++) {
|
246
|
-
const use = rand() > 0.5;
|
247
|
-
const fill = use ? bg1 : bg2;
|
248
|
-
const px = x * tile;
|
249
|
-
const py = y * tile;
|
250
|
-
cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: px, y: py, width: tile, height: tile, fill }, `L${x},${y}`));
|
251
|
-
if (mirrored) {
|
252
|
-
const mx = grid - x - 1;
|
253
|
-
const mpx = mx * tile;
|
254
|
-
cells.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: mpx, y: py, width: tile, height: tile, fill }, `R${mx},${y}`));
|
255
|
-
}
|
256
|
-
}
|
257
|
-
}
|
258
|
-
const variants = ["split", "swoop", "diagonal", "cap", "crescent", "band", "corner", "ring", "arc", "wave", "plain", "half"];
|
259
|
-
const chosenVariant = variant === "auto" ? pick(rand, variants) : variant;
|
260
|
-
const clipId = React.useMemo(() => {
|
261
|
-
const [a, b, c, d] = cyrb128(`pp-shape-${name}-${shape}-${r}`);
|
262
|
-
return `pps-${a.toString(16)}${b.toString(16)}${c.toString(16)}${d.toString(16)}`;
|
263
|
-
}, [name, shape, r]);
|
264
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
265
|
-
"svg",
|
266
|
-
{
|
267
|
-
width: size,
|
268
|
-
height: size,
|
269
|
-
viewBox: `0 0 ${size} ${size}`,
|
270
|
-
xmlns: "http://www.w3.org/2000/svg",
|
271
|
-
role: "img",
|
272
|
-
"aria-label": title ?? `Avatar ${name}`,
|
273
|
-
className,
|
274
|
-
style: { display: "inline-block", borderRadius: 12, ...style },
|
275
|
-
children: [
|
276
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: size, height: size, fill: bg1 }),
|
277
|
-
cells,
|
278
|
-
/* @__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 }) }) }),
|
279
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { clipPath: `url(#${clipId})`, children: [
|
280
|
-
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), fill: base }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx, cy, r, fill: base }),
|
281
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Overlays, { cx, cy, r, a1, a2, variant: chosenVariant, shape, rand })
|
282
|
-
] }),
|
283
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Face, { cx, cy, r, color: faceColor, rand })
|
284
|
-
]
|
285
|
-
}
|
286
|
-
);
|
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 }) });
|
287
212
|
}
|
288
213
|
// Annotate the CommonJS export names for ESM import in node:
|
289
214
|
0 && (module.exports = {
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/Avatar.tsx"],"sourcesContent":["export { default as Avatar } from \"./Avatar\";\r\nexport { default } from \"./Avatar\";\r\n","import * as React from \"react\";\r\nimport palettes100 from \"nice-color-palettes\";\r\nexport type HeadShape = \"circle\" | \"square\";\r\nexport type Variant =\r\n | \"auto\"\r\n | \"plain\"\r\n | \"split\"\r\n | \"swoop\"\r\n | \"diagonal\"\r\n | \"cap\"\r\n | \"crescent\"\r\n | \"band\"\r\n | \"corner\"\r\n | \"ring\"\r\n | \"arc\"\r\n | \"wave\"\r\n | \"half\"; // <-- new variant\r\nexport type AlignX = \"left\" | \"center\" | \"right\";\r\nexport type AlignY = \"top\" | \"center\" | \"bottom\";\r\n\r\nexport type AvatarProps = {\r\n name: string;\r\n\r\n // pixel background\r\n size?: number;\r\n pixelSize?: number;\r\n mirrored?: boolean;\r\n bg?: [string, string] | string | \"random\";\r\n\r\n // character controls\r\n headShape?: HeadShape;\r\n square?: boolean; // deprecated\r\n alignX?: AlignX;\r\n alignY?: AlignY;\r\n padding?: number;\r\n\r\n colors?: string | [string, string] | [string, string, string] | \"random\";\r\n variant?: Variant;\r\n\r\n // styling/a11y\r\n className?: string;\r\n style?: React.CSSProperties;\r\n title?: string;\r\n};\r\n\r\n//\r\n// Deterministic RNG (seeded)\r\n//\r\nfunction cyrb128(str: string) {\r\n let h1 = 1779033703, h2 = 3144134277, h3 = 1013904242, h4 = 2773480762;\r\n for (let i = 0, k; i < str.length; i++) {\r\n k = str.charCodeAt(i);\r\n h1 = h2 ^ Math.imul(h1 ^ k, 597399067);\r\n h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);\r\n h3 = h4 ^ Math.imul(h3 ^ k, 951274213);\r\n h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);\r\n }\r\n h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);\r\n h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);\r\n h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);\r\n h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);\r\n return [(h1 ^ h2 ^ h3 ^ h4) >>> 0, (h2 ^ h1) >>> 0, (h3 ^ h1) >>> 0, (h4 ^ h1) >>> 0];\r\n}\r\nfunction sfc32(a: number, b: number, c: number, d: number) {\r\n return function () {\r\n a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;\r\n let t = (a + b) | 0;\r\n a = b ^ (b >>> 9);\r\n b = (c + (c << 3)) | 0;\r\n c = (c << 21) | (c >>> 11);\r\n d = (d + 1) | 0;\r\n t = (t + d) | 0;\r\n c = (c + t) | 0;\r\n return (t >>> 0) / 4294967296;\r\n };\r\n}\r\nfunction rngFromSeed(seed: string) {\r\n const [a, b, c, d] = cyrb128(seed || \"pixelpeeps\");\r\n return sfc32(a, b, c, d);\r\n}\r\nfunction pick<T>(rand: () => number, arr: T[]) {\r\n return arr[Math.floor(rand() * arr.length)];\r\n}\r\n\r\n//\r\n// Color helpers\r\n//\r\nfunction hexToRgb(hex: string) {\r\n const h = hex.replace(\"#\", \"\");\r\n const full = h.length === 3 ? h.split(\"\").map(c => c + c).join(\"\") : h;\r\n const n = parseInt(full, 16);\r\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\r\n}\r\nfunction rgbToHex(r: number, g: number, b: number) {\r\n return \"#\" + [r, g, b].map(v => v.toString(16).padStart(2, \"0\")).join(\"\");\r\n}\r\nfunction shade(hex: string, percent: number) {\r\n const { r, g, b } = hexToRgb(hex);\r\n const t = percent < 0 ? 0 : 255;\r\n const p = Math.abs(percent);\r\n return rgbToHex(\r\n Math.round((t - r) * p) + r,\r\n Math.round((t - g) * p) + g,\r\n Math.round((t - b) * p) + b\r\n );\r\n}\r\nfunction yiq(hex: string) {\r\n const { r, g, b } = hexToRgb(hex);\r\n return (r * 299 + g * 587 + b * 114) / 1000;\r\n}\r\nfunction bestFeatureColor(base: string) {\r\n return yiq(base) > 150 ? \"#111827\" : \"#ffffff\";\r\n}\r\n\r\n//\r\n// Palettes: use nice-color-palettes (top 100)\r\n//\r\nconst NICE_PALETTES: string[][] = (palettes100 && Array.isArray(palettes100)) ? palettes100 as string[][] : [\r\n // fallback single palette\r\n [\"#73a9ff\", \"#fef3c7\", \"#ffd6a5\", \"#d4b4ff\", \"#a7f3d0\"]\r\n];\r\n\r\nfunction resolveBg(rand: () => number, bg?: AvatarProps[\"bg\"]): [string, string] {\r\n if (!bg || bg === \"random\") {\r\n return pick(rand, NICE_PALETTES).slice(0, 2) as [string, string];\r\n }\r\n if (Array.isArray(bg)) return [bg[0], bg[1] ?? bg[0]];\r\n // single hex -> auto shade pair\r\n return [shade(bg, 0.12), shade(bg, -0.06)];\r\n}\r\nfunction resolveCharColors(rand: () => number, colors?: AvatarProps[\"colors\"]): [string, string, string] {\r\n if (!colors || colors === \"random\") {\r\n const pal = pick(rand, NICE_PALETTES);\r\n const base = pal[0];\r\n const a1 = pal[1] ?? shade(base, 0.25);\r\n const a2 = pal[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n }\r\n if (typeof colors === \"string\") {\r\n return [colors, shade(colors, 0.25), shade(colors, -0.2)];\r\n }\r\n const base = (colors as string[])[0];\r\n const a1 = (colors as string[])[1] ?? shade(base, 0.25);\r\n const a2 = (colors as string[])[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n}\r\n\r\n//\r\n// Small face subcomponent: parametric mouth (fixed nice curve)\r\n//\r\nfunction Face({ cx, cy, r, color, rand }: { cx: number; cy: number; r: number; color: string; rand: () => number }) {\r\n const eyeOffsetX = r * (0.34 + rand() * 0.06); // small variation from seed\r\n const eyeOffsetY = r * (0.20 + rand() * 0.06);\r\n const eyeR = Math.max(2, Math.round(r * (0.08 + rand() * 0.02)));\r\n // Parametric mouth values from seed:\r\n const mouthWidth = r * (0.7 + rand() * 0.3); // 70-100%\r\n const mouthLift = r * (0.18 + rand() * 0.16); // 18-34%\r\n const mouthCurve = (rand() - 0.5) * 0.8; // -0.4..0.4 adjusts curvature (smile vs big smile)\r\n const mouthStroke = Math.max(1, Math.round(r * 0.06));\r\n\r\n // compute coordinates\r\n const x0 = cx - mouthWidth / 2;\r\n const x1 = cx + mouthWidth / 2;\r\n const my = cy + mouthLift;\r\n\r\n // quadratic control point to make a smooth curve (smile)\r\n const cxQ = cx;\r\n const cyQ = my + r * (-0.25 * mouthCurve - 0.1); // move control up or down by mouthCurve\r\n\r\n const d = `M ${x0} ${my} Q ${cxQ} ${cyQ} ${x1} ${my}`;\r\n\r\n return (\r\n <>\r\n <circle cx={cx - eyeOffsetX} cy={cy - eyeOffsetY} r={eyeR} fill={color} />\r\n <circle cx={cx + eyeOffsetX} cy={cy - eyeOffsetY} r={eyeR} fill={color} />\r\n <path d={d} stroke={color} strokeWidth={mouthStroke} fill=\"none\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\r\n </>\r\n );\r\n}\r\n\r\n//\r\n// Overlays (variants) including new `half` variant\r\n//\r\nfunction Overlays({\r\n cx, cy, r, a1, a2, variant, shape, rand\r\n}: {\r\n cx: number; cy: number; r: number;\r\n a1: string; a2: string;\r\n variant: Exclude<Variant, \"auto\">;\r\n shape: HeadShape;\r\n rand: () => number;\r\n}) {\r\n const x0 = cx - r, y0 = cy - r, x1 = cx + r, y1 = cy + r;\r\n\r\n // deterministic options\r\n const left = rand() > 0.5;\r\n const tlbr = rand() > 0.5;\r\n const horiz = rand() > 0.5;\r\n const cornerTL = rand() > 0.5;\r\n\r\n switch (variant) {\r\n case \"plain\": return null;\r\n\r\n case \"split\":\r\n return <rect x={left ? x0 : cx} y={y0} width={r} height={2 * r} fill={a1} />;\r\n\r\n case \"diagonal\":\r\n return tlbr ? (\r\n <polygon points={`${x0},${y0} ${x1},${y0} ${x1},${y1}`} fill={a1} />\r\n ) : (\r\n <polygon points={`${x0},${y0} ${x0},${y1} ${x1},${y1}`} fill={a1} />\r\n );\r\n\r\n case \"cap\":\r\n return (\r\n <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} />\r\n );\r\n\r\n case \"swoop\":\r\n return (\r\n <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} />\r\n );\r\n\r\n case \"crescent\":\r\n return (\r\n <>\r\n <circle cx={left ? cx - r * 0.55 : cx + r * 0.55} cy={cy} r={r * 0.95} fill={a2} />\r\n <circle cx={left ? cx - r * 0.52 : cx + r * 0.52} cy={cy} r={r * 0.75} fill=\"transparent\" stroke={shade(a2, -0.25)} strokeWidth={r * 0.08} />\r\n </>\r\n );\r\n\r\n case \"band\":\r\n return horiz ? (\r\n <rect x={x0} y={cy - r * 0.35} width={2 * r} height={r * 0.5} fill={a1} />\r\n ) : (\r\n <rect x={cx - r * 0.35} y={y0} width={r * 0.5} height={2 * r} fill={a1} />\r\n );\r\n\r\n case \"corner\":\r\n return cornerTL ? (\r\n <polygon points={`${x0},${y0} ${x0 + r * 0.9},${y0} ${x0},${y0 + r * 0.9}`} fill={a1} />\r\n ) : (\r\n <polygon points={`${x1},${y0} ${x1 - r * 0.9},${y0} ${x1},${y0 + r * 0.9}`} fill={a1} />\r\n );\r\n\r\n case \"ring\":\r\n return shape === \"circle\" ? (\r\n <circle cx={cx} cy={cy} r={r * 0.86} fill=\"none\" stroke={a1} strokeWidth={r * 0.18} />\r\n ) : (\r\n <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} />\r\n );\r\n\r\n case \"arc\":\r\n return <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} />;\r\n\r\n case \"wave\":\r\n return <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} />;\r\n\r\n // NEW variant: large half/diagonal cut (looks like attached image)\r\n case \"half\": {\r\n // choose diag or simple half using rand\r\n const diag = rand() > 0.4;\r\n if (diag) {\r\n // diagonal wedge\r\n return <polygon points={`${x0},${y0} ${x1},${y0} ${x1},${cy + (left ? r * 0.1 : -r * 0.1)}`} fill={a1} />;\r\n } else {\r\n // simple semicircle overlay offset to left/right for crescent effect\r\n const offset = left ? -r * 0.18 : r * 0.18;\r\n return <circle cx={cx + offset} cy={cy} r={r * 0.95} fill={a1} />;\r\n }\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\n//\r\n// Main component\r\n//\r\nexport default function Avatar({\r\n name,\r\n size = 128,\r\n pixelSize = 12,\r\n mirrored = true,\r\n bg,\r\n colors,\r\n headShape,\r\n square,\r\n alignX = \"center\",\r\n alignY = \"center\",\r\n padding,\r\n variant = \"auto\",\r\n className,\r\n style,\r\n title,\r\n}: AvatarProps) {\r\n const shape: HeadShape = headShape ?? (square ? \"square\" : \"circle\");\r\n // single RNG for everything derived from seed (deterministic)\r\n const rand = React.useMemo(() => rngFromSeed(String(name)), [name]);\r\n\r\n // background and character colors chosen from nice palettes\r\n const [bg1, bg2] = React.useMemo(() => resolveBg(rand, bg), [rand, bg]);\r\n const [base, a1, a2] = React.useMemo(() => resolveCharColors(rand, colors), [rand, colors]);\r\n const faceColor = bestFeatureColor(base);\r\n\r\n // Pixel grid\r\n const grid = Math.max(6, Math.floor(size / pixelSize));\r\n const tile = Math.ceil(size / grid);\r\n\r\n // geometry/calculations (all derived from rand)\r\n const autoPad = Math.max(4, Math.round(size * (0.06 + rand() * 0.02)));\r\n const pad = padding ?? autoPad;\r\n const baseR = Math.floor(size * (0.36 + rand() * 0.04)); // slight variation\r\n const maxR = Math.floor(size / 2 - pad);\r\n const r = Math.max(8, Math.min(baseR, maxR));\r\n\r\n let cx = size / 2;\r\n let cy = size / 2;\r\n if (alignX === \"left\") cx = r + pad;\r\n if (alignX === \"right\") cx = size - (r + pad);\r\n if (alignY === \"top\") cy = r + pad;\r\n if (alignY === \"bottom\") cy = size - (r + pad);\r\n\r\n // Pixel pattern generation -> uses rand sequentially; deterministic for seed\r\n const cells: React.ReactElement[] = [];\r\n const cols = mirrored ? Math.ceil(grid / 2) : grid;\r\n for (let y = 0; y < grid; y++) {\r\n for (let x = 0; x < cols; x++) {\r\n const use = rand() > 0.5;\r\n const fill = use ? bg1 : bg2;\r\n const px = x * tile;\r\n const py = y * tile;\r\n cells.push(<rect key={`L${x},${y}`} x={px} y={py} width={tile} height={tile} fill={fill} />);\r\n if (mirrored) {\r\n const mx = grid - x - 1;\r\n const mpx = mx * tile;\r\n cells.push(<rect key={`R${mx},${y}`} x={mpx} y={py} width={tile} height={tile} fill={fill} />);\r\n }\r\n }\r\n }\r\n\r\n // pick variant deterministically\r\n const variants: Exclude<Variant, \"auto\">[] = [\"split\", \"swoop\", \"diagonal\", \"cap\", \"crescent\", \"band\", \"corner\", \"ring\", \"arc\", \"wave\", \"plain\", \"half\"];\r\n const chosenVariant: Exclude<Variant, \"auto\"> = variant === \"auto\" ? pick(rand, variants) : (variant as Exclude<Variant, \"auto\">);\r\n\r\n // clip path id (stable-ish)\r\n const clipId = React.useMemo(() => {\r\n const [a, b, c, d] = cyrb128(`pp-shape-${name}-${shape}-${r}`);\r\n return `pps-${a.toString(16)}${b.toString(16)}${c.toString(16)}${d.toString(16)}`;\r\n }, [name, shape, r]);\r\n\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox={`0 0 ${size} ${size}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n role=\"img\"\r\n aria-label={title ?? `Avatar ${name}`}\r\n className={className}\r\n style={{ display: \"inline-block\", borderRadius: 12, ...style }}\r\n >\r\n {/* background grid */}\r\n <rect width={size} height={size} fill={bg1} />\r\n {cells}\r\n\r\n <defs>\r\n <clipPath id={clipId}>\r\n {shape === \"square\" ? (\r\n <rect x={cx - r} y={cy - r} width={2 * r} height={2 * r} rx={Math.max(4, r * 0.12)} />\r\n ) : (\r\n <circle cx={cx} cy={cy} r={r} />\r\n )}\r\n </clipPath>\r\n </defs>\r\n\r\n {/* head + overlays */}\r\n <g clipPath={`url(#${clipId})`}>\r\n {shape === \"square\" ? (\r\n <rect x={cx - r} y={cy - r} width={2 * r} height={2 * r} rx={Math.max(4, r * 0.12)} fill={base} />\r\n ) : (\r\n <circle cx={cx} cy={cy} r={r} fill={base} />\r\n )}\r\n\r\n <Overlays cx={cx} cy={cy} r={r} a1={a1} a2={a2} variant={chosenVariant} shape={shape} rand={rand} />\r\n </g>\r\n\r\n {/* facial features */}\r\n <Face cx={cx} cy={cy} r={r} color={faceColor} rand={rand} />\r\n </svg>\r\n );\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,YAAuB;AACvB,iCAAwB;AA2KpB;AA5HJ,SAAS,QAAQ,KAAa;AAC5B,MAAI,KAAK,YAAY,KAAK,YAAY,KAAK,YAAY,KAAK;AAC5D,WAAS,IAAI,GAAG,GAAG,IAAI,IAAI,QAAQ,KAAK;AACtC,QAAI,IAAI,WAAW,CAAC;AACpB,SAAK,KAAK,KAAK,KAAK,KAAK,GAAG,SAAS;AACrC,SAAK,KAAK,KAAK,KAAK,KAAK,GAAG,UAAU;AACtC,SAAK,KAAK,KAAK,KAAK,KAAK,GAAG,SAAS;AACrC,SAAK,KAAK,KAAK,KAAK,KAAK,GAAG,UAAU;AAAA,EACxC;AACA,OAAK,KAAK,KAAK,KAAM,OAAO,IAAK,SAAS;AAC1C,OAAK,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;AAC3C,OAAK,KAAK,KAAK,KAAM,OAAO,IAAK,SAAS;AAC1C,OAAK,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;AAC3C,SAAO,EAAE,KAAK,KAAK,KAAK,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK,QAAQ,CAAC;AACtF;AACA,SAAS,MAAM,GAAW,GAAW,GAAW,GAAW;AACzD,SAAO,WAAY;AACjB,WAAO;AAAG,WAAO;AAAG,WAAO;AAAG,WAAO;AACrC,QAAI,IAAK,IAAI,IAAK;AAClB,QAAI,IAAK,MAAM;AACf,QAAK,KAAK,KAAK,KAAM;AACrB,QAAK,KAAK,KAAO,MAAM;AACvB,QAAK,IAAI,IAAK;AACd,QAAK,IAAI,IAAK;AACd,QAAK,IAAI,IAAK;AACd,YAAQ,MAAM,KAAK;AAAA,EACrB;AACF;AACA,SAAS,YAAY,MAAc;AACjC,QAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,QAAQ,QAAQ,YAAY;AACjD,SAAO,MAAM,GAAG,GAAG,GAAG,CAAC;AACzB;AACA,SAAS,KAAQ,MAAoB,KAAU;AAC7C,SAAO,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC;AAC5C;AAKA,SAAS,SAAS,KAAa;AAC7B,QAAM,IAAI,IAAI,QAAQ,KAAK,EAAE;AAC7B,QAAM,OAAO,EAAE,WAAW,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,OAAK,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI;AACrE,QAAM,IAAI,SAAS,MAAM,EAAE;AAC3B,SAAO,EAAE,GAAI,KAAK,KAAM,KAAK,GAAI,KAAK,IAAK,KAAK,GAAG,IAAI,IAAI;AAC7D;AACA,SAAS,SAAS,GAAW,GAAW,GAAW;AACjD,SAAO,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,OAAK,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAC1E;AACA,SAAS,MAAM,KAAa,SAAiB;AAC3C,QAAM,EAAE,GAAG,GAAG,EAAE,IAAI,SAAS,GAAG;AAChC,QAAM,IAAI,UAAU,IAAI,IAAI;AAC5B,QAAM,IAAI,KAAK,IAAI,OAAO;AAC1B,SAAO;AAAA,IACL,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI;AAAA,IAC1B,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI;AAAA,IAC1B,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI;AAAA,EAC5B;AACF;AACA,SAAS,IAAI,KAAa;AACxB,QAAM,EAAE,GAAG,GAAG,EAAE,IAAI,SAAS,GAAG;AAChC,UAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO;AACzC;AACA,SAAS,iBAAiB,MAAc;AACtC,SAAO,IAAI,IAAI,IAAI,MAAM,YAAY;AACvC;AAKA,IAAM,gBAA6B,2BAAAA,WAAe,MAAM,QAAQ,2BAAAA,OAAW,IAAK,2BAAAA,UAA4B;AAAA;AAAA,EAE1G,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AACxD;AAEA,SAAS,UAAU,MAAoB,IAA0C;AAC/E,MAAI,CAAC,MAAM,OAAO,UAAU;AAC1B,WAAO,KAAK,MAAM,aAAa,EAAE,MAAM,GAAG,CAAC;AAAA,EAC7C;AACA,MAAI,MAAM,QAAQ,EAAE,EAAG,QAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;AAEpD,SAAO,CAAC,MAAM,IAAI,IAAI,GAAG,MAAM,IAAI,KAAK,CAAC;AAC3C;AACA,SAAS,kBAAkB,MAAoB,QAA0D;AACvG,MAAI,CAAC,UAAU,WAAW,UAAU;AAClC,UAAM,MAAM,KAAK,MAAM,aAAa;AACpC,UAAMC,QAAO,IAAI,CAAC;AAClB,UAAMC,MAAK,IAAI,CAAC,KAAK,MAAMD,OAAM,IAAI;AACrC,UAAME,MAAK,IAAI,CAAC,KAAK,MAAMF,OAAM,IAAI;AACrC,WAAO,CAACA,OAAMC,KAAIC,GAAE;AAAA,EACtB;AACA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,CAAC,QAAQ,MAAM,QAAQ,IAAI,GAAG,MAAM,QAAQ,IAAI,CAAC;AAAA,EAC1D;AACA,QAAM,OAAQ,OAAoB,CAAC;AACnC,QAAM,KAAM,OAAoB,CAAC,KAAK,MAAM,MAAM,IAAI;AACtD,QAAM,KAAM,OAAoB,CAAC,KAAK,MAAM,MAAM,IAAI;AACtD,SAAO,CAAC,MAAM,IAAI,EAAE;AACtB;AAKA,SAAS,KAAK,EAAE,IAAI,IAAI,GAAG,OAAO,KAAK,GAA6E;AAClH,QAAM,aAAa,KAAK,OAAO,KAAK,IAAI;AACxC,QAAM,aAAa,KAAK,MAAO,KAAK,IAAI;AACxC,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,KAAK,CAAC;AAE/D,QAAM,aAAa,KAAK,MAAM,KAAK,IAAI;AACvC,QAAM,YAAY,KAAK,OAAO,KAAK,IAAI;AACvC,QAAM,cAAc,KAAK,IAAI,OAAO;AACpC,QAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC;AAGpD,QAAM,KAAK,KAAK,aAAa;AAC7B,QAAM,KAAK,KAAK,aAAa;AAC7B,QAAM,KAAK,KAAK;AAGhB,QAAM,MAAM;AACZ,QAAM,MAAM,KAAK,KAAK,QAAQ,aAAa;AAE3C,QAAM,IAAI,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE;AAEnD,SACE,4EACE;AAAA,gDAAC,YAAO,IAAI,KAAK,YAAY,IAAI,KAAK,YAAY,GAAG,MAAM,MAAM,OAAO;AAAA,IACxE,4CAAC,YAAO,IAAI,KAAK,YAAY,IAAI,KAAK,YAAY,GAAG,MAAM,MAAM,OAAO;AAAA,IACxE,4CAAC,UAAK,GAAM,QAAQ,OAAO,aAAa,aAAa,MAAK,QAAO,eAAc,SAAQ,gBAAe,SAAQ;AAAA,KAChH;AAEJ;AAKA,SAAS,SAAS;AAAA,EAChB;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAS;AAAA,EAAO;AACrC,GAMG;AACD,QAAM,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK;AAGvD,QAAM,OAAO,KAAK,IAAI;AACtB,QAAM,OAAO,KAAK,IAAI;AACtB,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,WAAW,KAAK,IAAI;AAE1B,UAAQ,SAAS;AAAA,IACf,KAAK;AAAS,aAAO;AAAA,IAErB,KAAK;AACH,aAAO,4CAAC,UAAK,GAAG,OAAO,KAAK,IAAI,GAAG,IAAI,OAAO,GAAG,QAAQ,IAAI,GAAG,MAAM,IAAI;AAAA,IAE5E,KAAK;AACH,aAAO,OACL,4CAAC,aAAQ,QAAQ,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,MAAM,IAAI,IAElE,4CAAC,aAAQ,QAAQ,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,MAAM,IAAI;AAAA,IAGtE,KAAK;AACH,aACE,4CAAC,UAAK,GAAG,KAAK,EAAE,IAAI,KAAK,IAAI,IAAI,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,KAAK,IAAI,GAAG,MAAM,EAAE,IAAI,KAAK,IAAI,IAAI,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,MAAM,MAAM,IAAI;AAAA,IAG1I,KAAK;AACH,aACE,4CAAC,UAAK,GAAG,KAAK,EAAE,IAAI,KAAK,IAAI,IAAI,MAAM,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,KAAK,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,MAAM,IAAI;AAAA,IAGvJ,KAAK;AACH,aACE,4EACE;AAAA,oDAAC,YAAO,IAAI,OAAO,KAAK,IAAI,OAAO,KAAK,IAAI,MAAM,IAAQ,GAAG,IAAI,MAAM,MAAM,IAAI;AAAA,QACjF,4CAAC,YAAO,IAAI,OAAO,KAAK,IAAI,OAAO,KAAK,IAAI,MAAM,IAAQ,GAAG,IAAI,MAAM,MAAK,eAAc,QAAQ,MAAM,IAAI,KAAK,GAAG,aAAa,IAAI,MAAM;AAAA,SAC7I;AAAA,IAGJ,KAAK;AACH,aAAO,QACL,4CAAC,UAAK,GAAG,IAAI,GAAG,KAAK,IAAI,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,MAAM,IAAI,IAExE,4CAAC,UAAK,GAAG,KAAK,IAAI,MAAM,GAAG,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,GAAG,MAAM,IAAI;AAAA,IAG5E,KAAK;AACH,aAAO,WACL,4CAAC,aAAQ,QAAQ,GAAG,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,MAAM,IAAI,IAEtF,4CAAC,aAAQ,QAAQ,GAAG,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,MAAM,IAAI;AAAA,IAG1F,KAAK;AACH,aAAO,UAAU,WACf,4CAAC,YAAO,IAAQ,IAAQ,GAAG,IAAI,MAAM,MAAK,QAAO,QAAQ,IAAI,aAAa,IAAI,MAAM,IAEpF,4CAAC,UAAK,GAAG,KAAK,IAAI,MAAM,GAAG,KAAK,IAAI,MAAM,OAAO,IAAI,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,IAAI,MAAM,MAAK,QAAO,QAAQ,IAAI,aAAa,IAAI,MAAM;AAAA,IAGtJ,KAAK;AACH,aAAO,4CAAC,UAAK,GAAG,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,GAAG,MAAM,EAAE,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,IAAI,MAAM,MAAM,IAAI;AAAA,IAEnK,KAAK;AACH,aAAO,4CAAC,UAAK,GAAG,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,MAAM,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,MAAM,IAAI;AAAA;AAAA,IAG9N,KAAK,QAAQ;AAEX,YAAM,OAAO,KAAK,IAAI;AACtB,UAAI,MAAM;AAER,eAAO,4CAAC,aAAQ,QAAQ,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,MAAM,IAAI;AAAA,MACzG,OAAO;AAEL,cAAM,SAAS,OAAO,CAAC,IAAI,OAAO,IAAI;AACtC,eAAO,4CAAC,YAAO,IAAI,KAAK,QAAQ,IAAQ,GAAG,IAAI,MAAM,MAAM,IAAI;AAAA,MACjE;AAAA,IACF;AAAA,IAEA;AACE,aAAO;AAAA,EACX;AACF;AAKe,SAAR,OAAwB;AAAA,EAC7B;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,GAAgB;AACd,QAAM,QAAmB,cAAc,SAAS,WAAW;AAE3D,QAAM,OAAa,cAAQ,MAAM,YAAY,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AAGlE,QAAM,CAAC,KAAK,GAAG,IAAU,cAAQ,MAAM,UAAU,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACtE,QAAM,CAAC,MAAM,IAAI,EAAE,IAAU,cAAQ,MAAM,kBAAkB,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC;AAC1F,QAAM,YAAY,iBAAiB,IAAI;AAGvC,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,SAAS,CAAC;AACrD,QAAM,OAAO,KAAK,KAAK,OAAO,IAAI;AAGlC,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,OAAO,KAAK,IAAI,KAAK,CAAC;AACrE,QAAM,MAAM,WAAW;AACvB,QAAM,QAAQ,KAAK,MAAM,QAAQ,OAAO,KAAK,IAAI,KAAK;AACtD,QAAM,OAAO,KAAK,MAAM,OAAO,IAAI,GAAG;AACtC,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,IAAI,CAAC;AAE3C,MAAI,KAAK,OAAO;AAChB,MAAI,KAAK,OAAO;AAChB,MAAI,WAAW,OAAQ,MAAK,IAAI;AAChC,MAAI,WAAW,QAAS,MAAK,QAAQ,IAAI;AACzC,MAAI,WAAW,MAAO,MAAK,IAAI;AAC/B,MAAI,WAAW,SAAU,MAAK,QAAQ,IAAI;AAG1C,QAAM,QAA8B,CAAC;AACrC,QAAM,OAAO,WAAW,KAAK,KAAK,OAAO,CAAC,IAAI;AAC9C,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,OAAO,MAAM,MAAM;AACzB,YAAM,KAAK,IAAI;AACf,YAAM,KAAK,IAAI;AACf,YAAM,KAAK,4CAAC,UAAwB,GAAG,IAAI,GAAG,IAAI,OAAO,MAAM,QAAQ,MAAM,QAAvD,IAAI,CAAC,IAAI,CAAC,EAAyD,CAAE;AAC3F,UAAI,UAAU;AACZ,cAAM,KAAK,OAAO,IAAI;AACtB,cAAM,MAAM,KAAK;AACjB,cAAM,KAAK,4CAAC,UAAyB,GAAG,KAAK,GAAG,IAAI,OAAO,MAAM,QAAQ,MAAM,QAAzD,IAAI,EAAE,IAAI,CAAC,EAA0D,CAAE;AAAA,MAC/F;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAuC,CAAC,SAAS,SAAS,YAAY,OAAO,YAAY,QAAQ,UAAU,QAAQ,OAAO,QAAQ,SAAS,MAAM;AACvJ,QAAM,gBAA0C,YAAY,SAAS,KAAK,MAAM,QAAQ,IAAK;AAG7F,QAAM,SAAe,cAAQ,MAAM;AACjC,UAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,QAAQ,YAAY,IAAI,IAAI,KAAK,IAAI,CAAC,EAAE;AAC7D,WAAO,OAAO,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC;AAAA,EACjF,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;AAEnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS,OAAO,IAAI,IAAI,IAAI;AAAA,MAC5B,OAAM;AAAA,MACN,MAAK;AAAA,MACL,cAAY,SAAS,UAAU,IAAI;AAAA,MACnC;AAAA,MACA,OAAO,EAAE,SAAS,gBAAgB,cAAc,IAAI,GAAG,MAAM;AAAA,MAG7D;AAAA,oDAAC,UAAK,OAAO,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,QAC3C;AAAA,QAED,4CAAC,UACC,sDAAC,cAAS,IAAI,QACX,oBAAU,WACT,4CAAC,UAAK,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,OAAO,IAAI,GAAG,QAAQ,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI,GAAG,IAEpF,4CAAC,YAAO,IAAQ,IAAQ,GAAM,GAElC,GACF;AAAA,QAGA,6CAAC,OAAE,UAAU,QAAQ,MAAM,KACxB;AAAA,oBAAU,WACT,4CAAC,UAAK,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,OAAO,IAAI,GAAG,QAAQ,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI,GAAG,MAAM,MAAM,IAEhG,4CAAC,YAAO,IAAQ,IAAQ,GAAM,MAAM,MAAM;AAAA,UAG5C,4CAAC,YAAS,IAAQ,IAAQ,GAAM,IAAQ,IAAQ,SAAS,eAAe,OAAc,MAAY;AAAA,WACpG;AAAA,QAGA,4CAAC,QAAK,IAAQ,IAAQ,GAAM,OAAO,WAAW,MAAY;AAAA;AAAA;AAAA,EAC5D;AAEJ;","names":["palettes100","base","a1","a2"]}
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Avatar.tsx"],"sourcesContent":["export { default as Avatar } from \"./Avatar\";\r\nexport { default } from \"./Avatar\";\r\n","import * as React from \"react\";\r\nimport palettes100 from \"nice-color-palettes\";\r\n\r\nexport type HeadShape = \"circle\" | \"square\";\r\nexport type Variant =\r\n | \"auto\"\r\n | \"plain\"\r\n | \"split\"\r\n | \"swoop\"\r\n | \"diagonal\"\r\n | \"cap\"\r\n | \"crescent\"\r\n | \"band\"\r\n | \"corner\"\r\n | \"ring\"\r\n | \"arc\"\r\n | \"wave\"\r\n | \"half\";\r\nexport type AlignX = \"left\" | \"center\" | \"right\";\r\nexport type AlignY = \"top\" | \"center\" | \"bottom\";\r\n\r\nexport type FaceProps = {\r\n cx: number;\r\n cy: number;\r\n r: number;\r\n color: string;\r\n eyeShape?: \"circle\" | \"ellipse\" | \"line\" | \"wink\" | \"sleepy\" | \"surprised\" | \"random\";\r\n mouthShape?: \"smile\" | \"frown\" | \"flat\" | \"zigzag\" | \"random\";\r\n pupilColor?: string | \"auto\";\r\n eyeShine?: boolean | \"random\";\r\n rand: () => number;\r\n};\r\n\r\nexport type AvatarProps = {\r\n name: string;\r\n size?: number;\r\n pixelSize?: number;\r\n mirrored?: boolean;\r\n bg?: [string, string] | string | \"random\";\r\n headShape?: HeadShape;\r\n alignX?: AlignX;\r\n alignY?: AlignY;\r\n padding?: number;\r\n colors?: string | [string, string] | [string, string, string] | \"random\";\r\n variant?: Variant;\r\n eyeShape?: FaceProps[\"eyeShape\"];\r\n mouthShape?: FaceProps[\"mouthShape\"];\r\n pupilColor?: string | \"auto\";\r\n eyeShine?: boolean;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n title?: string;\r\n};\r\n\r\nfunction cyrb128(str: string) {\r\n let h1 = 1779033703,\r\n h2 = 3144134277,\r\n h3 = 1013904242,\r\n h4 = 2773480762;\r\n for (let i = 0, k; i < str.length; i++) {\r\n k = str.charCodeAt(i);\r\n h1 = h2 ^ Math.imul(h1 ^ k, 597399067);\r\n h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);\r\n h3 = h4 ^ Math.imul(h3 ^ k, 951274213);\r\n h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);\r\n }\r\n h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);\r\n h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);\r\n h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);\r\n h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);\r\n return [(h1 ^ h2 ^ h3 ^ h4) >>> 0, (h2 ^ h1) >>> 0, (h3 ^ h1) >>> 0, (h4 ^ h1) >>> 0];\r\n}\r\nfunction sfc32(a: number, b: number, c: number, d: number) {\r\n return function () {\r\n a >>>= 0;\r\n b >>>= 0;\r\n c >>>= 0;\r\n d >>>= 0;\r\n let t = (a + b) | 0;\r\n a = b ^ (b >>> 9);\r\n b = (c + (c << 3)) | 0;\r\n c = (c << 21) | (c >>> 11);\r\n d = (d + 1) | 0;\r\n t = (t + d) | 0;\r\n c = (c + t) | 0;\r\n return (t >>> 0) / 4294967296;\r\n };\r\n}\r\nfunction rngFromSeed(seed: string) {\r\n const [a, b, c, d] = cyrb128(seed || \"pixelpeeps\");\r\n return sfc32(a, b, c, d);\r\n}\r\nfunction pick<T>(rand: () => number, arr: T[]) {\r\n return arr[Math.floor(rand() * arr.length)];\r\n}\r\n\r\nfunction hexToRgb(hex: string) {\r\n const h = hex.replace(\"#\", \"\");\r\n const full = h.length === 3 ? h.split(\"\").map((c) => c + c).join(\"\") : h;\r\n const n = parseInt(full, 16);\r\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\r\n}\r\nfunction rgbToHex(r: number, g: number, b: number) {\r\n return \"#\" + [r, g, b].map((v) => v.toString(16).padStart(2, \"0\")).join(\"\");\r\n}\r\nfunction shade(hex: string, percent: number) {\r\n const { r, g, b } = hexToRgb(hex);\r\n const t = percent < 0 ? 0 : 255;\r\n const p = Math.abs(percent);\r\n return rgbToHex(\r\n Math.round((t - r) * p) + r,\r\n Math.round((t - g) * p) + g,\r\n Math.round((t - b) * p) + b\r\n );\r\n}\r\nfunction yiq(hex: string) {\r\n const { r, g, b } = hexToRgb(hex);\r\n return (r * 299 + g * 587 + b * 114) / 1000;\r\n}\r\n\r\nconst NICE_PALETTES: string[][] =\r\n palettes100 && Array.isArray(palettes100)\r\n ? (palettes100 as string[][])\r\n : [[\"#73a9ff\", \"#fef3c7\", \"#ffd6a5\", \"#d4b4ff\", \"#a7f3d0\"]];\r\n\r\nfunction resolveBg(rand: () => number, bg?: AvatarProps[\"bg\"]): [string, string] {\r\n if (!bg || bg === \"random\") {\r\n return pick(rand, NICE_PALETTES).slice(0, 2) as [string, string];\r\n }\r\n if (Array.isArray(bg)) return [bg[0], bg[1] ?? bg[0]];\r\n return [shade(bg, 0.12), shade(bg, -0.06)];\r\n}\r\nfunction resolveCharColors(rand: () => number, colors?: AvatarProps[\"colors\"]): [string, string, string] {\r\n if (!colors || colors === \"random\") {\r\n const pal = pick(rand, NICE_PALETTES);\r\n const base = pal[0];\r\n const a1 = pal[1] ?? shade(base, 0.25);\r\n const a2 = pal[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n }\r\n if (typeof colors === \"string\") {\r\n return [colors, shade(colors, 0.25), shade(colors, -0.2)];\r\n }\r\n const base = (colors as string[])[0];\r\n const a1 = (colors as string[])[1] ?? shade(base, 0.25);\r\n const a2 = (colors as string[])[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n}\r\n\r\n// 🌿 Simplified Face: no glasses, no hat, no ears, no freckles, no blush, no open mouth\r\nfunction Face({\r\n cx,\r\n cy,\r\n r,\r\n color,\r\n eyeShape: eyeShapeProp,\r\n mouthShape: mouthShapeProp,\r\n pupilColor,\r\n eyeShine: eyeShineProp,\r\n rand,\r\n}: FaceProps) {\r\n const decide = <T,>(prop: T | \"random\" | undefined, opts: T[]) => {\r\n if (prop === undefined || prop === \"random\") return pick(rand, opts);\r\n return prop;\r\n };\r\n\r\n const eyeShape = decide(eyeShapeProp ?? \"random\", [\"circle\", \"ellipse\", \"line\", \"wink\", \"sleepy\", \"surprised\"]);\r\n const mouthShape = decide(mouthShapeProp ?? \"random\", [\"smile\", \"frown\", \"flat\", \"zigzag\"]);\r\n const eyeShine = decide(eyeShineProp ?? \"random\", [true, false]);\r\n\r\n const eyeOffsetX = r * 0.36;\r\n const eyeOffsetY = r * 0.22;\r\n const eyeR = Math.max(2, r * 0.08);\r\n const pupilR = eyeR * 0.5;\r\n const mouthWidth = r * 0.7;\r\n const mouthLift = r * 0.2;\r\n const mouthStroke = Math.max(1, Math.round(r * 0.06));\r\n\r\n const finalPupilColor = pupilColor && pupilColor !== \"auto\" ? pupilColor : yiq(color) > 150 ? \"#111827\" : \"#ffffff\";\r\n const x0 = cx - mouthWidth / 2;\r\n const x1 = cx + mouthWidth / 2;\r\n const my = cy + mouthLift;\r\n\r\n const mouthPaths = {\r\n smile: `M ${x0} ${my} Q ${cx} ${my - r * 0.2} ${x1} ${my}`,\r\n frown: `M ${x0} ${my} Q ${cx} ${my + r * 0.2} ${x1} ${my}`,\r\n flat: `M ${x0} ${my} L ${x1} ${my}`,\r\n zigzag: (() => {\r\n const segs = 6;\r\n const step = mouthWidth / (segs - 1);\r\n let d = `M ${x0} ${my}`;\r\n for (let i = 1; i < segs; i++) {\r\n const px = x0 + step * i;\r\n const py = my + (i % 2 === 0 ? -r * 0.08 : r * 0.08);\r\n d += ` L ${px} ${py}`;\r\n }\r\n return d;\r\n })(),\r\n };\r\n\r\n const drawEye = (ex: number, ey: number, key: string) => {\r\n switch (eyeShape) {\r\n case \"ellipse\":\r\n return <ellipse key={key} cx={ex} cy={ey} rx={eyeR * 1.1} ry={eyeR * 0.7} fill={color} />;\r\n case \"line\":\r\n return <line key={key} x1={ex - eyeR} y1={ey} x2={ex + eyeR} y2={ey} stroke={color} strokeWidth={eyeR * 0.5} strokeLinecap=\"round\" />;\r\n case \"wink\":\r\n return <line key={key} x1={ex - eyeR} y1={ey} x2={ex + eyeR} y2={ey} stroke={color} strokeWidth={eyeR * 0.5} strokeLinecap=\"round\" />;\r\n case \"sleepy\":\r\n return <ellipse key={key} cx={ex} cy={ey} rx={eyeR * 1.05} ry={eyeR * 0.45} fill={color} />;\r\n case \"surprised\":\r\n return <circle key={key} cx={ex} cy={ey} r={eyeR * 1.1} fill={color} />;\r\n default:\r\n return <circle key={key} cx={ex} cy={ey} r={eyeR} fill={color} />;\r\n }\r\n };\r\n\r\n const leftEye = drawEye(cx - eyeOffsetX, cy - eyeOffsetY, \"le\");\r\n const rightEye = drawEye(cx + eyeOffsetX, cy - eyeOffsetY, \"re\");\r\n\r\n const pupils = (\r\n <>\r\n <circle cx={cx - eyeOffsetX} cy={cy - eyeOffsetY} r={pupilR} fill={finalPupilColor} />\r\n <circle cx={cx + eyeOffsetX} cy={cy - eyeOffsetY} r={pupilR} fill={finalPupilColor} />\r\n </>\r\n );\r\n\r\n const shine = eyeShine ? (\r\n <>\r\n <circle cx={cx - eyeOffsetX - pupilR * 0.4} cy={cy - eyeOffsetY - pupilR * 0.6} r={pupilR * 0.3} fill=\"#fff\" opacity={0.8} />\r\n <circle cx={cx + eyeOffsetX - pupilR * 0.4} cy={cy - eyeOffsetY - pupilR * 0.6} r={pupilR * 0.3} fill=\"#fff\" opacity={0.8} />\r\n </>\r\n ) : null;\r\n\r\n const mouth = <path d={mouthPaths[mouthShape]} stroke={color} strokeWidth={mouthStroke} fill=\"none\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />;\r\n\r\n return (\r\n <>\r\n {leftEye}\r\n {rightEye}\r\n {pupils}\r\n {shine}\r\n {mouth}\r\n </>\r\n );\r\n}\r\n\r\nexport default function Avatar({ name, size = 120, bg = \"random\", colors = \"random\" }: AvatarProps) {\r\n const rand = rngFromSeed(name);\r\n const [bg1, bg2] = resolveBg(rand, bg);\r\n const [base] = resolveCharColors(rand, colors);\r\n const cx = size / 2;\r\n const cy = size / 2;\r\n\r\n return (\r\n <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ borderRadius: \"50%\", background: `linear-gradient(135deg, ${bg1}, ${bg2})` }}>\r\n <Face cx={cx} cy={cy} r={size / 3} color={base} rand={rand} />\r\n </svg>\r\n );\r\n}\r\n"],"mappings":"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","names":["palettes100","base","a1","a2"]}
|
package/dist/index.mjs
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
// src/Avatar.tsx
|
2
|
-
import * as React from "react";
|
3
2
|
import palettes100 from "nice-color-palettes";
|
4
3
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
5
4
|
function cyrb128(str) {
|
@@ -63,13 +62,7 @@ function yiq(hex) {
|
|
63
62
|
const { r, g, b } = hexToRgb(hex);
|
64
63
|
return (r * 299 + g * 587 + b * 114) / 1e3;
|
65
64
|
}
|
66
|
-
|
67
|
-
return yiq(base) > 150 ? "#111827" : "#ffffff";
|
68
|
-
}
|
69
|
-
var NICE_PALETTES = palettes100 && Array.isArray(palettes100) ? palettes100 : [
|
70
|
-
// fallback single palette
|
71
|
-
["#73a9ff", "#fef3c7", "#ffd6a5", "#d4b4ff", "#a7f3d0"]
|
72
|
-
];
|
65
|
+
var NICE_PALETTES = palettes100 && Array.isArray(palettes100) ? palettes100 : [["#73a9ff", "#fef3c7", "#ffd6a5", "#d4b4ff", "#a7f3d0"]];
|
73
66
|
function resolveBg(rand, bg) {
|
74
67
|
if (!bg || bg === "random") {
|
75
68
|
return pick(rand, NICE_PALETTES).slice(0, 2);
|
@@ -93,161 +86,93 @@ function resolveCharColors(rand, colors) {
|
|
93
86
|
const a2 = colors[2] ?? shade(base, -0.2);
|
94
87
|
return [base, a1, a2];
|
95
88
|
}
|
96
|
-
function Face({
|
97
|
-
const eyeOffsetX = r * (0.34 + rand() * 0.06);
|
98
|
-
const eyeOffsetY = r * (0.2 + rand() * 0.06);
|
99
|
-
const eyeR = Math.max(2, Math.round(r * (0.08 + rand() * 0.02)));
|
100
|
-
const mouthWidth = r * (0.7 + rand() * 0.3);
|
101
|
-
const mouthLift = r * (0.18 + rand() * 0.16);
|
102
|
-
const mouthCurve = (rand() - 0.5) * 0.8;
|
103
|
-
const mouthStroke = Math.max(1, Math.round(r * 0.06));
|
104
|
-
const x0 = cx - mouthWidth / 2;
|
105
|
-
const x1 = cx + mouthWidth / 2;
|
106
|
-
const my = cy + mouthLift;
|
107
|
-
const cxQ = cx;
|
108
|
-
const cyQ = my + r * (-0.25 * mouthCurve - 0.1);
|
109
|
-
const d = `M ${x0} ${my} Q ${cxQ} ${cyQ} ${x1} ${my}`;
|
110
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
111
|
-
/* @__PURE__ */ jsx("circle", { cx: cx - eyeOffsetX, cy: cy - eyeOffsetY, r: eyeR, fill: color }),
|
112
|
-
/* @__PURE__ */ jsx("circle", { cx: cx + eyeOffsetX, cy: cy - eyeOffsetY, r: eyeR, fill: color }),
|
113
|
-
/* @__PURE__ */ jsx("path", { d, stroke: color, strokeWidth: mouthStroke, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" })
|
114
|
-
] });
|
115
|
-
}
|
116
|
-
function Overlays({
|
89
|
+
function Face({
|
117
90
|
cx,
|
118
91
|
cy,
|
119
92
|
r,
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
93
|
+
color,
|
94
|
+
eyeShape: eyeShapeProp,
|
95
|
+
mouthShape: mouthShapeProp,
|
96
|
+
pupilColor,
|
97
|
+
eyeShine: eyeShineProp,
|
124
98
|
rand
|
125
99
|
}) {
|
126
|
-
const
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
const
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
return /* @__PURE__ */ 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 });
|
157
|
-
// NEW variant: large half/diagonal cut (looks like attached image)
|
158
|
-
case "half": {
|
159
|
-
const diag = rand() > 0.4;
|
160
|
-
if (diag) {
|
161
|
-
return /* @__PURE__ */ jsx("polygon", { points: `${x0},${y0} ${x1},${y0} ${x1},${cy + (left ? r * 0.1 : -r * 0.1)}`, fill: a1 });
|
162
|
-
} else {
|
163
|
-
const offset = left ? -r * 0.18 : r * 0.18;
|
164
|
-
return /* @__PURE__ */ jsx("circle", { cx: cx + offset, cy, r: r * 0.95, fill: a1 });
|
100
|
+
const decide = (prop, opts) => {
|
101
|
+
if (prop === void 0 || prop === "random") return pick(rand, opts);
|
102
|
+
return prop;
|
103
|
+
};
|
104
|
+
const eyeShape = decide(eyeShapeProp ?? "random", ["circle", "ellipse", "line", "wink", "sleepy", "surprised"]);
|
105
|
+
const mouthShape = decide(mouthShapeProp ?? "random", ["smile", "frown", "flat", "zigzag"]);
|
106
|
+
const eyeShine = decide(eyeShineProp ?? "random", [true, false]);
|
107
|
+
const eyeOffsetX = r * 0.36;
|
108
|
+
const eyeOffsetY = r * 0.22;
|
109
|
+
const eyeR = Math.max(2, r * 0.08);
|
110
|
+
const pupilR = eyeR * 0.5;
|
111
|
+
const mouthWidth = r * 0.7;
|
112
|
+
const mouthLift = r * 0.2;
|
113
|
+
const mouthStroke = Math.max(1, Math.round(r * 0.06));
|
114
|
+
const finalPupilColor = pupilColor && pupilColor !== "auto" ? pupilColor : yiq(color) > 150 ? "#111827" : "#ffffff";
|
115
|
+
const x0 = cx - mouthWidth / 2;
|
116
|
+
const x1 = cx + mouthWidth / 2;
|
117
|
+
const my = cy + mouthLift;
|
118
|
+
const mouthPaths = {
|
119
|
+
smile: `M ${x0} ${my} Q ${cx} ${my - r * 0.2} ${x1} ${my}`,
|
120
|
+
frown: `M ${x0} ${my} Q ${cx} ${my + r * 0.2} ${x1} ${my}`,
|
121
|
+
flat: `M ${x0} ${my} L ${x1} ${my}`,
|
122
|
+
zigzag: (() => {
|
123
|
+
const segs = 6;
|
124
|
+
const step = mouthWidth / (segs - 1);
|
125
|
+
let d = `M ${x0} ${my}`;
|
126
|
+
for (let i = 1; i < segs; i++) {
|
127
|
+
const px = x0 + step * i;
|
128
|
+
const py = my + (i % 2 === 0 ? -r * 0.08 : r * 0.08);
|
129
|
+
d += ` L ${px} ${py}`;
|
165
130
|
}
|
131
|
+
return d;
|
132
|
+
})()
|
133
|
+
};
|
134
|
+
const drawEye = (ex, ey, key) => {
|
135
|
+
switch (eyeShape) {
|
136
|
+
case "ellipse":
|
137
|
+
return /* @__PURE__ */ jsx("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.1, ry: eyeR * 0.7, fill: color }, key);
|
138
|
+
case "line":
|
139
|
+
return /* @__PURE__ */ jsx("line", { x1: ex - eyeR, y1: ey, x2: ex + eyeR, y2: ey, stroke: color, strokeWidth: eyeR * 0.5, strokeLinecap: "round" }, key);
|
140
|
+
case "wink":
|
141
|
+
return /* @__PURE__ */ jsx("line", { x1: ex - eyeR, y1: ey, x2: ex + eyeR, y2: ey, stroke: color, strokeWidth: eyeR * 0.5, strokeLinecap: "round" }, key);
|
142
|
+
case "sleepy":
|
143
|
+
return /* @__PURE__ */ jsx("ellipse", { cx: ex, cy: ey, rx: eyeR * 1.05, ry: eyeR * 0.45, fill: color }, key);
|
144
|
+
case "surprised":
|
145
|
+
return /* @__PURE__ */ jsx("circle", { cx: ex, cy: ey, r: eyeR * 1.1, fill: color }, key);
|
146
|
+
default:
|
147
|
+
return /* @__PURE__ */ jsx("circle", { cx: ex, cy: ey, r: eyeR, fill: color }, key);
|
166
148
|
}
|
167
|
-
|
168
|
-
|
169
|
-
|
149
|
+
};
|
150
|
+
const leftEye = drawEye(cx - eyeOffsetX, cy - eyeOffsetY, "le");
|
151
|
+
const rightEye = drawEye(cx + eyeOffsetX, cy - eyeOffsetY, "re");
|
152
|
+
const pupils = /* @__PURE__ */ jsxs(Fragment, { children: [
|
153
|
+
/* @__PURE__ */ jsx("circle", { cx: cx - eyeOffsetX, cy: cy - eyeOffsetY, r: pupilR, fill: finalPupilColor }),
|
154
|
+
/* @__PURE__ */ jsx("circle", { cx: cx + eyeOffsetX, cy: cy - eyeOffsetY, r: pupilR, fill: finalPupilColor })
|
155
|
+
] });
|
156
|
+
const shine = eyeShine ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
157
|
+
/* @__PURE__ */ jsx("circle", { cx: cx - eyeOffsetX - pupilR * 0.4, cy: cy - eyeOffsetY - pupilR * 0.6, r: pupilR * 0.3, fill: "#fff", opacity: 0.8 }),
|
158
|
+
/* @__PURE__ */ jsx("circle", { cx: cx + eyeOffsetX - pupilR * 0.4, cy: cy - eyeOffsetY - pupilR * 0.6, r: pupilR * 0.3, fill: "#fff", opacity: 0.8 })
|
159
|
+
] }) : null;
|
160
|
+
const mouth = /* @__PURE__ */ jsx("path", { d: mouthPaths[mouthShape], stroke: color, strokeWidth: mouthStroke, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" });
|
161
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
162
|
+
leftEye,
|
163
|
+
rightEye,
|
164
|
+
pupils,
|
165
|
+
shine,
|
166
|
+
mouth
|
167
|
+
] });
|
170
168
|
}
|
171
|
-
function Avatar({
|
172
|
-
name
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
headShape,
|
179
|
-
square,
|
180
|
-
alignX = "center",
|
181
|
-
alignY = "center",
|
182
|
-
padding,
|
183
|
-
variant = "auto",
|
184
|
-
className,
|
185
|
-
style,
|
186
|
-
title
|
187
|
-
}) {
|
188
|
-
const shape = headShape ?? (square ? "square" : "circle");
|
189
|
-
const rand = React.useMemo(() => rngFromSeed(String(name)), [name]);
|
190
|
-
const [bg1, bg2] = React.useMemo(() => resolveBg(rand, bg), [rand, bg]);
|
191
|
-
const [base, a1, a2] = React.useMemo(() => resolveCharColors(rand, colors), [rand, colors]);
|
192
|
-
const faceColor = bestFeatureColor(base);
|
193
|
-
const grid = Math.max(6, Math.floor(size / pixelSize));
|
194
|
-
const tile = Math.ceil(size / grid);
|
195
|
-
const autoPad = Math.max(4, Math.round(size * (0.06 + rand() * 0.02)));
|
196
|
-
const pad = padding ?? autoPad;
|
197
|
-
const baseR = Math.floor(size * (0.36 + rand() * 0.04));
|
198
|
-
const maxR = Math.floor(size / 2 - pad);
|
199
|
-
const r = Math.max(8, Math.min(baseR, maxR));
|
200
|
-
let cx = size / 2;
|
201
|
-
let cy = size / 2;
|
202
|
-
if (alignX === "left") cx = r + pad;
|
203
|
-
if (alignX === "right") cx = size - (r + pad);
|
204
|
-
if (alignY === "top") cy = r + pad;
|
205
|
-
if (alignY === "bottom") cy = size - (r + pad);
|
206
|
-
const cells = [];
|
207
|
-
const cols = mirrored ? Math.ceil(grid / 2) : grid;
|
208
|
-
for (let y = 0; y < grid; y++) {
|
209
|
-
for (let x = 0; x < cols; x++) {
|
210
|
-
const use = rand() > 0.5;
|
211
|
-
const fill = use ? bg1 : bg2;
|
212
|
-
const px = x * tile;
|
213
|
-
const py = y * tile;
|
214
|
-
cells.push(/* @__PURE__ */ jsx("rect", { x: px, y: py, width: tile, height: tile, fill }, `L${x},${y}`));
|
215
|
-
if (mirrored) {
|
216
|
-
const mx = grid - x - 1;
|
217
|
-
const mpx = mx * tile;
|
218
|
-
cells.push(/* @__PURE__ */ jsx("rect", { x: mpx, y: py, width: tile, height: tile, fill }, `R${mx},${y}`));
|
219
|
-
}
|
220
|
-
}
|
221
|
-
}
|
222
|
-
const variants = ["split", "swoop", "diagonal", "cap", "crescent", "band", "corner", "ring", "arc", "wave", "plain", "half"];
|
223
|
-
const chosenVariant = variant === "auto" ? pick(rand, variants) : variant;
|
224
|
-
const clipId = React.useMemo(() => {
|
225
|
-
const [a, b, c, d] = cyrb128(`pp-shape-${name}-${shape}-${r}`);
|
226
|
-
return `pps-${a.toString(16)}${b.toString(16)}${c.toString(16)}${d.toString(16)}`;
|
227
|
-
}, [name, shape, r]);
|
228
|
-
return /* @__PURE__ */ jsxs(
|
229
|
-
"svg",
|
230
|
-
{
|
231
|
-
width: size,
|
232
|
-
height: size,
|
233
|
-
viewBox: `0 0 ${size} ${size}`,
|
234
|
-
xmlns: "http://www.w3.org/2000/svg",
|
235
|
-
role: "img",
|
236
|
-
"aria-label": title ?? `Avatar ${name}`,
|
237
|
-
className,
|
238
|
-
style: { display: "inline-block", borderRadius: 12, ...style },
|
239
|
-
children: [
|
240
|
-
/* @__PURE__ */ jsx("rect", { width: size, height: size, fill: bg1 }),
|
241
|
-
cells,
|
242
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: clipId, children: shape === "square" ? /* @__PURE__ */ jsx("rect", { x: cx - r, y: cy - r, width: 2 * r, height: 2 * r, rx: Math.max(4, r * 0.12) }) : /* @__PURE__ */ jsx("circle", { cx, cy, r }) }) }),
|
243
|
-
/* @__PURE__ */ jsxs("g", { clipPath: `url(#${clipId})`, children: [
|
244
|
-
shape === "square" ? /* @__PURE__ */ jsx("rect", { x: cx - r, y: cy - r, width: 2 * r, height: 2 * r, rx: Math.max(4, r * 0.12), fill: base }) : /* @__PURE__ */ jsx("circle", { cx, cy, r, fill: base }),
|
245
|
-
/* @__PURE__ */ jsx(Overlays, { cx, cy, r, a1, a2, variant: chosenVariant, shape, rand })
|
246
|
-
] }),
|
247
|
-
/* @__PURE__ */ jsx(Face, { cx, cy, r, color: faceColor, rand })
|
248
|
-
]
|
249
|
-
}
|
250
|
-
);
|
169
|
+
function Avatar({ name, size = 120, bg = "random", colors = "random" }) {
|
170
|
+
const rand = rngFromSeed(name);
|
171
|
+
const [bg1, bg2] = resolveBg(rand, bg);
|
172
|
+
const [base] = resolveCharColors(rand, colors);
|
173
|
+
const cx = size / 2;
|
174
|
+
const cy = size / 2;
|
175
|
+
return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, style: { borderRadius: "50%", background: `linear-gradient(135deg, ${bg1}, ${bg2})` }, children: /* @__PURE__ */ jsx(Face, { cx, cy, r: size / 3, color: base, rand }) });
|
251
176
|
}
|
252
177
|
export {
|
253
178
|
Avatar,
|
package/dist/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/Avatar.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport palettes100 from \"nice-color-palettes\";\r\nexport type HeadShape = \"circle\" | \"square\";\r\nexport type Variant =\r\n | \"auto\"\r\n | \"plain\"\r\n | \"split\"\r\n | \"swoop\"\r\n | \"diagonal\"\r\n | \"cap\"\r\n | \"crescent\"\r\n | \"band\"\r\n | \"corner\"\r\n | \"ring\"\r\n | \"arc\"\r\n | \"wave\"\r\n | \"half\"; // <-- new variant\r\nexport type AlignX = \"left\" | \"center\" | \"right\";\r\nexport type AlignY = \"top\" | \"center\" | \"bottom\";\r\n\r\nexport type AvatarProps = {\r\n name: string;\r\n\r\n // pixel background\r\n size?: number;\r\n pixelSize?: number;\r\n mirrored?: boolean;\r\n bg?: [string, string] | string | \"random\";\r\n\r\n // character controls\r\n headShape?: HeadShape;\r\n square?: boolean; // deprecated\r\n alignX?: AlignX;\r\n alignY?: AlignY;\r\n padding?: number;\r\n\r\n colors?: string | [string, string] | [string, string, string] | \"random\";\r\n variant?: Variant;\r\n\r\n // styling/a11y\r\n className?: string;\r\n style?: React.CSSProperties;\r\n title?: string;\r\n};\r\n\r\n//\r\n// Deterministic RNG (seeded)\r\n//\r\nfunction cyrb128(str: string) {\r\n let h1 = 1779033703, h2 = 3144134277, h3 = 1013904242, h4 = 2773480762;\r\n for (let i = 0, k; i < str.length; i++) {\r\n k = str.charCodeAt(i);\r\n h1 = h2 ^ Math.imul(h1 ^ k, 597399067);\r\n h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);\r\n h3 = h4 ^ Math.imul(h3 ^ k, 951274213);\r\n h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);\r\n }\r\n h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);\r\n h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);\r\n h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);\r\n h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);\r\n return [(h1 ^ h2 ^ h3 ^ h4) >>> 0, (h2 ^ h1) >>> 0, (h3 ^ h1) >>> 0, (h4 ^ h1) >>> 0];\r\n}\r\nfunction sfc32(a: number, b: number, c: number, d: number) {\r\n return function () {\r\n a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;\r\n let t = (a + b) | 0;\r\n a = b ^ (b >>> 9);\r\n b = (c + (c << 3)) | 0;\r\n c = (c << 21) | (c >>> 11);\r\n d = (d + 1) | 0;\r\n t = (t + d) | 0;\r\n c = (c + t) | 0;\r\n return (t >>> 0) / 4294967296;\r\n };\r\n}\r\nfunction rngFromSeed(seed: string) {\r\n const [a, b, c, d] = cyrb128(seed || \"pixelpeeps\");\r\n return sfc32(a, b, c, d);\r\n}\r\nfunction pick<T>(rand: () => number, arr: T[]) {\r\n return arr[Math.floor(rand() * arr.length)];\r\n}\r\n\r\n//\r\n// Color helpers\r\n//\r\nfunction hexToRgb(hex: string) {\r\n const h = hex.replace(\"#\", \"\");\r\n const full = h.length === 3 ? h.split(\"\").map(c => c + c).join(\"\") : h;\r\n const n = parseInt(full, 16);\r\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\r\n}\r\nfunction rgbToHex(r: number, g: number, b: number) {\r\n return \"#\" + [r, g, b].map(v => v.toString(16).padStart(2, \"0\")).join(\"\");\r\n}\r\nfunction shade(hex: string, percent: number) {\r\n const { r, g, b } = hexToRgb(hex);\r\n const t = percent < 0 ? 0 : 255;\r\n const p = Math.abs(percent);\r\n return rgbToHex(\r\n Math.round((t - r) * p) + r,\r\n Math.round((t - g) * p) + g,\r\n Math.round((t - b) * p) + b\r\n );\r\n}\r\nfunction yiq(hex: string) {\r\n const { r, g, b } = hexToRgb(hex);\r\n return (r * 299 + g * 587 + b * 114) / 1000;\r\n}\r\nfunction bestFeatureColor(base: string) {\r\n return yiq(base) > 150 ? \"#111827\" : \"#ffffff\";\r\n}\r\n\r\n//\r\n// Palettes: use nice-color-palettes (top 100)\r\n//\r\nconst NICE_PALETTES: string[][] = (palettes100 && Array.isArray(palettes100)) ? palettes100 as string[][] : [\r\n // fallback single palette\r\n [\"#73a9ff\", \"#fef3c7\", \"#ffd6a5\", \"#d4b4ff\", \"#a7f3d0\"]\r\n];\r\n\r\nfunction resolveBg(rand: () => number, bg?: AvatarProps[\"bg\"]): [string, string] {\r\n if (!bg || bg === \"random\") {\r\n return pick(rand, NICE_PALETTES).slice(0, 2) as [string, string];\r\n }\r\n if (Array.isArray(bg)) return [bg[0], bg[1] ?? bg[0]];\r\n // single hex -> auto shade pair\r\n return [shade(bg, 0.12), shade(bg, -0.06)];\r\n}\r\nfunction resolveCharColors(rand: () => number, colors?: AvatarProps[\"colors\"]): [string, string, string] {\r\n if (!colors || colors === \"random\") {\r\n const pal = pick(rand, NICE_PALETTES);\r\n const base = pal[0];\r\n const a1 = pal[1] ?? shade(base, 0.25);\r\n const a2 = pal[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n }\r\n if (typeof colors === \"string\") {\r\n return [colors, shade(colors, 0.25), shade(colors, -0.2)];\r\n }\r\n const base = (colors as string[])[0];\r\n const a1 = (colors as string[])[1] ?? shade(base, 0.25);\r\n const a2 = (colors as string[])[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n}\r\n\r\n//\r\n// Small face subcomponent: parametric mouth (fixed nice curve)\r\n//\r\nfunction Face({ cx, cy, r, color, rand }: { cx: number; cy: number; r: number; color: string; rand: () => number }) {\r\n const eyeOffsetX = r * (0.34 + rand() * 0.06); // small variation from seed\r\n const eyeOffsetY = r * (0.20 + rand() * 0.06);\r\n const eyeR = Math.max(2, Math.round(r * (0.08 + rand() * 0.02)));\r\n // Parametric mouth values from seed:\r\n const mouthWidth = r * (0.7 + rand() * 0.3); // 70-100%\r\n const mouthLift = r * (0.18 + rand() * 0.16); // 18-34%\r\n const mouthCurve = (rand() - 0.5) * 0.8; // -0.4..0.4 adjusts curvature (smile vs big smile)\r\n const mouthStroke = Math.max(1, Math.round(r * 0.06));\r\n\r\n // compute coordinates\r\n const x0 = cx - mouthWidth / 2;\r\n const x1 = cx + mouthWidth / 2;\r\n const my = cy + mouthLift;\r\n\r\n // quadratic control point to make a smooth curve (smile)\r\n const cxQ = cx;\r\n const cyQ = my + r * (-0.25 * mouthCurve - 0.1); // move control up or down by mouthCurve\r\n\r\n const d = `M ${x0} ${my} Q ${cxQ} ${cyQ} ${x1} ${my}`;\r\n\r\n return (\r\n <>\r\n <circle cx={cx - eyeOffsetX} cy={cy - eyeOffsetY} r={eyeR} fill={color} />\r\n <circle cx={cx + eyeOffsetX} cy={cy - eyeOffsetY} r={eyeR} fill={color} />\r\n <path d={d} stroke={color} strokeWidth={mouthStroke} fill=\"none\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\r\n </>\r\n );\r\n}\r\n\r\n//\r\n// Overlays (variants) including new `half` variant\r\n//\r\nfunction Overlays({\r\n cx, cy, r, a1, a2, variant, shape, rand\r\n}: {\r\n cx: number; cy: number; r: number;\r\n a1: string; a2: string;\r\n variant: Exclude<Variant, \"auto\">;\r\n shape: HeadShape;\r\n rand: () => number;\r\n}) {\r\n const x0 = cx - r, y0 = cy - r, x1 = cx + r, y1 = cy + r;\r\n\r\n // deterministic options\r\n const left = rand() > 0.5;\r\n const tlbr = rand() > 0.5;\r\n const horiz = rand() > 0.5;\r\n const cornerTL = rand() > 0.5;\r\n\r\n switch (variant) {\r\n case \"plain\": return null;\r\n\r\n case \"split\":\r\n return <rect x={left ? x0 : cx} y={y0} width={r} height={2 * r} fill={a1} />;\r\n\r\n case \"diagonal\":\r\n return tlbr ? (\r\n <polygon points={`${x0},${y0} ${x1},${y0} ${x1},${y1}`} fill={a1} />\r\n ) : (\r\n <polygon points={`${x0},${y0} ${x0},${y1} ${x1},${y1}`} fill={a1} />\r\n );\r\n\r\n case \"cap\":\r\n return (\r\n <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} />\r\n );\r\n\r\n case \"swoop\":\r\n return (\r\n <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} />\r\n );\r\n\r\n case \"crescent\":\r\n return (\r\n <>\r\n <circle cx={left ? cx - r * 0.55 : cx + r * 0.55} cy={cy} r={r * 0.95} fill={a2} />\r\n <circle cx={left ? cx - r * 0.52 : cx + r * 0.52} cy={cy} r={r * 0.75} fill=\"transparent\" stroke={shade(a2, -0.25)} strokeWidth={r * 0.08} />\r\n </>\r\n );\r\n\r\n case \"band\":\r\n return horiz ? (\r\n <rect x={x0} y={cy - r * 0.35} width={2 * r} height={r * 0.5} fill={a1} />\r\n ) : (\r\n <rect x={cx - r * 0.35} y={y0} width={r * 0.5} height={2 * r} fill={a1} />\r\n );\r\n\r\n case \"corner\":\r\n return cornerTL ? (\r\n <polygon points={`${x0},${y0} ${x0 + r * 0.9},${y0} ${x0},${y0 + r * 0.9}`} fill={a1} />\r\n ) : (\r\n <polygon points={`${x1},${y0} ${x1 - r * 0.9},${y0} ${x1},${y0 + r * 0.9}`} fill={a1} />\r\n );\r\n\r\n case \"ring\":\r\n return shape === \"circle\" ? (\r\n <circle cx={cx} cy={cy} r={r * 0.86} fill=\"none\" stroke={a1} strokeWidth={r * 0.18} />\r\n ) : (\r\n <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} />\r\n );\r\n\r\n case \"arc\":\r\n return <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} />;\r\n\r\n case \"wave\":\r\n return <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} />;\r\n\r\n // NEW variant: large half/diagonal cut (looks like attached image)\r\n case \"half\": {\r\n // choose diag or simple half using rand\r\n const diag = rand() > 0.4;\r\n if (diag) {\r\n // diagonal wedge\r\n return <polygon points={`${x0},${y0} ${x1},${y0} ${x1},${cy + (left ? r * 0.1 : -r * 0.1)}`} fill={a1} />;\r\n } else {\r\n // simple semicircle overlay offset to left/right for crescent effect\r\n const offset = left ? -r * 0.18 : r * 0.18;\r\n return <circle cx={cx + offset} cy={cy} r={r * 0.95} fill={a1} />;\r\n }\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\n//\r\n// Main component\r\n//\r\nexport default function Avatar({\r\n name,\r\n size = 128,\r\n pixelSize = 12,\r\n mirrored = true,\r\n bg,\r\n colors,\r\n headShape,\r\n square,\r\n alignX = \"center\",\r\n alignY = \"center\",\r\n padding,\r\n variant = \"auto\",\r\n className,\r\n style,\r\n title,\r\n}: AvatarProps) {\r\n const shape: HeadShape = headShape ?? (square ? \"square\" : \"circle\");\r\n // single RNG for everything derived from seed (deterministic)\r\n const rand = React.useMemo(() => rngFromSeed(String(name)), [name]);\r\n\r\n // background and character colors chosen from nice palettes\r\n const [bg1, bg2] = React.useMemo(() => resolveBg(rand, bg), [rand, bg]);\r\n const [base, a1, a2] = React.useMemo(() => resolveCharColors(rand, colors), [rand, colors]);\r\n const faceColor = bestFeatureColor(base);\r\n\r\n // Pixel grid\r\n const grid = Math.max(6, Math.floor(size / pixelSize));\r\n const tile = Math.ceil(size / grid);\r\n\r\n // geometry/calculations (all derived from rand)\r\n const autoPad = Math.max(4, Math.round(size * (0.06 + rand() * 0.02)));\r\n const pad = padding ?? autoPad;\r\n const baseR = Math.floor(size * (0.36 + rand() * 0.04)); // slight variation\r\n const maxR = Math.floor(size / 2 - pad);\r\n const r = Math.max(8, Math.min(baseR, maxR));\r\n\r\n let cx = size / 2;\r\n let cy = size / 2;\r\n if (alignX === \"left\") cx = r + pad;\r\n if (alignX === \"right\") cx = size - (r + pad);\r\n if (alignY === \"top\") cy = r + pad;\r\n if (alignY === \"bottom\") cy = size - (r + pad);\r\n\r\n // Pixel pattern generation -> uses rand sequentially; deterministic for seed\r\n const cells: React.ReactElement[] = [];\r\n const cols = mirrored ? Math.ceil(grid / 2) : grid;\r\n for (let y = 0; y < grid; y++) {\r\n for (let x = 0; x < cols; x++) {\r\n const use = rand() > 0.5;\r\n const fill = use ? bg1 : bg2;\r\n const px = x * tile;\r\n const py = y * tile;\r\n cells.push(<rect key={`L${x},${y}`} x={px} y={py} width={tile} height={tile} fill={fill} />);\r\n if (mirrored) {\r\n const mx = grid - x - 1;\r\n const mpx = mx * tile;\r\n cells.push(<rect key={`R${mx},${y}`} x={mpx} y={py} width={tile} height={tile} fill={fill} />);\r\n }\r\n }\r\n }\r\n\r\n // pick variant deterministically\r\n const variants: Exclude<Variant, \"auto\">[] = [\"split\", \"swoop\", \"diagonal\", \"cap\", \"crescent\", \"band\", \"corner\", \"ring\", \"arc\", \"wave\", \"plain\", \"half\"];\r\n const chosenVariant: Exclude<Variant, \"auto\"> = variant === \"auto\" ? pick(rand, variants) : (variant as Exclude<Variant, \"auto\">);\r\n\r\n // clip path id (stable-ish)\r\n const clipId = React.useMemo(() => {\r\n const [a, b, c, d] = cyrb128(`pp-shape-${name}-${shape}-${r}`);\r\n return `pps-${a.toString(16)}${b.toString(16)}${c.toString(16)}${d.toString(16)}`;\r\n }, [name, shape, r]);\r\n\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox={`0 0 ${size} ${size}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n role=\"img\"\r\n aria-label={title ?? `Avatar ${name}`}\r\n className={className}\r\n style={{ display: \"inline-block\", borderRadius: 12, ...style }}\r\n >\r\n {/* background grid */}\r\n <rect width={size} height={size} fill={bg1} />\r\n {cells}\r\n\r\n <defs>\r\n <clipPath id={clipId}>\r\n {shape === \"square\" ? (\r\n <rect x={cx - r} y={cy - r} width={2 * r} height={2 * r} rx={Math.max(4, r * 0.12)} />\r\n ) : (\r\n <circle cx={cx} cy={cy} r={r} />\r\n )}\r\n </clipPath>\r\n </defs>\r\n\r\n {/* head + overlays */}\r\n <g clipPath={`url(#${clipId})`}>\r\n {shape === \"square\" ? (\r\n <rect x={cx - r} y={cy - r} width={2 * r} height={2 * r} rx={Math.max(4, r * 0.12)} fill={base} />\r\n ) : (\r\n <circle cx={cx} cy={cy} r={r} fill={base} />\r\n )}\r\n\r\n <Overlays cx={cx} cy={cy} r={r} a1={a1} a2={a2} variant={chosenVariant} shape={shape} rand={rand} />\r\n </g>\r\n\r\n {/* facial features */}\r\n <Face cx={cx} cy={cy} r={r} color={faceColor} rand={rand} />\r\n </svg>\r\n );\r\n}\r\n"],"mappings":"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","names":["base","a1","a2"]}
|
1
|
+
{"version":3,"sources":["../src/Avatar.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport palettes100 from \"nice-color-palettes\";\r\n\r\nexport type HeadShape = \"circle\" | \"square\";\r\nexport type Variant =\r\n | \"auto\"\r\n | \"plain\"\r\n | \"split\"\r\n | \"swoop\"\r\n | \"diagonal\"\r\n | \"cap\"\r\n | \"crescent\"\r\n | \"band\"\r\n | \"corner\"\r\n | \"ring\"\r\n | \"arc\"\r\n | \"wave\"\r\n | \"half\";\r\nexport type AlignX = \"left\" | \"center\" | \"right\";\r\nexport type AlignY = \"top\" | \"center\" | \"bottom\";\r\n\r\nexport type FaceProps = {\r\n cx: number;\r\n cy: number;\r\n r: number;\r\n color: string;\r\n eyeShape?: \"circle\" | \"ellipse\" | \"line\" | \"wink\" | \"sleepy\" | \"surprised\" | \"random\";\r\n mouthShape?: \"smile\" | \"frown\" | \"flat\" | \"zigzag\" | \"random\";\r\n pupilColor?: string | \"auto\";\r\n eyeShine?: boolean | \"random\";\r\n rand: () => number;\r\n};\r\n\r\nexport type AvatarProps = {\r\n name: string;\r\n size?: number;\r\n pixelSize?: number;\r\n mirrored?: boolean;\r\n bg?: [string, string] | string | \"random\";\r\n headShape?: HeadShape;\r\n alignX?: AlignX;\r\n alignY?: AlignY;\r\n padding?: number;\r\n colors?: string | [string, string] | [string, string, string] | \"random\";\r\n variant?: Variant;\r\n eyeShape?: FaceProps[\"eyeShape\"];\r\n mouthShape?: FaceProps[\"mouthShape\"];\r\n pupilColor?: string | \"auto\";\r\n eyeShine?: boolean;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n title?: string;\r\n};\r\n\r\nfunction cyrb128(str: string) {\r\n let h1 = 1779033703,\r\n h2 = 3144134277,\r\n h3 = 1013904242,\r\n h4 = 2773480762;\r\n for (let i = 0, k; i < str.length; i++) {\r\n k = str.charCodeAt(i);\r\n h1 = h2 ^ Math.imul(h1 ^ k, 597399067);\r\n h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);\r\n h3 = h4 ^ Math.imul(h3 ^ k, 951274213);\r\n h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);\r\n }\r\n h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);\r\n h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);\r\n h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);\r\n h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);\r\n return [(h1 ^ h2 ^ h3 ^ h4) >>> 0, (h2 ^ h1) >>> 0, (h3 ^ h1) >>> 0, (h4 ^ h1) >>> 0];\r\n}\r\nfunction sfc32(a: number, b: number, c: number, d: number) {\r\n return function () {\r\n a >>>= 0;\r\n b >>>= 0;\r\n c >>>= 0;\r\n d >>>= 0;\r\n let t = (a + b) | 0;\r\n a = b ^ (b >>> 9);\r\n b = (c + (c << 3)) | 0;\r\n c = (c << 21) | (c >>> 11);\r\n d = (d + 1) | 0;\r\n t = (t + d) | 0;\r\n c = (c + t) | 0;\r\n return (t >>> 0) / 4294967296;\r\n };\r\n}\r\nfunction rngFromSeed(seed: string) {\r\n const [a, b, c, d] = cyrb128(seed || \"pixelpeeps\");\r\n return sfc32(a, b, c, d);\r\n}\r\nfunction pick<T>(rand: () => number, arr: T[]) {\r\n return arr[Math.floor(rand() * arr.length)];\r\n}\r\n\r\nfunction hexToRgb(hex: string) {\r\n const h = hex.replace(\"#\", \"\");\r\n const full = h.length === 3 ? h.split(\"\").map((c) => c + c).join(\"\") : h;\r\n const n = parseInt(full, 16);\r\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\r\n}\r\nfunction rgbToHex(r: number, g: number, b: number) {\r\n return \"#\" + [r, g, b].map((v) => v.toString(16).padStart(2, \"0\")).join(\"\");\r\n}\r\nfunction shade(hex: string, percent: number) {\r\n const { r, g, b } = hexToRgb(hex);\r\n const t = percent < 0 ? 0 : 255;\r\n const p = Math.abs(percent);\r\n return rgbToHex(\r\n Math.round((t - r) * p) + r,\r\n Math.round((t - g) * p) + g,\r\n Math.round((t - b) * p) + b\r\n );\r\n}\r\nfunction yiq(hex: string) {\r\n const { r, g, b } = hexToRgb(hex);\r\n return (r * 299 + g * 587 + b * 114) / 1000;\r\n}\r\n\r\nconst NICE_PALETTES: string[][] =\r\n palettes100 && Array.isArray(palettes100)\r\n ? (palettes100 as string[][])\r\n : [[\"#73a9ff\", \"#fef3c7\", \"#ffd6a5\", \"#d4b4ff\", \"#a7f3d0\"]];\r\n\r\nfunction resolveBg(rand: () => number, bg?: AvatarProps[\"bg\"]): [string, string] {\r\n if (!bg || bg === \"random\") {\r\n return pick(rand, NICE_PALETTES).slice(0, 2) as [string, string];\r\n }\r\n if (Array.isArray(bg)) return [bg[0], bg[1] ?? bg[0]];\r\n return [shade(bg, 0.12), shade(bg, -0.06)];\r\n}\r\nfunction resolveCharColors(rand: () => number, colors?: AvatarProps[\"colors\"]): [string, string, string] {\r\n if (!colors || colors === \"random\") {\r\n const pal = pick(rand, NICE_PALETTES);\r\n const base = pal[0];\r\n const a1 = pal[1] ?? shade(base, 0.25);\r\n const a2 = pal[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n }\r\n if (typeof colors === \"string\") {\r\n return [colors, shade(colors, 0.25), shade(colors, -0.2)];\r\n }\r\n const base = (colors as string[])[0];\r\n const a1 = (colors as string[])[1] ?? shade(base, 0.25);\r\n const a2 = (colors as string[])[2] ?? shade(base, -0.2);\r\n return [base, a1, a2];\r\n}\r\n\r\n// 🌿 Simplified Face: no glasses, no hat, no ears, no freckles, no blush, no open mouth\r\nfunction Face({\r\n cx,\r\n cy,\r\n r,\r\n color,\r\n eyeShape: eyeShapeProp,\r\n mouthShape: mouthShapeProp,\r\n pupilColor,\r\n eyeShine: eyeShineProp,\r\n rand,\r\n}: FaceProps) {\r\n const decide = <T,>(prop: T | \"random\" | undefined, opts: T[]) => {\r\n if (prop === undefined || prop === \"random\") return pick(rand, opts);\r\n return prop;\r\n };\r\n\r\n const eyeShape = decide(eyeShapeProp ?? \"random\", [\"circle\", \"ellipse\", \"line\", \"wink\", \"sleepy\", \"surprised\"]);\r\n const mouthShape = decide(mouthShapeProp ?? \"random\", [\"smile\", \"frown\", \"flat\", \"zigzag\"]);\r\n const eyeShine = decide(eyeShineProp ?? \"random\", [true, false]);\r\n\r\n const eyeOffsetX = r * 0.36;\r\n const eyeOffsetY = r * 0.22;\r\n const eyeR = Math.max(2, r * 0.08);\r\n const pupilR = eyeR * 0.5;\r\n const mouthWidth = r * 0.7;\r\n const mouthLift = r * 0.2;\r\n const mouthStroke = Math.max(1, Math.round(r * 0.06));\r\n\r\n const finalPupilColor = pupilColor && pupilColor !== \"auto\" ? pupilColor : yiq(color) > 150 ? \"#111827\" : \"#ffffff\";\r\n const x0 = cx - mouthWidth / 2;\r\n const x1 = cx + mouthWidth / 2;\r\n const my = cy + mouthLift;\r\n\r\n const mouthPaths = {\r\n smile: `M ${x0} ${my} Q ${cx} ${my - r * 0.2} ${x1} ${my}`,\r\n frown: `M ${x0} ${my} Q ${cx} ${my + r * 0.2} ${x1} ${my}`,\r\n flat: `M ${x0} ${my} L ${x1} ${my}`,\r\n zigzag: (() => {\r\n const segs = 6;\r\n const step = mouthWidth / (segs - 1);\r\n let d = `M ${x0} ${my}`;\r\n for (let i = 1; i < segs; i++) {\r\n const px = x0 + step * i;\r\n const py = my + (i % 2 === 0 ? -r * 0.08 : r * 0.08);\r\n d += ` L ${px} ${py}`;\r\n }\r\n return d;\r\n })(),\r\n };\r\n\r\n const drawEye = (ex: number, ey: number, key: string) => {\r\n switch (eyeShape) {\r\n case \"ellipse\":\r\n return <ellipse key={key} cx={ex} cy={ey} rx={eyeR * 1.1} ry={eyeR * 0.7} fill={color} />;\r\n case \"line\":\r\n return <line key={key} x1={ex - eyeR} y1={ey} x2={ex + eyeR} y2={ey} stroke={color} strokeWidth={eyeR * 0.5} strokeLinecap=\"round\" />;\r\n case \"wink\":\r\n return <line key={key} x1={ex - eyeR} y1={ey} x2={ex + eyeR} y2={ey} stroke={color} strokeWidth={eyeR * 0.5} strokeLinecap=\"round\" />;\r\n case \"sleepy\":\r\n return <ellipse key={key} cx={ex} cy={ey} rx={eyeR * 1.05} ry={eyeR * 0.45} fill={color} />;\r\n case \"surprised\":\r\n return <circle key={key} cx={ex} cy={ey} r={eyeR * 1.1} fill={color} />;\r\n default:\r\n return <circle key={key} cx={ex} cy={ey} r={eyeR} fill={color} />;\r\n }\r\n };\r\n\r\n const leftEye = drawEye(cx - eyeOffsetX, cy - eyeOffsetY, \"le\");\r\n const rightEye = drawEye(cx + eyeOffsetX, cy - eyeOffsetY, \"re\");\r\n\r\n const pupils = (\r\n <>\r\n <circle cx={cx - eyeOffsetX} cy={cy - eyeOffsetY} r={pupilR} fill={finalPupilColor} />\r\n <circle cx={cx + eyeOffsetX} cy={cy - eyeOffsetY} r={pupilR} fill={finalPupilColor} />\r\n </>\r\n );\r\n\r\n const shine = eyeShine ? (\r\n <>\r\n <circle cx={cx - eyeOffsetX - pupilR * 0.4} cy={cy - eyeOffsetY - pupilR * 0.6} r={pupilR * 0.3} fill=\"#fff\" opacity={0.8} />\r\n <circle cx={cx + eyeOffsetX - pupilR * 0.4} cy={cy - eyeOffsetY - pupilR * 0.6} r={pupilR * 0.3} fill=\"#fff\" opacity={0.8} />\r\n </>\r\n ) : null;\r\n\r\n const mouth = <path d={mouthPaths[mouthShape]} stroke={color} strokeWidth={mouthStroke} fill=\"none\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />;\r\n\r\n return (\r\n <>\r\n {leftEye}\r\n {rightEye}\r\n {pupils}\r\n {shine}\r\n {mouth}\r\n </>\r\n );\r\n}\r\n\r\nexport default function Avatar({ name, size = 120, bg = \"random\", colors = \"random\" }: AvatarProps) {\r\n const rand = rngFromSeed(name);\r\n const [bg1, bg2] = resolveBg(rand, bg);\r\n const [base] = resolveCharColors(rand, colors);\r\n const cx = size / 2;\r\n const cy = size / 2;\r\n\r\n return (\r\n <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ borderRadius: \"50%\", background: `linear-gradient(135deg, ${bg1}, ${bg2})` }}>\r\n <Face cx={cx} cy={cy} r={size / 3} color={base} rand={rand} />\r\n </svg>\r\n );\r\n}\r\n"],"mappings":"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","names":["base","a1","a2"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "pixelpeeps",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.2",
|
4
4
|
"description": "Deterministic, cute pixel avatars for React. Zero deps. SVG output.",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"module": "dist/index.mjs",
|
@@ -32,7 +32,8 @@
|
|
32
32
|
"react": ">=17"
|
33
33
|
},
|
34
34
|
"dependencies": {
|
35
|
-
"nice-color-palettes": "^4.0.0"
|
35
|
+
"nice-color-palettes": "^4.0.0",
|
36
|
+
"pixelpeeps": "^1.0.1"
|
36
37
|
},
|
37
38
|
"devDependencies": {
|
38
39
|
"@types/react": "^19.2.2",
|