Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@ericrovell/blossom

ericrovell14MIT1.10.0TypeScript support: included

Blossom is a JS library tool for colour manipulations and transformations.

color, color names, transform, convert, harmony colors, rgb, hex, hsl, hsv, cmyk, xyz, lab, lch, hwb, monochromatic colors, a11y, color mix

readme

Library logo as flower

Blossom

Blossom is a JS library tool for color manipulations and transformations.

Features:

  • Chainable API;
  • Ummutable;
  • Written in Typescript;
  • Types included;
  • Dependency-free;

Getting started

npm i @ericrovell/blossom
import { blossom } from "@ericrovell/blossom";

blossom("#FF0000")
  .grayscale
  .setAlpha(0.25)
  .toStringRGB

// -> rgb(128 128 128 / 0.25)

Supported color models

  • Hexadecimal strings;
  • RGB (objects, strings);
  • HSL (objects, strings);
  • HSV (objects);
  • CMYK (objects);
  • XYZ (objects);
  • LAB (objects);
  • LCH (objects, strings);
  • HWB (objects, strings);
  • Named colors

API

Color parsing

<summary> blossom </summary>

Parses the given input and creates a new Blossom instance.

  import { blossom } from "@ericrovell/blossom";

  // string input
  blossom("#ABC");
  blossom("#AABBCC");
  blossom("#ADCDEF12");
  blossom("rgb(100, 200, 255)");
  blossom("rgba(100, 200, 255, 0.5)");
  blossom("rgba(10% 20% 30% / 35%)");
  blossom("hsl(180, 78%, 87%)");
  blossom("hsla(180, 78%, 87%, 0.5)");
  blossom("hsla(180deg 78% 87% / 50%)");

  // object input
  blossom({ r: 12, g: 34, b: 56 });
  blossom({ r: 12, g: 34, b: 56, a: 1 });
  blossom({ h: 180, s: 50, l: 75 });
  blossom({ h: 180, s: 50, l: 75, a: 1 });
  blossom({ h: 180, s: 50, v: 65 });
  blossom({ h: 180, s: 50, v: 65, a: 1 });
  blossom({ c: 25, m: 50, k: 75, k: 100 });
  blossom({ c: 25, m: 50, k: 75, k: 100, a: 1 });
<summary> getModel </summary>

Parses a color and returns a color model name of the given input.

    import { getModel } from "@ericrovell/blossom";

    getModel("#ADC123"); // -> "hex"
    getModel({ r: 13, g: 237, b: 162 }); // -> "rgb"
    getModel("hsl(180deg 50% 50%)"); // -> "hsl"
    getModel("Hi!"); // -> null

Color transformations

<summary> .hex </summary>

Returns the hexadecimal representation of a color. Outputs the modern #RRGGBBAA opacity syntax for transparent colors.

  blossom("rgb(0, 255, 0)").hex; // -> "#00FF00"
  blossom({ h: 300, s: 100, l: 50 }).hex; // -> "#FF00FF"
  blossom({ r: 255, g: 255, b: 255, a: 0 }).hex; // -> "#FFFFFF00"
<summary> .rgb </summary>

Returns the RGB color model object of a color.

  blossom("#ff0000").rgb; // -> { r: 255, g: 0, b: 0, a: 1 }
  blossom({ h: 180, s: 100, l: 50, a: 0.5 }).rgb; // -> { r: 0, g: 255, b: 255, a: 0.5 }
<summary> .toStringRGB </summary>

Returns the RGB color model string of a color. Outputs the modern whitespace syntax.

  blossom("#ff0000").toStringRGB; // -> "rgb(255 0 0)"
  blossom({ h: 180, s: 100, l: 50, a: 0.5 }).toStringRGB; // -> "rgb(0 255 255 / 0.5)"
<summary> .hsl </summary>

Returns the HSL color space object of a color.

  blossom("#ffff00").hsl; // -> { h: 60, s: 100, l: 50, a: 1 }
  blossom("rgba(0, 0, 255, 0.5)").hsl; // -> { h: 240, s: 100, l: 50, a: 0.5 }
<summary> .toStringHSL </summary>

