@pixygon/avatar 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,187 @@
1
+ // src/types/index.ts
2
+ var STYLE_COUNTS = {
3
+ eye: 12,
4
+ brow: 8,
5
+ nose: 8,
6
+ mouth: 8,
7
+ hair: 16,
8
+ facial_hair: 8,
9
+ glasses: 6
10
+ };
11
+
12
+ // src/presets.ts
13
+ var SKIN_PRESETS = [
14
+ [0.98, 0.89, 0.78],
15
+ // Porcelain
16
+ [0.96, 0.84, 0.71],
17
+ // Fair
18
+ [0.92, 0.78, 0.63],
19
+ // Light
20
+ [0.87, 0.72, 0.55],
21
+ // Medium-light
22
+ [0.78, 0.62, 0.46],
23
+ // Medium
24
+ [0.68, 0.51, 0.36],
25
+ // Olive
26
+ [0.58, 0.42, 0.3],
27
+ // Tan
28
+ [0.47, 0.33, 0.22],
29
+ // Brown
30
+ [0.36, 0.24, 0.16],
31
+ // Dark
32
+ [0.26, 0.17, 0.11]
33
+ // Deep
34
+ ];
35
+ var EYE_COLOR_PRESETS = [
36
+ [0.1, 0.1, 0.1],
37
+ // Black
38
+ [0.35, 0.22, 0.1],
39
+ // Brown
40
+ [0.55, 0.35, 0.15],
41
+ // Hazel
42
+ [0.25, 0.5, 0.25],
43
+ // Green
44
+ [0.2, 0.4, 0.7],
45
+ // Blue
46
+ [0.45, 0.45, 0.5],
47
+ // Gray
48
+ [0.55, 0.25, 0.25],
49
+ // Red
50
+ [0.5, 0.3, 0.6]
51
+ // Violet
52
+ ];
53
+ var HAIR_COLOR_PRESETS = [
54
+ [0.08, 0.06, 0.05],
55
+ // Black
56
+ [0.22, 0.14, 0.08],
57
+ // Dark brown
58
+ [0.4, 0.26, 0.14],
59
+ // Brown
60
+ [0.58, 0.42, 0.24],
61
+ // Light brown
62
+ [0.78, 0.62, 0.34],
63
+ // Dirty blonde
64
+ [0.9, 0.78, 0.48],
65
+ // Blonde
66
+ [0.72, 0.26, 0.12],
67
+ // Red
68
+ [0.88, 0.52, 0.22],
69
+ // Ginger
70
+ [0.6, 0.6, 0.62],
71
+ // Gray
72
+ [0.92, 0.92, 0.94]
73
+ // White
74
+ ];
75
+
76
+ // src/defaults.ts
77
+ function defaultAppearance() {
78
+ return {
79
+ body: { height: 0.5, build: 0.5 },
80
+ head: {
81
+ width: 1,
82
+ height: 1,
83
+ eye_style: 0,
84
+ eye_color: [...EYE_COLOR_PRESETS[1]],
85
+ eye_y: 0.5,
86
+ eye_spacing: 0.5,
87
+ eye_size: 0.5,
88
+ eye_rotation: 0.5,
89
+ brow_style: 0,
90
+ brow_color: [...HAIR_COLOR_PRESETS[0]],
91
+ brow_y: 0.5,
92
+ brow_spacing: 0.5,
93
+ brow_size: 0.5,
94
+ brow_rotation: 0.5,
95
+ nose_style: 0,
96
+ nose_y: 0.5,
97
+ nose_size: 0.5,
98
+ mouth_style: 0,
99
+ mouth_y: 0.5,
100
+ mouth_size: 0.5,
101
+ mouth_color: [0.75, 0.35, 0.35],
102
+ hair_style: 0,
103
+ hair_color: [...HAIR_COLOR_PRESETS[2]],
104
+ facial_hair_style: 0,
105
+ facial_hair_color: [...HAIR_COLOR_PRESETS[0]],
106
+ glasses_style: 0,
107
+ glasses_color: [0.1, 0.1, 0.1]
108
+ },
109
+ skin_color: [...SKIN_PRESETS[2]]
110
+ };
111
+ }
112
+ function randomAppearance() {
113
+ const rng = (min, max) => min + Math.random() * (max - min);
114
+ const rngInt = (max) => Math.floor(Math.random() * max);
115
+ const pick = (arr) => arr[rngInt(arr.length)];
116
+ const hairColor = pick(HAIR_COLOR_PRESETS);
117
+ return {
118
+ body: {
119
+ height: rng(0.2, 0.8),
120
+ build: rng(0.2, 0.8)
121
+ },
122
+ head: {
123
+ width: rng(0.7, 1.3),
124
+ height: rng(0.7, 1.3),
125
+ eye_style: rngInt(STYLE_COUNTS.eye),
126
+ eye_color: [...pick(EYE_COLOR_PRESETS)],
127
+ eye_y: rng(0.3, 0.7),
128
+ eye_spacing: rng(0.3, 0.7),
129
+ eye_size: rng(0.3, 0.7),
130
+ eye_rotation: 0.5,
131
+ brow_style: rngInt(STYLE_COUNTS.brow),
132
+ brow_color: [...hairColor],
133
+ brow_y: rng(0.3, 0.7),
134
+ brow_spacing: rng(0.3, 0.7),
135
+ brow_size: rng(0.3, 0.7),
136
+ brow_rotation: 0.5,
137
+ nose_style: rngInt(STYLE_COUNTS.nose),
138
+ nose_y: rng(0.3, 0.7),
139
+ nose_size: rng(0.3, 0.7),
140
+ mouth_style: rngInt(STYLE_COUNTS.mouth),
141
+ mouth_y: rng(0.3, 0.7),
142
+ mouth_size: rng(0.3, 0.7),
143
+ mouth_color: [0.75, 0.35, 0.35],
144
+ hair_style: rngInt(STYLE_COUNTS.hair),
145
+ hair_color: [...hairColor],
146
+ facial_hair_style: Math.random() < 0.3 ? 1 + rngInt(STYLE_COUNTS.facial_hair - 1) : 0,
147
+ facial_hair_color: [...hairColor],
148
+ glasses_style: Math.random() < 0.2 ? 1 + rngInt(STYLE_COUNTS.glasses - 1) : 0,
149
+ glasses_color: [0.1, 0.1, 0.1]
150
+ },
151
+ skin_color: [...pick(SKIN_PRESETS)]
152
+ };
153
+ }
154
+
155
+ // src/hooks/useAvatarEditor.ts
156
+ import { useCallback, useState } from "react";
157
+ function useAvatarEditor(initial) {
158
+ const [appearance, setAppearance] = useState(
159
+ () => initial ?? defaultAppearance()
160
+ );
161
+ const [tab, setTab] = useState("body");
162
+ const update = useCallback((path, value) => {
163
+ setAppearance((prev) => {
164
+ const next = structuredClone(prev);
165
+ const parts = path.split(".");
166
+ let obj = next;
167
+ for (let i = 0; i < parts.length - 1; i++) {
168
+ obj = obj[parts[i]];
169
+ }
170
+ obj[parts[parts.length - 1]] = value;
171
+ return next;
172
+ });
173
+ }, []);
174
+ const randomize = useCallback(() => setAppearance(randomAppearance()), []);
175
+ const reset = useCallback(() => setAppearance(initial ?? defaultAppearance()), [initial]);
176
+ return { appearance, tab, setTab, update, randomize, reset };
177
+ }
178
+
179
+ export {
180
+ STYLE_COUNTS,
181
+ SKIN_PRESETS,
182
+ EYE_COLOR_PRESETS,
183
+ HAIR_COLOR_PRESETS,
184
+ defaultAppearance,
185
+ randomAppearance,
186
+ useAvatarEditor
187
+ };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { A as AvatarAppearance } from '../index-DwPxw0AI.mjs';
3
+
4
+ interface AvatarEditorProps {
5
+ /** Initial appearance (uses default if omitted). */
6
+ initial?: AvatarAppearance;
7
+ /** Called whenever the appearance changes. */
8
+ onChange?: (appearance: AvatarAppearance) => void;
9
+ /** Called when the user clicks "Done". */
10
+ onDone?: (appearance: AvatarAppearance) => void;
11
+ /** Called when the user clicks "Cancel". */
12
+ onCancel?: () => void;
13
+ /** Optional class name for the root container. */
14
+ className?: string;
15
+ }
16
+ declare function AvatarEditor({ initial, onChange, onDone, onCancel, className, }: AvatarEditorProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { AvatarEditor, type AvatarEditorProps };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { A as AvatarAppearance } from '../index-DwPxw0AI.js';
3
+
4
+ interface AvatarEditorProps {
5
+ /** Initial appearance (uses default if omitted). */
6
+ initial?: AvatarAppearance;
7
+ /** Called whenever the appearance changes. */
8
+ onChange?: (appearance: AvatarAppearance) => void;
9
+ /** Called when the user clicks "Done". */
10
+ onDone?: (appearance: AvatarAppearance) => void;
11
+ /** Called when the user clicks "Cancel". */
12
+ onCancel?: () => void;
13
+ /** Optional class name for the root container. */
14
+ className?: string;
15
+ }
16
+ declare function AvatarEditor({ initial, onChange, onDone, onCancel, className, }: AvatarEditorProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { AvatarEditor, type AvatarEditorProps };