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

Package detail

@zsviczian/colormaster

zsviczian174MIT1.2.2TypeScript support: included

🏆 A powerful and fully typed module for all your coloring needs.

color, colour, rgb, hex, hsl, cmyk, hsv, hwb, lab, lch, luv, uvw, ryb, xyz, cmyk, css, color-names, convert, a11y, accessibility, mix, harmonies

readme

This is the same as https://github.com/lbragile/ColorMaster only package.json is patched with the 3 missing exports. It seems lbragile's original project is abandoned. I've waited 1.5 years for this PR to be reviewed. I've given up.

ColorMaster is a powerful and fully typed module for all your coloring needs.

💎 Features

  • 📦 Compact: Just ~2.5 KB minified & gzipped
  • 👌 Straightforward: Clear & intuitive function names with chainable API
  • 🔫 Bulletproof: Entirely TypeScript (strict mode) and very thoroughly tested
  • Strongly Typed: Includes types out of the box
  • 🏗 Extendable: Plugins allow you to extend upon core functionality as needed
  • 🌳 Tree Shakable: Only adds functions that you use to reduce your project's size
  • 📑 CSS Compliant: Adheres to CSS color specifications
  • 🚂 Works Everywhere: Browser (client) and NodeJS (server) support
  • 🐣 Dependency Free: Full control of features & enhancements

 

⭐ Getting Started

npm install colormaster

Then simply start using ColorMaster in your project:

<summary>RGBA Color Space</summary>
// note that the import name can be anything (default export), we use "CM" for brevity
import CM from "colormaster";

// object argument
CM({ r: 128, g: 128, b: 128, a: 0.5 }).stringRGB(); // "rgba(128, 128, 128, 0.5)"
CM({ r: 128, g: 128, b: 128, a: 0.5 }).stringRGB({ alpha: false }); // "rgb(128, 128, 128)"
CM({ r: 128, g: 128, b: 128, a: 0.5 }).alphaTo(0.8).stringRGB(); // "rgba(128, 128, 128, 0.8)"

// string argument
CM("rgba(128, 128, 128, 0.5)").stringRGB(); // "rgba(128, 128, 128, 0.5)"
CM("rgba(128, 128, 128, 0.5)").stringRGB({ alpha: false }); // "rgb(128, 128, 128)"
CM("rgba(128, 128, 128, 0.5)").alphaTo(0.8).stringRGB(); // "rgba(128, 128, 128, 0.8)"
CM("rgba(128, 128, 128, 0.5)").stringRGB(); // "rgba(128, 128, 128, 0.5)"
CM("rgba(50%, 50%, 50%, 50%)").stringRGB(); // "rgba(128, 128, 128, 0.5)"
CM("rgba(50% 50% 50% 50%)").stringRGB(); // "rgba(128, 128, 128, 0.5)"
CM("rgba(50% 50% 50% / 50%)").stringRGB(); // "rgba(128, 128, 128, 0.5)"
CM("rgba(50% 50% 50% / 0.5)").stringRGB(); // "rgba(128, 128, 128, 0.5)"
<summary>HSLA Color Space</summary>
import CM from "colormaster";

// object argument
CM({ h: 300, s: 50, l: 60, a: 0.5 }).stringHSL(); // "hsla(300, 50%, 60%, 0.5)"
CM({ h: 300, s: 50, l: 60, a: 0.5 }).stringHSL({ alpha: false }); // "hsl(300, 50%, 60%)"
CM({ h: 300, s: 50, l: 60, a: 0.5 }).alphaTo(0.8).stringHSL(); // "hsla(300, 50%, 60%, 0.8)"

// string argument
CM("hsla(300, 50%, 60%, 0.5)").stringHSL(); // "hsla(300, 50%, 60%, 0.5)"
CM("hsla(300, 50%, 60%, 0.5)").stringHSL({ alpha: false }); // "hsl(300, 50%, 60%)"
CM("hsla(300, 50%, 60%, 0.5)").alphaTo(0.8).stringHSL(); // "hsla(300, 50%, 60%, 0.8)"
CM("hsla(50%, 50%, 60%, 50%)").stringHSL(); // "hsla(180, 50%, 60%, 0.5)"
CM("hsla(50% 50% 60% 50%)").stringHSL(); // "hsla(180, 50%, 60%, 0.5)"
CM("hsla(50% 50% 60% / 50%)").stringHSL(); // "hsla(180, 50%, 60%, 0.5)"
CM("hsla(50% 50% 60% / 0.5)").stringHSL(); // "hsla(180, 50%, 60%, 0.5)"
<summary>HEXA Color Space</summary>
import CM from "colormaster";

// object argument
CM({ r: "45", g: "67", b: "89", a: "AB" }).stringHEX(); // "#456789AB"
CM({ r: "45", g: "67", b: "89", a: "AB" }).stringHEX({ alpha: false }); // "#456789"
CM({ r: "45", g: "67", b: "89", a: "AB" }).alphaTo("CC").stringHEX(); // "#456789CC"

// string argument
CM("#456789AB").stringHEX(); // "#456789AB" ← 8-Digit Hex Input
CM("#456789").stringHEX(); // "#456789FF" ← 6-Digit Hex Input
CM("#4567").stringHEX(); // "#44556677" ← 4-Digit Hex Input
CM("#456").stringHEX(); // "#445566FF" ← 3-Digit Hex Input
CM("#456789AB").stringHEX({ alpha: false }); // "#456789"
CM("#456789AB").alphaTo("CC").stringHEX(); // "#456789CC"

Note: HEXA string are always returned in upperCase by ColorMaster. If you prefer lowerCase strings, you can simply use (chain) the built in toLowerCase(). More information is available here


Note: Many more color spaces are provided via plugins to make ColorMaster compact.

 

🎯 Playground

