@batpb/genart - generative art library

Logo

A TypeScript compatible library built on p5.js for creating responsive generative art projects.

view the project on github brittni-and-the-polar-bear/genart

How to Add a New Palette to the Library (Developer Instructions)

Table of Contents

Step 1: Add Any New Colors for the Palette

Step 2: Categorize the Palette

Step 3: Add the File for the Palette

Step 4: Create the Palette Object

Step 5: Export the Palette from the index.ts File

Step 6: Add the Palette to the Palette Maps

Step 7: Add the New Palette to the Palette Unit Tests

Step 8: Add the New Palette to the Palette Map Unit Tests

Step 9: Run the ALL_PALETTES Unit Test

Step 10: Add Documentation

Step 11: Add the New Palette to the Palette Category Markdown Pages

Step 12: Add Palette to the “All Palettes on One Page” Markdown Page

Step 13: Add Palette to the Release Notes

Full PaletteColor File Example

Fin.


Step 1: Add Any New Colors for the Palette

Table of Contents

Step 2: Categorize the Palette

Valid Categories:

Table of Contents

Step 3: Add the File for the Palette

The directory of the color file will be /src/main/color/palette/palettes/<category>. Each nested category will be its own directory (e.g. holiday/christmas).

The filename of the palette file will be the name of the palette with all lowercase letters, followed by -palette. Separate words using a dash (-) character.

If there is already a file with that name, a palette with that name already exists in the library. Verify that the palette does not already exist in the library, and use a new name for the new palette if it does not exist.

Example: /src/main/color/palette/palettes/miscellaneous/brittni-palette.ts

Table of Contents

Step 4: Create the Palette Object

The object name of the palette should have all capital letters and end with _PALETTE.

Example: BRITTNI_PALETTE

Step 4, Part A: Set Palette Name

The NAME property should be in all lowercase letters.
Example: NAME: 'brittni'

Table of Contents

Step 4, Part B: Set Palette Sources

The SOURCE and SOURCE_URL properties are an optional properties.

The palette source should be a string describing the original source of the palette colors.

If the palette was inspired by or taken from a website, the SOURCE_URL property should be the URL of the website.

Table of Contents

Step 4, Part C: Set the IS_GRADIENT Flag

If the palette is a gradient, the IS_GRADIENT flag should be set to true. Otherwise, it should be set to false.

Table of Contents

Step 4, Part D: Set the DISCRIMINATOR Property

The DISCRIMINATOR property should be Discriminators.PALETTE.
Example: DISCRIMINATOR: Discriminators.PALETTE

Table of Contents

Step 4, Part E: Set the Colors

The COLORS property of the palette will be an array of PaletteColor objects. The colors array should be considered an ordered list.

Table of Contents

Step 4, Part F: Create the Contrast Map

The CONTRAST_MAP property is an optional property.