Returns the HSL color space string of a color. Outputs the modern whitespace syntax.

  blossom("#ffff00").toStringHSL; // -> "hsl(60deg 100% 50%)"
  blossom("rgba(0, 0, 255, 0.5)").toStringHSL; // -> "hsl(240deg 100% 50% / 0.5)"
<summary> .hsv </summary>

Returns the HSV color space object of a color.

  blossom("#ffff00").hsv; // -> { h: 60, s: 100, v: 100, a: 1 }
  blossom("rgba(0, 255, 255, 0.5)").hsv; // -> { h: 180, s: 100, v: 100, a: 1 }
<summary> .toStringHSV </summary>

Returns the HSV color space string of a color. Outputs the modern whitespace syntax.

  blossom("#FFFF00").toStringHSV; // -> "hsc(60deg 100% 100%)"
  blossom("rgba(0, 0, 255, 0.5)").toStringHSV; // -> "hsc(240deg 100% 100% / 0.5)"
<summary> .cmyk </summary>

Returns the CMYK color space object of a color.

  blossom("#FFFFFF").cmyk; // -> { c: 0, m: 0, y: 0, k: 0, a: 1 }
  blossom("#555AAA").cmyk; // -> { c: 50, m: 47, y: 0, k: 33, a: 1 }
<summary> .toStringCMYK </summary>

Returns the CMYK color space string of a color.

  blossom("#FFFFFF").toStringCMYK; // -> device-cmyk(0% 0% 0% 0%){ c: 0, m: 0, y: 0, k: 0, a: 1 }
  blossom("#555AAA80").toStringCMYK; // -> device-cmyk(50% 47% 0 33% / 0.5)
<summary> .xyz, available via XYZ plugin </summary>

Returns the CIE XYZ color space object of a color.

  blossom("#FFFFFF").xyz; // -> { x: 95.047, y: 100, z: 108.883 a: 1 }
  blossom({ x: 0, y: 0, z: 0 }).hex; // -> "#000000"
<summary> .toStringXYZ </summary>

Returns the CIE XYZ color space string of a color.

  blossom("#FFFFFF").toStringXYZ; // -> color(xyz 96.42 100 82.52)
  blossom("#555AAA80").toStringXYZ; // -> color(xyz 13.65 11.79 29.83 / 0.5)
<summary> .lab, available via LAB plugin </summary>

Returns the CIE LAB color space object of a color.

  blossom("#FFFFFF").lab; // -> { l: 100, a: 0, b: 0, alpha: 1 }
  blossom("#123ABC").lab; // -> { l: 29.95, a: 29.48, b: -72.93, alpha: 1 }
<summary> .toStringLAB </summary>

Returns the CIE LAB color space string of a color.

  blossom("#FFFFFF").toStringLAB; // -> lab(100% 0 0)
  blossom("#555AAA80").toStringLAB; // -> lab(40.88% 15.43 -44.4)
<summary> .lch, available via LCH plugin </summary>

Returns the CIE LCH color space object of a color.

  blossom("#FFFFFF").lch; // -> { l: 100, c: 0, h: 0, a: 1 }
  blossom("#123ABC").lch; // -> { l: 29.95, c: 78.66, c: 292.01, alpha: 1 }
<summary> .toStringLCH </summary>

Returns the CIE LCH color space string of a color.

  blossom("#FFFFFF").toStringLCH; // -> lch(100% 0 0)
  blossom("#555AAA80").toStringLCH; // -> lch(40.88% 47.01 289.16 / 0.5)
<summary> .hwb, available via HWB plugin </summary>

Returns the HWB color space object of a color.

  blossom("#FFFFFF").hwb; // -> { h: 0, w: 100, b: 0, a: 1 }
  blossom("#123ABC").hwb; // -> { h: 226, w: 7, b: 26, a: 1 }
<summary> .toStringHWB </summary>

Returns the HWB color space string of a color.

  blossom("#FFFFFF").toStringHWB; // -> hwb(0 100% 0%)
  blossom("#555AAA80").toStringHWB; // -> hwb(236 33% 33% / 0.5)
<summary> .name, available via Names plugin </summary>