ColorMaster also has a playground where key functionality is illustrated. Those that are interested can play around with the elegant user interface for daily color related needs, grab the corresponding ColorMaster snippet from each page's code button, or even use our REST API for quick results to common requests.

 

🔥 API

Object Instantiation (Color Generation)

<summary>ColorMaster(color)</summary>

Parses a given input color so that ColorMaster can perform necessary operations to manipulate/transform that input

import CM from "colormaster";

CM("rgba(255, 0, 0, 1)").stringRGB(); // "rgba(255, 0, 0, 1.0)"
CM({ r: 255, g: 0, b: 0, a: 1 }).stringRGB(); // "rgba(255, 0, 0, 1.0)"

CM("hsla(120, 100%, 50%, 1)").stringHSL(); // "hsla(120, 100%, 50%, 1.0)"
CM({ h: 120, s: 100, l: 50, a: 1 }).stringHSL(); // "hsla(120, 100%, 50%, 1.0)"

// Supports 3-digit, 4-digit, 6-digit, and 8-digit HEX(A) input.
CM("#456789").stringHEX(); // "#456789FF"
CM({ r: "45", g: "67", b: "89", a: "AB" }).stringHEX(); // "#456789AB"

// requires name plugin
import CM, { extendPlugins } from "colormaster";
import NamePlugin from "colormaster/plugins/name";

extendPlugins([NamePlugin]);

CM("red").stringHEX(); // "#FF0000FF"
<summary>random()</summary>

Generates a random RGBA color.

import { random } from "colormaster";

random().stringRGB(); // "rgba(255, 0, 0, 1.0)"
random()().stringHSL(); // "hsla(0, 100%, 50%, 1.0)"
random().stringHEX(); // "#FF0000FF"

 

Formatting

<summary>stringRGB(opts?)</summary>

Generates a human readable RGBA color space string from a given color instance

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").stringRGB(); // "rgba(255, 0, 0, 1)"
CM("rgba(255, 0, 0, 1)").stringRGB({ alpha: false }); // "rgba(255, 0, 0)"
CM("rgba(200.1234, 100.1234, 50.1234, 0.61234)").stringRGB({ precision: [1, 2, 3, 4] }); // "rgba(200.1, 100.12, 50.123, 0.6123)"
<summary>stringHEX(opts?)</summary>

Generates a human readable HEXA color space string from a given color instance

Note: this method always returns an 8-digit hex string (you do not need to/cannot specify precision)

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").stringHEX(); // "#FF0000FF"
CM("rgba(255, 0, 0, 1)").stringHEX({ alpha: false }); // "#FF0000"
<summary>stringHSL(opts?)</summary>

Generates a human readable HSLA color space string from a given color instance

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").stringHSL(); // "hsl(0, 100%, 50%, 1)"
CM("rgba(255, 0, 0, 1)").stringHSL({ alpha: false }); // "hsl(0, 100%, 50%)"
CM("hsla(200.1234, 75.1234, 50.1234, 0.61234)").stringHSL({ precision: [1, 2, 3, 4] }); // "hsla(200.1, 100.12%, 50.123%, 0.6123)"
<summary>name() (name plugin)</summary>

Gets the color table CSS/HTML name for a given color

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").name(); // "red"
CM("rgba(0, 255, 0, 1)").name(); // "green"
CM("rgba(0, 0, 255, 1)").name(); // "blue"

Note: More color space string formation methods (string<COLOR-SPACE>) are available with each Color Space Plugin.

 

Channel/Instance Level Information

<summary>format</summary>

Retrieve the format of color instance (what is the color space)

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").format; // "rgb"
<summary>red</summary>

Get the "red" channel value for the color instance.

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").red; // 255
CM("hsla(0, 100%, 50%, 1)").red; // 255
CM("#F00F").red; // "FF"
<summary>green</summary>

Get the "green" channel value for the color instance.

import CM from "colormaster";
CM("rgba(0, 255, 0, 1)").green; // 255
CM("hsla(120, 100%, 50%, 1)").green; // 255
CM("#0F0F").green; // "FF"
<summary>blue</summary>

Get the "blue" channel value for the color instance.

import CM from "colormaster";
CM("rgba(0, 0, 255, 1)").blue; // 255
CM("hsla(240, 100%, 50%, 1)").blue; // 255
CM("#00FF").blue; // "FF"
<summary>alpha</summary>

Get the "alpha" channel value for the color instance.

import CM from "colormaster";
CM("rgba(0, 0, 255, 1)").alpha; // 1
CM("hsla(240, 100%, 50%, 1)").alpha; // 1
CM("#FF0F").alpha; // "FF"
<summary>hue</summary>

Get the "hue" channel value for the color instance.

import CM from "colormaster";
CM("rgba(0, 0, 255, 1)").hue; // 240
CM("hsla(240, 100%, 50%, 1)").hue; // 240
CM("#00F").hue; // 240
<summary>saturation</summary>

Get the "saturation" channel value for the color instance.

import CM from "colormaster";
CM("rgba(0, 0, 255, 1)").saturation; // 100
CM("hsla(240, 100%, 50%, 1)").saturation; // 100
CM("#00F").saturation; // 100
<summary>lightness</summary>

Get the "lightness" channel value for the color instance.

import CM from "colormaster";
CM("rgba(0, 0, 255, 1)").lightness; // 50
CM("hsla(240, 100%, 50%, 1)").lightness; // 50
CM("#00F").lightness; // 50

 

Objects From Color Instance

<summary>rgba()</summary>

Retrieve the object corresponding to the color instance

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").rgba(); // "{ r: 255, g: 0, b: 0, a: 1 }"
<summary>hsla()</summary>

Retrieve the object corresponding to the color instance

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").hsla(); // "{ h: 0, s: 100, l: 50, a: 1 }"
<summary>hexa(opts?)</summary>

