π 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:
RGBA Color Space
// 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)"
HSLA Color Space
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)"
HEXA Color Space
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)
ColorMaster(color)
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"
random()
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
stringRGB(opts?)
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)"
stringHEX(opts?)
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"
stringHSL(opts?)
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)"
name()
(name plugin)
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
format
Retrieve the format of color instance (what is the color space)
import CM from "colormaster";
CM("rgba(255, 0, 0, 1)").format; // "rgb"
red
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"
green
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"
blue
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"
alpha
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"
hue
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
saturation
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
lightness
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
rgba()
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 }"
hsla()
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 }"
hexa(opts?)
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
hueTo(value | cssName)
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"
hueBy(delta)
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"
alphaTo(value)
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"
alphaBy(delta)
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"
saturationTo(value)
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)"
saturateBy(delta)
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)"
desaturateBy(delta)
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)"
lightnessTo(value)
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)"
lighterBy(delta)
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)"
darkerBy(delta)
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)"
grayscale()
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)"
rotate(value)
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)"
invert(opts?)
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.
brightness(opts?)
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
luminance(opts?)
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
contrast(opts?)
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"
isLight()
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
isDark()
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
readableOn(opts?)
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)
equalTo(compareColor?)
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
isWarm()
"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
isCool()
"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
isTinted()
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
isShaded()
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
isToned()
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
isPureHue(opts)
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
closestWebSafe()
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)"
closestCool()
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)"
closestWarm()
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)"
closestPureHue()
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)
harmony(opts?)
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)
mix(opts?)
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.
MixPlugin
(Color Mixtures | 2.78KB)
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]);
...
NamePlugin
(CSS Names | 2.21KB)
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]);
...
A11yPlugin
(Accessibility | 1.97KB)
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]);
...
HarmonyPlugin
(Color Harmonies | 0.639KB)
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.
LCHPlugin
(LCH[A] Color Space | 1.74KB)
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)"
LUVPlugin
(LUV[A] Color Space | 1.73KB)
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)"
LABPlugin
(LAB[A] Color Space | 1.63KB)
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)"
UVWPlugin
(UVW[A] Color Space | 1.54KB)
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)"
XYZPlugin
(XYZ[A] Color Space | 1.44KB)
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)"
HWBPlugin
(HWB[A] Color Space | 1.15KB)
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)"
HSVPlugin
(HSV[A] Color Space | 1.06KB)
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)"
RYBPlugin
(RYB[A] Color Space | 0.921KB)
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)"
CMYKPlugin
(CMYK[A] Color Space | 0.906KB)
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.
RGBA Types
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
HEXA Types
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
HSLA Types
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
- API documentation can be found on our documentation site.
- A more in depth guide can be seen in our Wikis.
Β
π 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:
- [x] CSS/HTML name handling
- [x] Color wheel manipulation (rotation, saturation, lightness, grayscale, etc.)
- [x] Proper handling of improper input values
- [x]
brightness
,luminance
,contrast
accessibility functions - along with other helpful wrappers - [x] Plugin Mechanism to extend functionality of core library
- [x] Color harmony generation
- [x] Color mixing (done in
LCHA
color space) - [x]
RGB[A]
color space conversion & parsing - [x]
HEX[A]
color space conversion & parsing - [x]
HSL[A]
color space conversion & parsing - [x]
HSV[A]
color space conversion & parsing - [x]
HWB[A]
color space conversion & parsing - [x]
XYZ[A]
color space conversion & parsing - [x]
LAB[A]
color space conversion & parsing - [x]
LCH[A]
color space conversion & parsing - [x]
LUV[A]
color space conversion & parsing - [x]
UVW[A]
color space conversion & parsing - [x]
RYB[A]
color space conversion & parsing - [x]
CMYK[A]
color space conversion & parsing
Note: suggestions and/or requests (in addition to the above) are always welcome!
Β
License
All of the code used in ColorMaster is released under the MIT License.