The CONTRAST_MAP should contain information about colors in the palette that have a contrast value of 4.5 or higher. Entries for black (#000000) and white (#FFFFFF) are required.

The keys in the object are the hex values of the colors. The values in the object are lists of palette hex values that have a contrast value of 4.5 or greater when compared to the key.

Black (#000000) and white (#FFFFFF) can be added as contrast colors for any palette color.

All hex values should be written with capital letters.

CONTRAST_MAP Example

// type definition included for example purposes only
type ContrastMap = {
    readonly '#000000': string[],
    readonly '#FFFFFF': string[],
    readonly [HEX: string]: string[]
}

// const object declaration included for example purposes only
// CONTRAST_MAP will be a property of the new Palette object.
const CONTRAST_MAP: ContrastMap = {
    '#000000': ['#0FFF4F', '#FF6BB5'],
    '#FFFFFF': ['#121212', '#0437F1', '#7A00F5'],
    '#121212': ['#FFFFFF', '#0FFF4F', '#FF6BB5'],
    '#0437F1': ['#FFFFFF', '#0FFF4F'],
    '#0FFF4F': ['#000000', '#121212', '#0437F1', '#7A00F5'],
    '#7A00F5': ['#FFFFFF', '#0FFF4F'],
    '#FF6BB5': ['#000000', '#121212']
}

Table of Contents

Step 5: Export the Palette from the index.ts File

In the index.ts file in the same category directory, add a statement to export the palette.
Example: export * from './brittni';

Table of Contents

Step 6: Add the Palette to the Palette Maps

Add the color to the Palette map matching its category and any parent categories, using the setUndefinedKey method. The key will be the NAME property, and the value will be the Palette object.

Add the color to the Palette map for all palettes, using the setUndefinedKey method. The key will be the NAME property, and the value will be the Palette object.

If the palette is a gradient (i.e. the IS_GRADIENT property is set to true), add the color to the Palette map for gradient palettes, using the setUndefinedKey method. The key will be the NAME property, and the value will be the Palette object.

Table of Contents

Step 7: Add the New Palette to the Palette Unit Tests

In the src/test/palette/palettes/<category> directory, create the unit test for the individual palette. The purpose of these unit tests are to make sure that the palette only contains its expected colors and to make sure that the palette has a valid configuration (at least 2 colors, lowercase name, valid contrast map, etc.). Each nested category will be its own directory (e.g. holiday/christmas).

Run the unit test to ensure that it passes.

Individual Palette Unit Test Example

import { PaletteColor } from 'palette';
import { PC_0437F1, PC_0FFF4F, PC_121212, PC_7A00F5, PC_FF6BB5 } from 'palette-colors';
import { BRITTNI_PALETTE } from 'palettes';

import { checkForValidPalette } from 'unit-test/shared';

const PALETTE_NAME: string = 'BRITTNI_PALETTE';

describe('BRITTNI_PALETTE tests', (): void => {
    const expectedColors: PaletteColor[] = [
        PC_121212,
        PC_0437F1,
        PC_0FFF4F,
        PC_7A00F5,
        PC_FF6BB5
    ]

    test(`${PALETTE_NAME} is valid`, (): void => {
        checkForValidPalette(BRITTNI_PALETTE, expectedColors);
    });
});

Table of Contents

Step 8: Add the New Palette to the Palette Map Unit Tests

Add the new palette to the EXPECTED_PALETTES list in each applicable palette map unit test. Run each palette map unit test to ensure that they pass.

If the palette is a gradient (i.e. the IS_GRADIENT property is set to true), add the new palette to the EXPECTED_PALETTES list in the gradient palettes unit test. Run the unit test to ensure that it passes.

Table of Contents

Step 9: Run the ALL_PALETTES Unit Test

Run the unit test for the ALL_PALETTES palette map (/src/test/color/palette/palette-maps/all-palettes.test.ts).

If the “all palettes are unique” test fails, the new palette’s color combination already exists in the library or a palette with the same name already exists in the library.

The colors in your palette may exist in a palette under a different name or in a different category.

You may need to change the name of your palette, if your color combination does not already exist in the library.

Table of Contents

Step 10: Add Documentation

Step 10, Part A: Add the Coolors Palette Widget

Go to https://coolors.co/

Create a palette with all the colors of the new palette. The palette color order should match how the colors are listed in the source code.

Export the palette for embedding and copy the provided HTML code.

Paste the HTML at the top of the palette documentation.

Coolors Palette Widget Example

<!--suppress JSUnresolvedLibraryURL -->
<!-- Coolors Palette Widget -->
<script src="https://coolors.co/palette-widget/widget.js"></script>
<script data-id="031196377224963245">new CoolorsPaletteWidget("031196377224963245", ["121212","0437f1","0fff4f","7a00f5","ff6bb5"]); </script>

Table of Contents

Step 10, Part B: Add the @see Annotations for Each PaletteColor

Add a @see annotation with a @link for every PaletteColor object in the palette.

Example: @see {@link PC_121212}

Table of Contents

Step 10, Part C: Add the @see Annotation to Each PaletteColor

Add a @see annotation with a @link to the palette in documentation of every PaletteColor object in the palette.

Example: @see {@link BRITTNI_PALETTE}

Table of Contents

Step 10, Part D: Add the @category Annotations

Add @category annotations for the Palettes (All) category and each palette category of the new palette (e.g. @category Palettes (Miscellaneous)).

If the palette is a gradient (i.e. the IS_GRADIENT property is set to true), add a @category annotation for the Palettes (Gradient) category.

Table of Contents

Step 11: Add the New Palette to the Palette Category Markdown Pages

Add an entry for the new palette to each applicable palette category markdown page. This entry should include the Coolors Palette Widget and a link to the palette’s source. The TypeScript use example is optional.

Be sure to add the new markdown section to the Table of Contents.

If the palette is a gradient (i.e. the IS_GRADIENT property is set to true), add an entry for the new palette to the gradient palettes markdown page.

Palette Category Entry Example

<!--suppress JSUnresolvedLibraryURL -->
# classic christmas

<a href="https://coolors.co/palette/bb010b-cd1624-006f57-23856d-faf8f8" target="_blank" rel="noopener noreferrer">palette source: coolors</a>

<!-- Coolors Palette Widget -->
<script src="https://coolors.co/palette-widget/widget.js"></script>
<script data-id="048851888975141655">new CoolorsPaletteWidget("048851888975141655", ["bc010a","d01625","007058","23856d","fbf9f9"],"classic christmas"); </script>
<br/>

```typescript
import {CLASSIC_CHRISTMAS_PALETTE} from 'palettes';

let name: string = CLASSIC_CHRISTMAS_PALETTE.NAME;
```

[Table of Contents](#table-of-contents)

Table of Contents

Step 12: Add Palette to the “All Palettes on One Page” Markdown Page

Add an entry for the new palette to the “All Palettes on One Page” markdown page. This entry should include the Coolors Palette Widget and a link to the palette’s source.

All Palettes Entry Example

### [classic christmas](/genart/palettes/holidays/christmas/christmas-palettes.html#classic-christmas)

palette source:
<a href="https://coolors.co/palette/bb010b-cd1624-006f57-23856d-faf8f8" target="_blank" rel="noopener noreferrer">coolors</a>

<!-- Coolors Palette Widget -->
<script data-id="048851888975141655">new CoolorsPaletteWidget("048851888975141655", ["bc010a","d01625","007058","23856d","fbf9f9"],"classic christmas"); </script>
<br/>

[Table of Contents](#table-of-contents)

Table of Contents

Step 13: Add Palette to the Release Notes

Add the palette as a new constant to the release notes draft markdown file.

Release Notes Entry Example

<!--suppress JSUnresolvedLibraryURL -->
## `BRITTNI_PALETTE`

<!-- Coolors Palette Widget -->
<script src="https://coolors.co/palette-widget/widget.js"></script>
<script data-id="031196377224963245">new CoolorsPaletteWidget("031196377224963245", ["121212","0437f1","0fff4f","7a00f5","ff6bb5"]); </script>
<br/>

```typescript
/**
 * <!-- Coolors Palette Widget -->
 * <script src="https://coolors.co/palette-widget/widget.js"></script>
 * <script data-id="031196377224963245">new CoolorsPaletteWidget("031196377224963245", ["121212","0437f1","0fff4f","7a00f5","ff6bb5"]); </script>
 *
 * @see {@link PC_121212}
 * @see {@link PC_0437F1}
 * @see {@link PC_0FFF4F}
 * @see {@link PC_7A00F5}
 * @see {@link PC_FF6BB5}
 *
 * @category Palettes (All)
 * @category Palettes (Miscellaneous)
 */
declare const BRITTNI_PALETTE: Palette;
```

Table of Contents

Full PaletteColor File Example

import {Discriminators} from 'discriminator';
import {Palette} from 'palette';
import {PC_0437F1, PC_0FFF4F, PC_121212, PC_7A00F5, PC_FF6BB5} from 'palette-colors';

import {ALL_PALETTES, MISCELLANEOUS_PALETTES} from '../palette-maps';

/**
 * <!-- Coolors Palette Widget -->
 * <script src="https://coolors.co/palette-widget/widget.js"></script>
 * <script data-id="031196377224963245">new CoolorsPaletteWidget("031196377224963245", ["121212","0437f1","0fff4f","7a00f5","ff6bb5"]); </script>
 *
 * @see {@link PC_121212}
 * @see {@link PC_0437F1}
 * @see {@link PC_0FFF4F}
 * @see {@link PC_7A00F5}
 * @see {@link PC_FF6BB5}
 *
 * @category Palettes (All)
 * @category Palettes (Miscellaneous)
 */
export const BRITTNI_PALETTE: Palette = {
    NAME: 'brittni',

    IS_GRADIENT: false,

    COLORS: [
        PC_121212,
        PC_0437F1,
        PC_0FFF4F,
        PC_7A00F5,
        PC_FF6BB5
    ],

    CONTRAST_MAP: {
        '#000000': ['#0FFF4F', '#FF6BB5'],
        '#FFFFFF': ['#121212', '#0437F1', '#7A00F5'],
        '#121212': ['#FFFFFF', '#0FFF4F', '#FF6BB5'],
        '#0437F1': ['#FFFFFF', '#0FFF4F'],
        '#0FFF4F': ['#000000', '#121212', '#0437F1', '#7A00F5'],
        '#7A00F5': ['#FFFFFF', '#0FFF4F'],
        '#FF6BB5': ['#000000', '#121212']
    },

    DISCRIMINATOR: Discriminators.PALETTE
};

ALL_PALETTES.setUndefinedKey(BRITTNI_PALETTE.NAME, BRITTNI_PALETTE);
MISCELLANEOUS_PALETTES.setUndefinedKey(BRITTNI_PALETTE.NAME, BRITTNI_PALETTE);

Table of Contents


Fin.

Table of Contents