Retrieve the object corresponding to the color instance

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").hexa(); // "{ r: "FF", g: "00", b: "00", a: "FF" }"

Note: More color space object formation methods (<color-space>a) are available with each Color Space Plugin.

 

Manipulation

<summary>hueTo(value | cssName)</summary>

Changes the "hue" channel value TO a given input value (done in HSLA space and converted back to RGBA space)

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").hueTo(120).stringRGB(); // "rgba(0, 255, 0, 1.0)"
CM("hsla(0, 100%, 50%, 1)").hueTo(120).stringHSL(); // "hsla(120, 100%, 50%, 1.0)"
CM("#f00").hueTo("green").stringHEX(); // "#00FF00FF"
<summary>hueBy(delta)</summary>

Changes the "hue" channel value BY a given delta (done in HSLA space and converted back to RGBA space)

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").hueBy(120).stringRGB(); // "rgba(0, 255, 0, 1.0)"
CM("hsla(0, 100%, 50%, 1)").hueBy(-30).stringHSL(); // "hsla(330, 100%, 50%, 1.0)"
CM("#f00").hueBy(240).stringHEX(); // "#0000FFFF"
<summary>alphaTo(value)</summary>

Changes the "alpha" channel value TO a given input value

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").alphaTo(0.5).stringRGB(); // "rgba(255, 0, 0, 0.5)"
CM("hsla(0, 100%, 50%, 1)").alphaTo(0.5).stringHSL(); // "hsla(0, 100%, 50%, 0.5)"
CM("#f00").alphaTo("AA").stringHEX(); // "#FF0000AA"
<summary>alphaBy(delta)</summary>

Changes the "alpha" channel value BY a given delta

import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").alphaBy(-0.1).stringRGB(); // "rgba(255, 0, 0, 0.9)"
CM("hsla(0, 100%, 50%, 1)").alphaBy(-0.1).stringHSL(); // "hsla(0, 100%, 50%, 0.9)"
CM("#f009").alphaBy("23").stringHEX(); // "#FF0000BC"
<summary>saturationTo(value)</summary>

Sets the saturation channel of a color to value

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").saturationTo(75).stringHSL(); // "hsla(0, 75%, 50%, 1.0)"
<summary>saturateBy(delta)</summary>

This adds pigmentation to a color, making it less gray.

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").saturateBy(20).stringHSL(); // "hsla(0, 80%, 50%, 1.0)"
<summary>desaturateBy(delta)</summary>

The opposite affect of saturateBy(delta). This removes pigmentation from a color making it more gray.

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").desaturateBy(20).stringHSL(); // "hsla(0, 40%, 50%, 1.0)"
<summary>lightnessTo(value)</summary>

Sets the lightness channel of a color to value

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").lightnessTo(75).stringHSL(); // "hsla(0, 60%, 75%, 1.0)"
<summary>lighterBy(delta)</summary>

This adds white to a color.

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").lighterBy(10).stringHSL(); // "hsla(0, 60%, 60%, 1.0)"
<summary>darkerBy(delta)</summary>

The opposite of lighterBy(delta). This adds black to a color.

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").darkerBy(10).stringHSL(); // "hsla(0, 60%, 40%, 1.0)"
<summary>grayscale()</summary>

The same as setting the saturation to "0%" for a color. This makes the color appear grey as it completely removes all pigmentation.

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").grayscale().stringHSL(); // "hsla(0, 0%, 50%, 1.0)"
<summary>rotate(value)</summary>

This simply adjusts the angle of the color along the color wheel by incrementing the hue value.

import CM from "colormaster";
CM("hsla(0, 60%, 50%, 1)").rotate(120).stringHSL(); // "hsla(120, 60%, 50%, 1.0)"
<summary>invert(opts?)</summary>

Gets the inverted color corresponding to the current color. This is different from a complementary color.

Example, hue of 120 is 240 for the inverted color (360-120), but 300 for the complementary color (120+180)

import CM from "colormaster";
CM("hsla(120, 60%, 30%, 0.3)").invert().stringHSL(); // "hsla(240, 40%, 70%, 0.7)"
CM("hsla(120, 60%, 30%, 0.3)").invert({ alpha: false }).stringHSL(); // "hsla(240, 40%, 70%, 0.3)"

 

Accessibility (Plugin - aka A11y)

To use the methods below, the plugin first needs to be extended. That being said, we will skip this step to avoid repetition.

<summary>brightness(opts?)</summary>

Finds the normalized brightness of the color as defined by WCAG

import CM from "colormaster";
CM("hsla(0, 0%, 0%, 1)").brightness(); // 0
CM("hsla(0, 0%, 0%, 1)").brightness({ percentage: true }); // 0
CM("hsla(0, 0%, 25.1%, 1)").brightness(); // 0.251
CM("hsla(0, 0%, 25.1%, 1)").brightness({ percentage: true }); // 25.1
CM("hsla(0, 0%, 50.2%, 1)").brightness(); // 0.502
CM("hsla(0, 0%, 50.2%, 1)").brightness({ percentage: true }); // 50.2
CM("hsla(0, 0%, 75.29%, 1)").brightness(); // 0.7529
CM("hsla(0, 0%, 75.29%, 1)").brightness({ percentage: true }); // 75.29
CM("hsla(0, 0%, 100%, 1)").brightness(); // 1
CM("hsla(0, 0%, 100%, 1)").brightness({ percentage: true }); // 100
<summary>luminance(opts?)</summary>

Finds the normalized luminance of the color as defined by WCAG 2.0