Returns the name of the color as exact match of browser supported list of 140 named colors. If the color has not an alias returns null instead.

  blossom("#FF0000").name; // -> "red"
  blossom("#123ABC").name; // -> null
<summary> .closestName, available via Names plugin </summary>

Returns the closest named color from browser supported list of 140 named colors color.

  blossom("#FF0001").closestName; // -> "red"
  blossom("#66339A").closestName; // -> "rebeccapurple"

Color manipulation

<summary> .setAlpha(value) </summary>

Changes the alpha channel value and returns a new Blossom instance.

  blossom("rgb(0, 0, 0)")
    .setAlpha(0.5)
    .toStringRGB; // -> "rgb(0 0 0 / 0.5)"
<summary> .inverted </summary>

Creates a new Blossom instance with an inverted color.

  blossom("#aabbcc")
    .inverted
    .hex; // -> "#554433"
<summary> .saturate(amount = 0.1) </summary>

Increases the HSL saturation of a color by the given amount.

  blossom("#bf4040")
    .saturate(0.25)
    .hex; // -> "#df2020"

  blossom("hsl(0, 50%, 50%)")
    .saturate(0.5)
    .toStringHSL; // -> "hsl(0deg 100% 50%)"
<summary> .desaturate(amount = 0.1) </summary>

Decreases the HSL saturation of a color by the given amount.

  blossom("#df2020")
    .saturate(0.25)
    .hex; // -> "#bf4040"

  blossom("hsl(0, 100%, 50%)")
    .saturate(0.5)
    .toStringHSL; // -> "hsl(0deg 50% 50%)"  
<summary> .grayscale </summary>

Creates a gray color with the same lightness as a source color. Same result as .desaturate(1).

  blossom("#bf4040")
    .grayscale
    .hex; // -> "#808080"

  blossom("hsl(0, 100%, 50%)")
    .grayscale
    .toStringHSL; // -> "hsl(0deg 0% 50%)"
<summary> .lighten(amount = 0.1) </summary>

Increases the HSL lightness of a color by the given amount.

  blossom("#000000")
    .lighten(0.5)
    .hex; // -> "#808080"

  blossom("#223344")
    .lighten(0.3)
    .hex; // -> "#5580aa"

  blossom("hsl(0, 50%, 50%)")
    .lighten(0.5)
    .toStringHSL; // -> "hsl(0deg 50% 100%)"
<summary> .darken(amount = 0.1) </summary>

Decreases the HSL lightness of a color by the given amount.

  blossom("#ffffff")
    .darken(0.5)
    .hex; // -> "#808080"

  blossom("#5580aa")
    .darken(0.3)
    .hex; // -> "#223344"

  blossom("hsl(0, 50%, 100%)")
    .lighten(0.5)
    .toStringHSL; // -> "hsl(0, 50%, 50%)"
<summary> .setHue(value) </summary>

Changes the hue value and returns a new Blossom instance.

  blossom("hsl(90, 50%, 50%)")
    .setHue(180)
    .toStringHSL; // -> "hsl(180deg 50% 50%)"

  blossom("hsl(90, 50%, 50%)")
    .setHue(370)
    .toStringHSL; // -> "hsl(10deg 50% 50%)"
<summary> .rotate(amout = 15) </summary>

Increases the HSL hue value of a color by the given amount.

  blossom("hsl(90, 50%, 50%)")
    .rotate(90)
    .toStringHSL; // -> "hsl(180deg 50% 50%)"

  blossom("hsl(90, 50%, 50%)")
    .rotate(-180)
    .toStringHSL; // -> "hsl(270deg 50% 50%)"

Color properties

<summary> .valid </summary>

Returns a boolean indicating whether or not an input has been parsed successfully. On unsuccess, color value defaults to black without error.

  blossom("#FFF").valid; // -> true
  blossom("#NaN").valid; // -> false
  blossom("hello").valid; // -> false
  blossom({ r: 0, g: 0, b: 0 }).valid; // -> true
  blossom({ r: 0, g: 0, v: 0 }).valid; // -> false
<summary> .alpha </summary>

Returns an alpha channel value of the color.

  blossom("#FFFFFF").alpha; // -> 1
  blossom("rgba(50 100 150 / 0.5)").alpha; // -> 0.5
