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 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, pixelSize, mirrored, bg, colors, headShape, square, alignX, alignY, padding, variant, className, style, title, }: AvatarProps): react_jsx_runtime.JSX.Element;
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, pixelSize, mirrored, bg, colors, headShape, square, alignX, alignY, padding, variant, className, style, title, }: AvatarProps): react_jsx_runtime.JSX.Element;
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
- function bestFeatureColor(base) {
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({ cx, cy, r, color, rand }) {
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
- a1,
157
- a2,
158
- variant,
159
- shape,
129
+ color,
130
+ eyeShape: eyeShapeProp,
131
+ mouthShape: mouthShapeProp,
132
+ pupilColor,
133
+ eyeShine: eyeShineProp,
160
134
  rand
161
135
  }) {
162
- const x0 = cx - r, y0 = cy - r, x1 = cx + r, y1 = cy + r;
163
- const left = rand() > 0.5;
164
- const tlbr = rand() > 0.5;
165
- const horiz = rand() > 0.5;
166
- const cornerTL = rand() > 0.5;
167
- switch (variant) {
168
- case "plain":
169
- return null;
170
- case "split":
171
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: left ? x0 : cx, y: y0, width: r, height: 2 * r, fill: a1 });
172
- case "diagonal":
173
- 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 });
174
- case "cap":
175
- 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 });
176
- case "swoop":
177
- 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 });
178
- case "crescent":
179
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
180
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: left ? cx - r * 0.55 : cx + r * 0.55, cy, r: r * 0.95, fill: a2 }),
181
- /* @__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 })
182
- ] });
183
- case "band":
184
- 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 });
185
- case "corner":
186
- 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 });
187
- case "ring":
188
- 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 });
189
- case "arc":
190
- 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 });
191
- case "wave":
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
- default:
204
- return null;
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
- size = 128,
210
- pixelSize = 12,
211
- mirrored = true,
212
- bg,
213
- colors,
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":"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","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
- function bestFeatureColor(base) {
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({ cx, cy, r, color, rand }) {
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
- a1,
121
- a2,
122
- variant,
123
- shape,
93
+ color,
94
+ eyeShape: eyeShapeProp,
95
+ mouthShape: mouthShapeProp,
96
+ pupilColor,
97
+ eyeShine: eyeShineProp,
124
98
  rand
125
99
  }) {
126
- const x0 = cx - r, y0 = cy - r, x1 = cx + r, y1 = cy + r;
127
- const left = rand() > 0.5;
128
- const tlbr = rand() > 0.5;
129
- const horiz = rand() > 0.5;
130
- const cornerTL = rand() > 0.5;
131
- switch (variant) {
132
- case "plain":
133
- return null;
134
- case "split":
135
- return /* @__PURE__ */ jsx("rect", { x: left ? x0 : cx, y: y0, width: r, height: 2 * r, fill: a1 });
136
- case "diagonal":
137
- return tlbr ? /* @__PURE__ */ jsx("polygon", { points: `${x0},${y0} ${x1},${y0} ${x1},${y1}`, fill: a1 }) : /* @__PURE__ */ jsx("polygon", { points: `${x0},${y0} ${x0},${y1} ${x1},${y1}`, fill: a1 });
138
- case "cap":
139
- return /* @__PURE__ */ 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 });
140
- case "swoop":
141
- return /* @__PURE__ */ 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 });
142
- case "crescent":
143
- return /* @__PURE__ */ jsxs(Fragment, { children: [
144
- /* @__PURE__ */ jsx("circle", { cx: left ? cx - r * 0.55 : cx + r * 0.55, cy, r: r * 0.95, fill: a2 }),
145
- /* @__PURE__ */ 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 })
146
- ] });
147
- case "band":
148
- return horiz ? /* @__PURE__ */ jsx("rect", { x: x0, y: cy - r * 0.35, width: 2 * r, height: r * 0.5, fill: a1 }) : /* @__PURE__ */ jsx("rect", { x: cx - r * 0.35, y: y0, width: r * 0.5, height: 2 * r, fill: a1 });
149
- case "corner":
150
- return cornerTL ? /* @__PURE__ */ jsx("polygon", { points: `${x0},${y0} ${x0 + r * 0.9},${y0} ${x0},${y0 + r * 0.9}`, fill: a1 }) : /* @__PURE__ */ jsx("polygon", { points: `${x1},${y0} ${x1 - r * 0.9},${y0} ${x1},${y0 + r * 0.9}`, fill: a1 });
151
- case "ring":
152
- return shape === "circle" ? /* @__PURE__ */ jsx("circle", { cx, cy, r: r * 0.86, fill: "none", stroke: a1, strokeWidth: r * 0.18 }) : /* @__PURE__ */ 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 });
153
- case "arc":
154
- return /* @__PURE__ */ 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 });
155
- case "wave":
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
- default:
168
- return null;
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
- size = 128,
174
- pixelSize = 12,
175
- mirrored = true,
176
- bg,
177
- colors,
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,
@@ -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.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",