import CM from "colormaster";
CM("hsla(0, 0%, 0%, 1)").luminance(); // 0
CM("hsla(0, 0%, 0%, 1)").luminance({ percentage: true }); // 0
CM("hsla(0, 0%, 25.1%, 1)").luminance(); // 0.0513
CM("hsla(0, 0%, 25.1%, 1)").luminance({ percentage: true }); // 5.13
CM("hsla(0, 0%, 50.2%, 1)").luminance(); // 0.2159
CM("hsla(0, 0%, 50.2%, 1)").luminance({ percentage: true }); // 21.59
CM("hsla(0, 0%, 75.29%, 1)").luminance(); // 0.5271
CM("hsla(0, 0%, 75.29%, 1)").luminance({ percentage: true }); // 52.71
CM("hsla(0, 0%, 100%, 1)").luminance(); // 1
CM("hsla(0, 0%, 100%, 1)").luminance({ percentage: true }); // 100
<summary>contrast(opts?)</summary>

Indicates how well a given color can be read/seen when on a background given by bgColor. A ratio of "1:1" indicates very poor contrast, while "21:1" indicates very good contrast. The calculated value also depends on factors such as text size and contrast ratio type. The lowest acceptable contrast ratio is "3:1" according to WCAG

import CM from "colormaster";

// default bgColor is white
CM("hsla(0, 0%, 0%, 1)").contrast(); // 21
CM("hsla(0, 0%, 0%, 1)").contrast({ ratio: true }); // "21.0000:1"
CM("hsla(0, 0%, 25.1%, 1)").contrast(); // 10.3653
CM("hsla(0, 0%, 25.1%, 1)").contrast({ ratio: true }); // "10.3653:1"
CM("hsla(0, 0%, 50.2%, 1)").contrast(); // 3.9489
CM("hsla(0, 0%, 50.2%, 1)").contrast({ ratio: true }); // "3.9489:1"
CM("hsla(0, 0%, 75.29%, 1)").contrast(); // 1.8194
CM("hsla(0, 0%, 75.29%, 1)").contrast({ ratio: true }); // "1.8194:1"
CM("hsla(0, 0%, 100%, 1)").contrast(); // 1
CM("hsla(0, 0%, 100%, 1)").contrast({ ratio: true }); // "1.0000:1"
CM("hsla(0, 0%, 100%, 1)").contrast({ bgColor: "#000", ratio: true }); // "21.0000:1"
<summary>isLight()</summary>

Based on the color brightness (true if brightness >= 0.5)

import CM from "colormaster";
CM("hsla(0, 0%, 0%)").isLight(); // false
CM("hsla(0, 0%, 49.9%)").isLight(); // false
CM("hsla(0, 0%, 50.1%)").isLight(); // true
CM("hsla(0, 0%, 100%)").isLight(); // true
<summary>isDark()</summary>

Based on the color brightness (true if brightness < 0.5)

import CM from "colormaster";
CM("hsla(0, 0%, 0%)").isDark(); // true
CM("hsla(0, 0%, 49.9%)").isDark(); // true
CM("hsla(0, 0%, 50.1%)").isDark(); // false
CM("hsla(0, 0%, 100%)").isDark(); // false
<summary>readableOn(opts?)</summary>

Based on the contrast value of a color on a given background color. The output is obtained by the conditions outlined in WCAG

import CM from "colormaster";

// extremes (default color is white as bg, size = body, level = minimum)
CM("#fff").readableOn(); // false (1.0:1)
CM("#fff").readableOn({ bgColor: CM("#000") }); // true (21.0:1)
CM("#000").readableOn({ bgColor: CM("#000") }); // false (1.0:1)
CM("#000").readableOn(); // true (21.0:1)

// 3.0:1
CM("#fff").readableOn({ bgColor: CM("#949494FF"), size: "large", level: "minimum" }); // true (3.03:1)
CM("#fff").readableOn({ bgColor: CM("#959595FF"), size: "large", level: "minimum" }); // false (2.99:1)

// 4.5:1
CM("#fff").readableOn({ bgColor: CM("#777F") }); // false (4.47:1)
CM("#fff").readableOn({ bgColor: CM("#767676FF") }); // true (4.54:1)
CM("#fff").readableOn({ bgColor: CM("#777F"), size: "large", level: "enhanced" }); // false (4.47:1)
CM("#fff").readableOn({ bgColor: CM("#767676FF"), size: "large", level: "enhanced" }); // true (4.54:1)

// 7.0:1
CM("#fff").readableOn({ bgColor: CM("#595959FF"), size: "body", level: "enhanced" }); // true (7.0:1)
CM("#fff").readableOn({ bgColor: CM("#5A5A5AFF"), size: "body", level: "enhanced" }); // false (6.89:1)
<summary>equalTo(compareColor?)</summary>

Determines if the current color is identical (all channels are the same) to compareColor

import CM from "colormaster";
CM("#12345678").equalTo(CM("#12345678")); // true
CM("#12345678").equalTo(CM("#00345678")); // false
CM("#12345678").equalTo(CM("#123456FF")); // false
<summary>isWarm()</summary>

"Warm colors are the colors from red through to yellow. These colors are said to bring to mind warmth, like the sun." Based on the information presented on Canva

import CM from "colormaster";
CM("hsla(74.9, 100%, 50%, 1)").isWarm(); // true
CM("hsla(255, 100%, 50%, 1)").isWarm(); // true
CM("hsla(0, 100%, 50%, 1)").isWarm(); // true
CM("hsla(180, 100%, 50%, 1)").isWarm(); // false
<summary>isCool()</summary>

"Cool colors are the colors from blue to green and purple. These colors are said to bring to mind coolness, like water." Based on the information presented on Canva

import CM from "colormaster";
CM("hsla(75, 100%, 50%, 1)").isCool(); // true
CM("hsla(254.9, 100%, 50%, 1)").isCool(); // true
CM("hsla(0, 100%, 50%, 1)").isCool(); // false
CM("hsla(180, 100%, 50%, 1)").isCool(); // true
<summary>isTinted()</summary>