<summary> .opaque </summary>

Returns a boolean indicating whether or not a color is opaque.

  blossom("#FFFFFF").opaque; // -> true
  blossom("rgba(50 100 150 / 0.5)").opaque; // -> false
<summary> .transparent </summary>

Returns a boolean indicating whether or not a color is transparent.

  blossom("#FFFFFF").transparent; // -> false
  blossom("rgba(50 100 150 / 0.5)").transparent; // -> true
<summary> .hue </summary>

Returns the Hue value of the number on the color wheel.

  blossom("hsl(90deg 50% 50%)").hue; // -> 90
  blossom("hsl(-10deg 50% 50%)").hue; // -> 350
<summary> .saturation </summary>

Returns the saturation value of the number.

  blossom("hsl(90deg 50% 50%)").saturation; // -> 0.5
  blossom("hsl(-10deg 98% 50%)").saturation; // -> 0.98
<summary> .lightness </summary>

Returns the lightness value of the number.

  blossom("hsl(90deg 50% 50%)").lightness; // -> 0.5
  blossom("hsl(-10deg 50% 46%)").lightness; // -> 0.46
<summary> .brightness </summary>

Returns the brightness of a color in range [0; 1]. The calculation logic is modified from Web Content Accessibility Guidelines.

  blossom("#000000").brightness; // -> 0
  blossom("#808080").brightness; // -> 0.5
  blossom("#FFFFFF").brightness; // -> 1
<summary> .light </summary>

A Boolean indicator whether or not a color is light (brightness >= 0.5).

  blossom("#000000").light; // -> false
  blossom("#808080").light; // -> true
  blossom("#FFFFFF").light; // -> true
<summary> .dark </summary>

A Boolean indicator whether or not a color is dark (brightness < 0.5).

  blossom("#000000").dark; // -> true
  blossom("#808080").dark; // -> false
  blossom("#FFFFFF").dark; // -> false
<summary> .luminance, available via a11y plugin </summary>

Returns the relative luminance of a color, normalized to range [0, 1] as from pure black to pure white according to WCAG 2.0.

  blossom("#000000").luminance; // 0
  blossom("#808080").luminance; // 0.22
  blossom("#ffffff").luminance; // 1
<summary> .contrast(color = "#FFF"), available via a11y plugin </summary>

Calculates a contrast ratio for a pair of colors.

The luminance difference lies in range [1 (white on white), 21 (black on white)]. WCAG required a ratio at least 4.5 for normal text and 3:1 for large one.

  blossom("#000000").contrast(); // 21 (black on white)
  blossom("#ffffff").contrast("#000000"); // 21 (white on black)
  blossom("#777777").contrast(); // 4.47 (gray on white)
  blossom("#ff0000").contrast(); // 3.99 (red on white)
  blossom("#0000ff").contrast("#ff000"); // 2.14 (blue on red)
<summary> .readable(color = "#FFF", options?), available via a11y plugin </summary>

Checks that a background and text color pair is readable according to WCAG 2.0 Contrast and Color Requirements.

  blossom("#000000").isReadable(); // true (normal black text on white bg conforms to WCAG AA)
  blossom("#777777").isReadable(); // false (normal gray text on white bg conforms to WCAG AA)
  blossom("#ffffff").isReadable("#000000"); // true (normal white text on black bg conforms to WCAG AA)
  blossom("#e60000").isReadable("#ffff47", { level: "AAA" }); // false (normal red text on yellow bg does not conform to WCAG AAA)
  blossom("#e60000").isReadable("#ffff47", { level: "AAA", size: "large" }); // true (large red text on yellow bg conforms to WCAG AAA)
<summary> .mix(color, ratio = 0.5), available via mix plugin </summary>

Produces a mixture of two colors and returns the result as new Blossom instance. Mix produced using CIE LAB color space.

  import { colord, extend } from "blossom";
  import pluginMix from "@ericrovell/blossom/plugins/mix";

  extend([ mixPlugin ]);

  blossom("#FFFFFF").mix("#000000").hex; // -> "#777777"
  blossom("#800080").mix("#DDA0DD").hex; // -> "#AF5CAE"
  blossom("#CD853F").mix("#EEE8AA", 0.6).hex; // -> "#E3C07E"
  blossom("#008080").mix("#808000", 0.35).hex; // -> "#50805D"
