Open Peeps: Color System
Relevant source files
The following files were used as context for generating this wiki page:The Open Peeps color system is responsible for selecting and applying colors to various parts of the generated SVG avatar, including skin, clothing, and certain head features. It is designed to be configurable, allowing users to provide their own color palettes or use the system's defaults. The system uses a pseudo-random number generator (PRNG) based on a seed to ensure deterministic color selection from the available options.
This system integrates with the core avatar generation process by providing a collection of selected colors that are then injected directly into the SVG markup for different components. This ensures a consistent and customizable appearance for each avatar.
Core Concepts
Color Categories
The system defines three primary color categories that can be customized for an avatar. These colors are managed in a ColorPickCollection, which is a record mapping category names to their selected hex color codes.
| Category | Description | Corresponding Option |
|---|---|---|
skin | The color of the avatar's skin. | skinColor |
clothing | The color of the avatar's clothing. | clothingColor |
headContrast | A contrast color used for certain head components, like specific hairstyles or facial hair. | headContrastColor |
Sources: packages/avatar/src/open-peeps/utils/getColors.ts:12-16, packages/avatar/src/open-peeps/types.ts:6-10
Color Selection Flow
The color selection process is initiated within the create function of the Open Peeps style. It calls the getColors utility, which uses a PRNG to pick one color from the array of available colors for each category defined in the OpenPeepsOptions. If no colors are provided for a category, it defaults to transparent.
The following diagram illustrates the data flow for color selection:
This diagram shows how getColors uses the PRNG and OpenPeepsOptions to produce the final ColorPickCollection.
Sources: packages/avatar/src/open-peeps/utils/getColors.ts:11-17, packages/avatar/src/open-peeps/index.ts:16-17
Configuration and Defaults
The color system is highly configurable through the OpenPeepsOptions object. Users can override the default color palettes by providing arrays of hex color strings.
Avatar Options
The following properties in OpenPeepsOptions are used to configure the color palettes:
| Property | Type | Description |
|---|---|---|
skinColor | string[] | An array of hex color codes for skin tones. |
clothingColor | string[] | An array of hex color codes for clothing. |
headContrastColor | string[] | An array of hex color codes for contrast elements on the head. |
Sources: packages/avatar/src/open-peeps/types.ts:6-10
Default Color Palettes
If the user does not provide custom color arrays, the system falls back to a set of default palettes defined in the style's JSON schema.
| Category | Default Palette (Hex Codes) |
|---|---|
skinColor | ffdbb4, edb98a, d08b5b, ae5d29, 694d3d |
clothingColor | e78276, ffcf77, fdea6b, 78e185, 9ddadb, 8fa7df, e279c7 |
headContrastColor | 2c1b18, e8e1e1, ecdcbf, d6b370, f59797, b58143, a55728, 724133, 4a312c, c93305 |
Additionally, a default SKIN_COLORS array is defined in packages/avatar/src/config/avatar.ts, which is used as part of the base avatar configuration.
Sources: packages/avatar/src/open-peeps/schema.ts:31-43, packages/avatar/src/open-peeps/schema.ts:163-175, packages/avatar/src/open-peeps/schema.ts:176-188, packages/avatar/src/config/avatar.ts:5-7
Implementation Details
The getColors Function
The core of the color selection logic resides in the getColors function. It takes the prng instance and options object, and for each color category, it randomly picks a value from the corresponding color array in the options. The convertColor utility is used, though its implementation is not shown in the provided files, it likely ensures the color is in the correct format.
// packages/avatar/src/open-peeps/utils/getColors.ts:11-17
export function getColors({ prng, options }: Props): ColorPickCollection {
return {
skin: convertColor(prng.pick(options.skinColor ?? []) ?? 'transparent'),
clothing: convertColor(prng.pick(options.clothingColor ?? []) ?? 'transparent'),
headContrast: convertColor(prng.pick(options.headContrastColor ?? []) ?? 'transparent'),
}
}
Sources: packages/avatar/src/open-peeps/utils/getColors.ts:11-17
SVG Integration
Once the ColorPickCollection is created, the create function in packages/avatar/src/open-peeps/index.ts uses these colors to populate the final SVG string. The colors are injected into the fill attributes of various <path> and other SVG elements.
// packages/avatar/src/open-peeps/index.ts:15-29
export const create: StyleCreate<OpenPeepsOptions> = ({ prng, options }) => {
const components = getComponents({ prng, options })
const colors = getColors({ prng, options })
return {
attributes: {
'viewBox': '0 0 704 704',
'fill': 'none',
'shape-rendering': 'auto',
},
body: `<g fill-rule="evenodd" clip-rule="evenodd"><path d="..." fill="${xml(colors.skin)}"/><path d="..." fill="${xml(colors.clothing)}"/><path d="..." fill="#000"/></g><g transform="matrix(.99789 0 0 1 156 62)">${components.head?.value(colors) ?? ''}</g><g transform="translate(315 248)">${components.face?.value(colors) ?? ''}</g><g transform="translate(279 400)">${components.facialHair?.value(colors) ?? ''}</g><g transform="translate(203 303)">${components.accessories?.value(colors) ?? ''}</g>`,
// ...
}
}
As seen above, colors.skin and colors.clothing are used for the main body and clothing paths. The colors object is also passed down to individual components like head, face, and facialHair.
Sources: packages/avatar/src/open-peeps/index.ts:15-29
Component-Specific Colors
Some components, particularly those for head and facial hair, can have multiple parts and may require a contrast color. The headContrast color is used for this purpose. For example, the full4 and moustache9 facial hair components use colors.headContrast for one of their paths.
// packages/avatar/src/open-peeps/components/facialHair.ts:17-18
export const facialHair: ComponentGroup = {
// ...
full4: (colors) =>
`<g fill-rule="evenodd" clip-rule="evenodd"><path d="..." fill="${xml(colors.headContrast)}"/><path d="..." fill="#000"/></g>`,
// ...
moustache9: (colors) =>
`<g fill-rule="evenodd" clip-rule="evenodd"><path d="..." fill="${xml(colors.headContrast)}"/><path d="..." fill="#000"/></g>`,
// ...
}
This allows for more detailed and varied avatar appearances, where hair color can differ from the outline color.
Sources: packages/avatar/src/open-peeps/components/facialHair.ts:17-18, packages/avatar/src/open-peeps/components/facialHair.ts:74-75
Summary
The Open Peeps color system provides a simple yet powerful way to manage and apply colors to generated avatars. By defining distinct color categories (skin, clothing, headContrast), offering configurable palettes via options, and using a deterministic selection method, it ensures that avatars are both consistent and customizable. The direct injection of these colors into the SVG components at generation time is an efficient way to style the final output.