A color is tinted if its lightness value is strictly greater than 50%.

import CM from "colormaster";
CM("hsla(0, 100%, 51%, 1)").isTinted(); // true
CM("hsla(0, 100%, 50%, 1)").isTinted(); // false
CM("hsla(0, 100%, 49%, 1)").isTinted(); // false
<summary>isShaded()</summary>

A color is shaded if its lightness value is strictly less than 50%.

import CM from "colormaster";
CM("hsla(0, 100%, 51%, 1)").isShaded(); // false
CM("hsla(0, 100%, 50%, 1)").isShaded(); // false
CM("hsla(0, 100%, 49%, 1)").isShaded(); // true
<summary>isToned()</summary>

A color is toned if its saturation value is strictly less than 100%.

import CM from "colormaster";
CM("hsla(0, 100%, 51%, 1)").isToned(); // false
CM("hsla(0, 99%, 51%, 1)").isToned(); // true
<summary>isPureHue(opts)</summary>

A color is pure if its saturation value is 100% and lightness value is 50%.

import CM from "colormaster";
CM("hsla(0, 100%, 50%, 1)").isPureHue(); // { pure: true, reason: 'N/A' }
CM("hsla(0, 100%, 50%, 1)").isPureHue({ reason: false }); // true
CM("hsla(0, 100%, 51%, 1)").isPureHue(); // { pure: false, reason: 'tinted' }
CM("hsla(0, 100%, 51%, 1)").isPureHue({ reason: false }); // false
CM("hsla(0, 100%, 49%, 1)").isPureHue(); // { pure: false, reason: 'shaded' }
CM("hsla(0, 100%, 49%, 1)").isPureHue({ reason: false }); // false
CM("hsla(0, 99%, 50%, 1)").isPureHue(); // { pure: false, reason: 'toned' }
CM("hsla(0, 99%, 50%, 1)").isPureHue({ reason: false }); // false
<summary>closestWebSafe()</summary>

Finds the closest color to the current color instance that is considered to be web safe

import CM from "colormaster";
CM("hsla(3, 97%, 47%, 0.7)").closestWebSafe().stringHSL(); // "hsla(0, 100%, 50%, 0.7)"
<summary>closestCool()</summary>

Finds the closest color to the current color instance that is a "Cool" color

import CM from "colormaster";
CM("hsla(300, 100%, 50%, 1)").closestCool().stringHSL(); // "hsla(254, 100%, 50%, 1.0)"
<summary>closestWarm()</summary>

Finds the closest color to the current color instance that is a "Warm" color

import CM from "colormaster";
CM("hsla(120, 100%, 50%, 1)").closestWarm().stringHSL(); // "hsla(74, 100%, 50%, 1.0)"
<summary>closestPureHue()</summary>

Finds the closest color (hue) to the current color instance that has 100% saturation and 50% lightness.

import CM from "colormaster";
CM("hsla(120, 99%, 51%, 1)").closestPureHue().stringHSL(); // "hsla(120, 100%, 50%, 1.0)"

 

Color Harmonies (Plugin)

<summary>harmony(opts?)</summary>

Generates a color harmony according to the selected type. Note that for the 'monochromatic' color harmony, an array of tints, shades, or tones is generated based on the provided monochromaticOpts

import CM, { extendPlugins } from "colormaster";
import HarmonyPlugin from "colormaster/plugins/harmony";

extendPlugins([HarmonyPlugin]);

const ogColor = "hsla(30, 50%, 50%, 1)";
CM(ogColor)
  .harmony({ type: "analogous" })
  .map((c) => c.stringHSL());
// ["hsla(0, 50%, 50%, 1.0)", "hsla(30, 50%, 50%, 1.0)", "hsla(60, 50%, 50%, 1.0)"]