<summary> .delta(color = "#FFF"), available via LAB plugin </summary>

Calculates the perceived color difference between two colors. The difference calculated according to Delta E2000.

Returns the normalized value in range from [0, 1], where 0 means the same colors and 1 are completely different ones.

  colord("#3296fa").delta("#197dc8") // 0.099
  colord("#faf0c8").delta("#fff") // 0.148
  colord("#afafaf").delta("#b4b4b4") // 0.014
  colord("#000").delta("#fff") // 1.0

Color Utilities

<summary> random() </summary>

Creates new instance with a random color.

  import { random } from "@ericrovell/blossom";

  random().hex; // -> "#01C8EC"
  random().setAlpha(0.5).rgb; // -> { r: 13, g: 237, b: 162, a: 0.5 }

Plugins

Usage

To extend the functionality using plugins, the extend function should be used:

import { blossom, extend } from "@ericrovell/blossom";
import { plugin1, plugin2 } from "plugin-path;

extend([
  plugin1,
  plugin2
]);

Included plugins

<summary> Harmonies </summary>

Provides functionatity to generate harmony colors.

Available harmony pallets:

  • analogous;
  • complimentary;
  • double-split-comlimentary;
  • rectangle;
  • tetradic;
  • triadic;
  • split-complimentary;

    import { blossom, extends } from "@ericrovell/blossom";
    import { pluginHarmonies } from "blossom/plugins/harmonies";
    
    extend([ pluginHarmonies ]);
    
    const color = blossom("FF0000");
    
    color.harmonies("analogous")
    .map(color => color.hex); // -> [ "#FF0080", "#FF0000", "#FF8000"]
    color.harmonies("complimentary")
    .map(color => color.hex); // -> [ "#FF0000", "#00FFFF" ]
    color.harmonies("double-split-complimentary")
    .map(color => color.hex); // -> [ "#FF0080", "#FF0000", "#FF8000", "#00FF80", "#0080FF" ]
    color.harmonies("rectangle")
    .map(color => color.hex); // -> [ "#FF0000", "#FFFF00", "#00FFFF", "#0000FF" ]
    color.harmonies("tetradic")
    .map(color => color.hex); // -> [ "#FF0000", "#80FF00", "#00FFFF", "#8000FF" ]
    color.harmonies("triadic"  )
    .map(color => color.hex); // -> [ "#FF0000", "#00FF00", "#0000FF" ]
    color.harmonies("split-complimentary")
    .map(color => color.hex); // -> [ "#FF0000", "#00FF80", "#0080FF" ]

    Harmony color schemes type is available for import:

    import type { Harmony } from "@ericrovell/blossom/plugins/harmonies";
    
    const harmony: Harmony = "analogous";
    const notHarmony: Harmony = "round"; // TypeError
<summary> Monochromatic </summary>

Provides functionatity to generate monochromatic colors as:

  • Tints;
  • Shades;
  • Tones.

    import { blossom, extends } from "@ericrovell/blossom";
    import { pluginMonochromatic } from "blossom/plugins/monochromatic";
    
    extend([ pluginMonochromatic ]);
    
    const color = blossom("FF0000");
    
    color.tints(4).map(tint => tint.hex); // -> [ "#FF0000", "#FF4242", "#FF8585", "#FFC7C7", "#FFFFFF" ]
    color.shades(4).map(shade => shade.hex); // -> [ "#FF0000", "#BD0000", "#7A0000", "#380000", "#000000" ]
    color.tones(4).map(tone => tone.hex); // -> [ "#FF0000", "#DF2020", "#BF4040", "#9F6060", "#808080" ]

    The original color is always included as first palette item.

    If there is not enough space between colors to generate required number of colors, less number of colors will be generated. For example, generating 10 shades for #050505 is not practical as #000000 is too close and all shades will be indistinguishable:

    import { blossom, extends } from "@ericrovell/blossom";
    import { pluginMonochromatic } from "blossom/plugins/monochromatic";
    
    extend([ pluginMonochromatic ]);
    
    blossom("#FAFAFA").tints(10).map(tint => tint.hex); // -> [ "#FAFAFA", "#FDFDFD", "#FFFFFF" ]
    blossom("#050505").shades(10).map(shade => shade.hex); // -> [ "#050505", "#020202", "#000000" ]
    blossom("#827D7D").tones(10).map(tone => tone.hex); // -> [ "#827D7D", "#817E7E", "#808080" ]
<summary> A11Y (Accessibility) </summary>

Adds accessibility and color contrast utilities working according to Web Content Accessibility Guidelines 2.0.

  import { blossom, extend } from "@ericrovell/blossom";
  import { pluginA11Y } from "@ericrovell/blossom/plugins/a11y";

  extend([ pluginA11Y ]);

  blossom("#000000").luminance; // 0
  blossom("#CCDDEE").luminance; // 0.71
  blossom("#FFFFFF").luminance; // 1

  blossom("#000000").contrast(); // 21 (black on white)
  blossom("#FFFFFF").contrast("#000000"); // 21 (white on black)
  blossom("#0000ff").contrast("#FF000"); // 2.14 (blue on red)

  blossom("#000000").readable(); // true (black on white)
  blossom("#FFFFFF").readable("#000000"); // true (white on black)
  blossom("#777777").readable(); // false (gray on white)
  blossom("#E60000").readable("#FFFF47"); // true (normal red text on yellow bg conforms to WCAG AA)
  blossom("#E60000").readable("#FFFF47", { level: "AAA" }); // false (normal red text on yellow bg does not conform to WCAG AAA)
  blossom("#E60000").readable("#FFFF47", { level: "AAA", size: "large" }); // true (large red text on yellow bg conforms to WCAG AAA)
<summary> XYZ (CIE XYZ Color space) </summary>

Adds support of CIE XYZ color model.

  import { blossom, extend } from "@ericrovell/blossom";
  import { pluginXYZ } from "@ericrovell/blossom/plugins/xyz";

  extend([ pluginXYZ ]);

  blossom("#FFFFFF").xyz; // -> { x: 95.047, y: 100, z: 108.883, a: 1 }
  blossom({ x: 0, y: 0, z: 0 }).hex; // -> "#000000"
<summary> LAB (CIE LAB Color space) </summary>

Adds support of CIE LAB color model. Plugin provides .delta method for perceived color difference calculations: 0 for same colors, 1 for completely different ones.

  import { blossom, extend } from "@ericrovell/blossom";
  import { pluginLAB } from "@ericrovell/blossom/plugins/lab";

  extend([ pluginLAB ]);

  blossom({ l: 29.95, a: 29.48, b: -72.93 }).hex; // "#123ABC"
  blossom("#FFFFFF").lab; // { l: 100, a: 0, b: 0, alpha: 1 }

  blossom("#afafaf").delta("#b4b4b4") // 0.014
  blossom("#000").delta("#fff") // 1.0
<summary> LCH (CIE LCH Color space) </summary>

Adds support of CIE LCH color model.

  import { blossom, extend } from "@ericrovell/blossom";
  import { pluginLCH } from "@ericrovell/blossom/plugins/lch";

  extend([ pluginLCH ]);

  blossom({ l: 29.95, a: 29.48, b: 40.21 }).hex; // "#6B372A"
  blossom("#FFFFFF").lab; // { l: 100, c: 0, h: 0, a: 1 }
<summary> HWB </summary>

Adds support of HWB color model.

  import { blossom, extend } from "@ericrovell/blossom";
  import { pluginHWB } from "@ericrovell/blossom/plugins/hwb";

  extend([ pluginHWB ]);

  blossom({h: 236, w: 33, b: 33 }).hex; // "#555AAA"
  blossom("#FFFFFF").hwb; // { h: 0, w: 100, b: 0 }
<summary> Mix </summary>

Adds support for mixing colors. Mixture is produced using CIE LAB color space.

  import { colord, extend } from "blossom";
  import pluginMix from "@ericrovell/blossom/plugins/mix";

  extend([ mixPlugin ]);

  blossom("#FFFFFF").mix("#000000").hex; // -> "#777777"
  blossom("#800080").mix("#DDA0DD").hex; // -> "#AF5CAE"
  blossom("#CD853F").mix("#EEE8AA", 0.6).hex; // -> "#E3C07E"
  blossom("#008080").mix("#808000", 0.35).hex; // -> "#50805D"