CM(ogColor)
  .harmony({ type: "complementary" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(210, 50%, 50%, 1.0)"]

CM(ogColor)
  .harmony({ type: "split-complementary" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(180, 50%, 50%, 1.0)", "hsla(240, 50%, 50%, 1.0)"]

CM(ogColor)
  .harmony({ type: "double-split-complementary" })
  .map((c) => c.stringHSL());
// ["hsla(0, 50%, 50%, 1.0)", "hsla(30, 50%, 50%, 1.0)", "hsla(60, 50%, 50%, 1.0)", "hsla(180, 50%, 50%, 1.0)", "hsla(240, 50%, 50%, 1.0)"]

CM(ogColor)
  .harmony({ type: "triad" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(150, 50%, 50%, 1.0)", "hsla(270, 50%, 50%, 1.0)"]

CM(ogColor)
  .harmony({ type: "rectangle" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(90, 50%, 50%, 1.0)",  "hsla(210, 50%, 50%, 1.0)", "hsla(270, 50%, 50%, 1.0)"]

CM(ogColor)
  .harmony({ type: "square" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(120, 50%, 50%, 1.0)", "hsla(210, 50%, 50%, 1.0)", "hsla(300, 50%, 50%, 1.0)"]

CM(ogColor)
  .harmony({ type: "monochromatic", effect: "tints" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(30, 50%, 60%, 1.0)", "hsla(30, 50%, 70%, 1.0)", "hsla(30, 50%, 80%, 1.0)", "hsla(30, 50%, 90%, 1.0)", "hsla(30, 50%, 100%, 1.0)"]

CM(ogColor)
  .harmony({ type: "monochromatic", effect: "shades" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(30, 50%, 40%, 1.0)", "hsla(30, 50%, 30%, 1.0)", "hsla(30, 50%, 20%, 1.0)", "hsla(30, 50%, 10%, 1.0)", "hsla(30, 50%, 0%, 1.0)"]

CM(ogColor)
  .harmony({ type: "monochromatic", effect: "tones" })
  .map((c) => c.stringHSL());
// ["hsla(30, 50%, 50%, 1.0)", "hsla(30, 40%, 50%, 1.0)", "hsla(30, 30%, 50%, 1.0)", "hsla(30, 20%, 50%, 1.0)", "hsla(30, 10%, 50%, 1.0)", "hsla(30, 0%, 50%, 1.0)"]

 

Color Mixing (Plugin)

<summary>mix(opts?)</summary>

Mixes a ratio of color WITH 1-ratio of the current color instance in a given colorspace

Unlike other color libraries, ColorMaster uses the LUVA color space for mixing colors as this produces superior results.

import CM, { extendPlugins } from "colormaster";
import MixPlugin from "colormaster/plugins/mix";

extendPlugins([MixPlugin]);

// ratio = 0.5, colorspace = 'luv' (default)
CM("#FFFF").mix({ color: "#000F" }).stringHEX(); // "#777777FF"
CM("#FFFA").mix({ color: "#000B" }).stringHEX(); // "#777777B3"

CM("#FF0").mix({ color: "#00F", colorspace: "ryb" }).stringHEX(); // "#008000FF"

CM("#ABC").mix({ color: "#F00F", ratio: -1 }).stringHEX(); // "#AABBCCFF" → ratio < 0
CM("#ABC").mix({ color: "#F00F", ratio: 0 }).stringHEX(); // "#AABBCCFF" → ratio = 0
CM("#ABC").mix({ color: "#F00F", ratio: 1 }).stringHEX(); // "#FF0000FF" → ratio = 1
CM("#ABC").mix({ color: "#F00F", ratio: 2 }).stringHEX(); // "#FF0000FF" → ratio > 1

 

🤯 General Plugins

ColorMaster comes out of the box with an extendable plugin mechanism that adds extra functionality to the core library.

<summary>MixPlugin (Color Mixtures | 2.78KB)</summary>

Allows mixing of colors with a given ratio.

Unlike other color libraries, ColorMaster uses the LCHA color space for mixing colors as this produces superior results.

import CM, { extendPlugins } from "colormaster";
import MixPlugin from "colormaster/plugins/mix";

extendPlugins([MixPlugin]);

...
<summary>NamePlugin (CSS Names | 2.21KB)</summary>

Want to use type-checked CSS names rather than memorizing their corresponding channel values? Then this plugin is for you. It also lets you retrieve a CSS name from the current color instance.

import CM, { extendPlugins } from "colormaster";
import A11yPlugin from "colormaster/plugins/accessibility";

extendPlugins([A11yPlugin]);

...
<summary>A11yPlugin (Accessibility | 1.97KB)</summary>

Useful functions for determining if a given color adheres to certain well know accessibility rules/guidelines

import CM, { extendPlugins } from "colormaster";
import A11yPlugin from "colormaster/plugins/accessibility";

extendPlugins([A11yPlugin]);

...
<summary>HarmonyPlugin (Color Harmonies | 0.639KB)</summary>

Lets you generate beautiful color harmonies based on the current color instance

import CM, { extendPlugins } from "colormaster";
import HarmonyPlugin from "colormaster/plugins/harmony";

extendPlugins([HarmonyPlugin]);

...

 

🎨 Color Space Plugins

ColorMaster also provides color space related plugins.

<summary>LCHPlugin (LCH[A] Color Space | 1.74KB)</summary>
import CM, { extendPlugins } from "colormaster";
import LCHPlugin from "colormaster/plugins/lch";

extendPlugins([LCHPlugin]);

CM({ l: 88, c: 120, h: 136, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").lcha(); // { l: 88, c: 120, h: 136, a: 0.5 }

CM("lcha(88 120 136 / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringLCH(); // "lcha(88%, 120, 136, 0.5)"
<summary>LUVPlugin (LUV[A] Color Space | 1.73KB)</summary>
import CM, { extendPlugins } from "colormaster";
import LUVPlugin from "colormaster/plugins/luv";

extendPlugins([LUVPlugin]);

CM({ l: 88, u: -85, v: 87, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").luva(); // { l: 88, u: -85, v: 87, a: 0.5 }

CM("color(luva 88%, -85%, 87% / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringLUV(); // "color(luva 88%, -85%, 87%, 0.5)"
<summary>LABPlugin (LAB[A] Color Space | 1.63KB)</summary>
import CM, { extendPlugins } from "colormaster";
import LABPlugin from "colormaster/plugins/lab";

extendPlugins([LABPlugin]);

CM({ l: 100, a: -100, b: 100, alpha: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").laba(); // { l: 100, a: -100, b: 100, alpha: 0.5 }

CM("laba(100 -100 100 / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringLAB(); // "laba(100%, -100, 100, 0.5)"
<summary>UVWPlugin (UVW[A] Color Space | 1.54KB)</summary>
import CM, { extendPlugins } from "colormaster";
import UVWPlugin from "colormaster/plugins/uvw";

extendPlugins([UVWPlugin]);

CM({ u: 26, v: 72, w: 93, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").uvwa(); // { u: 26, v: 72, w: 93, a: 0.5 }

CM("color(uvwa 26, 72, 93 / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringUVW(); // "color(uvwa 26, 72, 93, 0.5)"
<summary>XYZPlugin (XYZ[A] Color Space | 1.44KB)</summary>
import CM, { extendPlugins } from "colormaster";
import XYZPlugin from "colormaster/plugins/xyz";

extendPlugins([XYZPlugin]);

CM({ x: 35, y: 70, z: 10, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").xyza(); // { x: 35, y: 70, z: 10, a: 0.5 }

CM("color(xyza 35 70 10 / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringXYZ(); // "color(xyza 35, 70, 10, 0.5)"
<summary>HWBPlugin (HWB[A] Color Space | 1.15KB)</summary>
import CM, { extendPlugins } from "colormaster";
import HWBPlugin from "colormaster/plugins/hwb";

extendPlugins([HWBPlugin]);

CM({ h: 120, w: 0, b: 0, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").hwba(); // { h: 120, w: 0, b: 0, a: 0.5 }

CM("hwba(120 0% 0% / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringHWB(); // "hwba(120, 0%, 0%, 0.5)"
<summary>HSVPlugin (HSV[A] Color Space | 1.06KB)</summary>
import CM, { extendPlugins } from "colormaster";
import HSVPlugin from "colormaster/plugins/hsv";

extendPlugins([HSVPlugin]);

CM({ h: 120, s: 100, v: 100, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").hsva(); // { h: 120, s: 100, v: 100, a: 0.5 }

CM("hsva(120 100% 100% / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringHSV(); // "hsva(120, 100%, 100%, 0.5)"
<summary>RYBPlugin (RYB[A] Color Space | 0.921KB)</summary>
import CM, { extendPlugins } from "colormaster";
import RYBPlugin from "colormaster/plugins/ryb";

extendPlugins([RYBPlugin]);

CM({ r: 0, y: 255, b: 255, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").ryba(); // { r: 0, y: 255, b: 255, a: 0.5 }

CM("color(ryba 0, 255, 255 / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").stringRYB(); // "color(ryba 0, 255, 255, 0.5)"
<summary>CMYKPlugin (CMYK[A] Color Space | 0.906KB)</summary>
import CM, { extendPlugins } from "colormaster";
import CMYKPlugin from "colormaster/plugins/cmyk";

extendPlugins([CMYKPlugin]);

CM({ c: 100, m: 0, y: 100, k: 0, a: 0.5 }).stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").cmyka(); // { c: 100, m: 0, y: 100, k: 0, a: 0.5 }

CM("device-cmyk(100 0% 100% 0 / 0.5)").stringRGB(); // "rgba(0, 255, 0, 0.5)"
CM("rgba(0, 255, 0, 0.5)").cmyka(); // "device-cmyk(100, 0, 100, 0, 0.5)"

Multiple plugins can be added at the same time by simply providing them as an array to the extendPlugins helper.

Note: more plugins will be added to accommodate user demands & improve ColorMaster as a whole

 

😍 Strongly Typed

Rather than using pure JavaScript which can lead to hard to debug errors during development, ColorMaster was written in TypeScript (strict mode) to provide a pleasant development experience.

The type definitions are included with the module, so you get intellisense right out of the box.

Additionally, ColorMaster exports all of its types and interfaces so that you can use them in your code.

Next we present how to type your code for RGBA, HEXA, and HSLA color space objects, but you can follow the same principles for all supported color spaces.

<summary>RGBA Types</summary>
import { Irgb, Irgba } from "colormaster/types";

let rgb: Irgb;
rgb = { r: 128, g: 128, b: 128 }; // OK
rgb = { r: 128, g: 128, b: 128, a: 0.5 }; // ERROR
rgb = { red: 128, green: 128, blue: 128 }; // ERROR

let rgba: Irgba;
rgba = { r: 128, g: 128, b: 128, a: 0.5 }; // OK
rgba = { r: 128, g: 128, b: 128 }; // ERROR
rgba = { r: 128, g: 128, b: 128, alpha: 0.5 }; // ERROR
<summary>HEXA Types</summary>
import { Ihex, Ihexa } from "colormaster/types";

let hex: Ihex;
hex = { r: "AA", g: "BB", b: "CC" }; // OK
hex = { r: "AA", g: "BB", b: "CC", a: "DD" }; // ERROR
hex = { red: "AA", green: "BB", blue: "CC" }; // ERROR

let hexa: Ihexa;
hexa = { r: "AA", g: "BB", b: "CC", a: "DD" }; // OK
hexa = { r: "AA", g: "BB", b: "CC" }; // ERROR
hexa = { r: "AA", g: "BB", b: "CC", alpha: "DD" }; // ERROR
<summary>HSLA Types</summary>
import { Ihsl, Ihsla } from "colormaster/types";

let hsl: Ihsl;
hsl = { h: 240, s: 50, l: 75 }; // OK
hsl = { h: 240, s: 50, l: 75, a: 0.5 }; // ERROR
hsl = { hue: 240, saturation: 50, lightness: 75 }; // ERROR

let hsla: Ihsla;
hsla = { h: 240, s: 50, l: 75, a: 0.5 }; // OK
hsla = { h: 240, s: 50, l: 75 }; // ERROR
hsla = { h: 240, s: 50, l: 75, alpha: 0.5 }; // ERROR

 

📕 Documentation Documentation

 

📈 Roadmap & Tasks

Visit our automated Kanban for a detailed overview of the features/tasks that need to be added to ColorMaster in the near future.

Here is a snapshot of completed and planned features:

  • <input checked="" disabled="" type="checkbox"> CSS/HTML name handling
  • <input checked="" disabled="" type="checkbox"> Color wheel manipulation (rotation, saturation, lightness, grayscale, etc.)
  • <input checked="" disabled="" type="checkbox"> Proper handling of improper input values
  • <input checked="" disabled="" type="checkbox"> brightness, luminance, contrast accessibility functions - along with other helpful wrappers
  • <input checked="" disabled="" type="checkbox"> Plugin Mechanism to extend functionality of core library
  • <input checked="" disabled="" type="checkbox"> Color harmony generation
  • <input checked="" disabled="" type="checkbox"> Color mixing (done in LCHA color space)
  • <input checked="" disabled="" type="checkbox"> RGB[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> HEX[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> HSL[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> HSV[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> HWB[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> XYZ[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> LAB[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> LCH[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> LUV[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> UVW[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> RYB[A] color space conversion & parsing
  • <input checked="" disabled="" type="checkbox"> CMYK[A] color space conversion & parsing

Note: suggestions and/or requests (in addition to the above) are always welcome!

 

License GitHub License

All of the code used in ColorMaster is released under the MIT License.

FOSSA Status

changelog

ColorMaster Change Log

All notable changes to the ColorMaster module will be documented in this file.

v1.2.1 - September 06, 2021

Fixed

  • JSDoc of interfaces/class methods for better intellisense experience

v1.2.0 - September 02, 2021

Added

  • LUV, UVW, RYB parsers & plugins with associated testing
  • Added typeGuards for new color spaces & adjusted RGB/HEX type guards

Fixed

  • RYBtoRGB & RGBtoRYB conversions
  • Parsing RegExp in all color spaces to be more robust with spaces before/after commas

Changed

  • Allow mixing in different color spaces

v1.1.1 - August 24, 2021

Added

  • Links to JSDoc of parsers

Fixed

  • stringCMYK() & stringXYZ() and respective parsing
  • Alpha channel value parsing

Changed

  • ColorMaster logo
  • README color space plugins section and stringRGB(), stringHSL(), stringHEX()

v1.1.0 - August 18, 2021

Added

  • Simplified logic of CM constructor
  • LAB[A] HSV[A], HWB[A], XYZ[A], LCH[A], CMYK[A] parsers - along with respective plugins - and fully tested them
  • Community documents such as CONTRIBUTING.md
  • Issue & PR templates

Fixed

  • README to include more plugin information
  • typeGuard logic to be more specific in scope
  • Logic in parsers for object clamping

Changed

  • Webpack to not give sourcemaps
  • Produce ES and CommonJS modules during bundling
  • Test CI GitHub Action to use a matrix build - test common NodeJS version in parallel
  • Exports field in package.json to show in bundlephobia
  • Adjusted Jest config to reduce CLI command

v1.0.0 - August 15, 2021

Added

  • Ability to extend plugins
  • Tree Shaking with Webpack
  • Bundle size analyzer (webpack plugin) ← only runs in production build
  • Harmony plugin
  • Mix in LCHA space (needs work to be more accurate)
  • isValid() function & format getter is more robust
  • Conversion helper functions to different color spaces
  • Option to hexa() for rounding
  • Tests for conversions
  • Ability to extend parsers → allows to extend ColorMaster instantiation by CSS name
  • LABA, LCHA, XYZA, HSVA conversion logic to and from RGBA
  • static Parsers property to simplify logic
  • Community related files & templates for issues/PRs
  • Mixing (plugin) & tests
  • Parsing tests
  • Types to color Records so that they give intellisense

Fixed

  • Negative hue parsing
  • Closest color logic by adding helper functions. Added random() outside of ColorMaster class. Start of mix() - working on RGBtoLAB & RGBtoLCH
  • Improved parsers (RegExp)
  • Fixed Jest config & adjusted coverage thresholds to be at least 95%
  • README to reflect the refactor

Changed

  • Refactor to only use RGB behind the scene
  • Parser functionality to be more general (better RegExp)
  • All accessibility functions are now more general (independent of input format)
  • ColorMaster class to make it default export a function that returns an instance
  • Opts to be alpha for some method
  • Separated parsers from conversion logic

Removed

  • Redundant typing on class method opts objects

v0.1.0 - August 1, 2021

Added

  • Functionality and tests for:

    • rotation
    • format
    • name
    • random
    • brightness
    • luminance
    • isDark
    • isLight
    • contrast
    • readableOn
    • equalTo
    • harmony (color harmonies)
    • isWarm
    • isCool
    • isTinted
    • isShaded
    • isToned
    • isPureHue
    • closestPureHue
    • closestWebSafe (web safe)
    • closestWarm
    • closestCool
  • README documentation for API

  • Support for 3/4-digit HEX
  • Size check GitHub action

Fixed

  • Tests to provide more coverage (100% coverage)
  • random() and fromName() to generate RGB color instance which user can convert using hsl() or hex()
  • Edge cases in colormaster class when generating color instances
  • GitHub actions scripts

Changed

  • Getter & Setter function names to be more general
  • name() function to search by name exactly or approximately
  • HSLAFrom() to allow user to use CSS Name instead of number for hue channel

Removed

  • Benchmark tests as they are not meaningful enough
  • Packages related to benchmark script

v0.0.7 - July 28, 2021

Added

  • HSLA and HEXA color-spaces (with tests)
  • Implementation interfaces to reduce complexity of implementation scripts (less comments)
  • Getter and Setter functions for arrays of object instances
  • Webpack to create a production build
  • npm dedupe to the pre-commit hook and post-commit/pre-push hooks
  • Functionality such as invert, saturate/desaturate, lightness/darkness, grayscale
  • Full testing of saturation/de-saturation, lighter/darker, grayscale in all color-spaces
  • NPM scripts for releasing a publication of the module - patch, minor, major

Fixed

  • Logic in HEXA & HSLA color-spaces that produced invalid conversions
  • Logic in class methods to use getter and setter functions rather than accessing private variables

Changed

  • Type file extensions to .d.ts - adjusted npm scripts accordingly
  • Release script to have pre and post
  • Default options from false to true as returning alpha in string is more common
  • Updated README & documentation

Removed

  • Throw statements (errors) by using simple validation/setting to default values

v0.0.2 to v0.0.6 - July 24, 2021

Added

  • NPM scripts to handle the module publication in a smoother and more proper manner

v0.0.1 - July 24, 2021

Added

  • Wrapper overloads to RGBColors class to let user instantiate RGB(A) objects in 4 different ways
  • Continuous Integration
  • Testing
  • Linting and format checking scripts
  • Github workflows
  • README (with logo)
  • Pre-commit hook to lint and format
  • Pre-push hook to test
  • Benchmark testing
  • Documentation with Typedoc
  • np for automated publishing

Changed

  • Class method names to better reflect functionality