<summary> Names </summary>

Adds support for a list of 140 named colors supported by all modern browsers.

  import { colord, extend } from "blossom";
  import pluginNames from "@ericrovell/blossom/plugins/names";

  extend([ pluginNames ]);

  blossom("white").hex           // -> "#FFFFFF"
  blossom("red").hex             // -> "#FF0000"
  blossom("#FF0000").name        // -> "red"
  blossom("#ABC123").name        // -> null
  blossom("#FF0101").closestName // -> "red"
  blossom("#66339A").closestName // -> "rebeccapurple"

Types

Blossom is written in strict TypeScript and ships with types in the library itself.

While not only typing its own functions and variables, you can also type yours. Depending on the color space you are using, the types can be also imported and used to type the code.

import type { ColorRGB, ColorHSL } from "@ericrovell/blossom";

const foo: ColorHSL = { h: 0, s: 0, l: 0 };
const bar: ColorRGB = { r: 0, g: 0, v: 0 }; // type error!

Extending the functionality

To extend functionality for your needs, just extend the Blossom class:

import { Blossom } from "@ericrovell/blossom";

class BlossomExtended extends Blossom {
  constructor(input?) {
        super(input);
    }

  get red() {
    return this.color.r;
  }
}

const extended = new BlossomExtended("#FF0000");
extended.red // -> 255;

Inspiration

It was a long time I was thinking about this project. There were two unsuccessfull attemps, it was not thoughfull enough.

This project is inspired by fantastic colord project, that gave me the idea about architecture and implementation.

changelog

Blossom Changelog

1.10.0 (2021-09-26):

  • [feature]: extended LAB plugin functionality with .delta() method for perceived color difference calculations using Delta E2000;

1.9.0 (2021-09-04):

  • [feature]: new build-in plugin names plugin with named colors support;
  • [fix]: missing color models type exports;

1.8.0 (2021-08-12):

  • [feature]: new build-in plugin with HWB color space support ❤️ @omgovich;
  • [feature]: new build-in plugin mix with color mixing using CIE LAB color space for better results ❤️ @omgovich;

1.7.0 (2021-08-10):

  • [feature]: .toStringLAB property for string representation of color;
  • [feature]: .toStringXYZ property for string representation of color;
  • [feature]: new build-in plugin with CIE LCH color space support ❤️ @omgovich;

1.6.0 (2021-08-08):

  • [feature]: new harmony pallete "double-split-complimentary" available via Harmonies plugin;
  • [feature]: new build-in plugin with CIE XYZ color space support ❤️ @omgovich;
  • [feature]: new build-in plugin with CIE LAB color space support ❤️ @omgovich;

1.5.0 (2021-08-06):

  • [feature]: parsing CMYK strings;
  • [feature]: string output for CMYK Color models via .toStringCMYK property;
  • [feature]: string output for HSV Color models via .toStringHSV property;
  • [fix]: .luminance property valid type signature;

1.4.2 (2021-08-06):

  • [fix]: build-in plugins exports;
  • [fix]: build-in plugins types;
  • [fix]: types from declaration files works as intended.

1.4.0 (2021-08-06):

  • [feature]: new build-in a11y plugin ❤️ @omgovich.

1.3.2 (2021-08-03):

  • [fix]: .saturation and .lightness properties precision degree now has fixed value.

1.3.1 (2021-08-02)

  • [improvement]: Providing CommonJS build;

1.3.0 (2021-07-28)

  • [feature]: build-in Monochromatic plugin that provides functionatity to generate monochromatic color palletes (tints, shades, tones);
  • [feature]: .saturation getter for more precise value of HSL color model saturation;
  • [feature]: .lightness getter for more precise value of HSL color model lightness;

1.2.0 (2021-07-23)

  • [feature]: Harmonies plugin implementation;

1.1.0 (2021-07-22)

  • [feature]: Plugin API implementation;

1.0.0 (2021-07-19)

  • Initial release. Basic API.