Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ctrl/tinycolor

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ctrl/tinycolor - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

color-bounds.d.ts

931

bundles/tinycolor.es2015.js

@@ -0,1 +1,286 @@

/**
* Take input from [0, n] and return it as [0, 1]
*/
function bound01(n, max) {
if (isOnePointZero(n)) {
n = '100%';
}
const processPercent = isPercentage(n);
n = max === 360 ? n : Math.min(max, Math.max(0, parseFloat(n)));
// Automatically convert percentage into number
if (processPercent) {
n = parseInt(String(n * max), 10) / 100;
}
// Handle floating point rounding errors
if (Math.abs(n - max) < 0.000001) {
return 1;
}
// Convert into [0, 1] range if it isn't already
if (max === 360) {
// If n is a hue given in degrees,
// wrap around out-of-range values into [0, 360] range
// then convert into [0, 1].
n = (n < 0 ? n % max + max : n % max) / parseFloat(String(max));
}
else {
// If n not a hue given in degrees
// Convert into [0, 1] range if it isn't already.
n = (n % max) / parseFloat(String(max));
}
return n;
}
/** Force a number between 0 and 1 */
function clamp01(val) {
return Math.min(1, Math.max(0, val));
}
/**
* Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
* <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
*/
function isOnePointZero(n) {
return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1;
}
/** Check to see if string passed in is a percentage */
function isPercentage(n) {
return typeof n === 'string' && n.indexOf('%') !== -1;
}
/**
* Return a valid alpha value [0,1] with all invalid values being set to 1
*/
function boundAlpha(a) {
a = parseFloat(a);
if (isNaN(a) || a < 0 || a > 1) {
a = 1;
}
return a;
}
/** Replace a decimal with it's percentage value */
function convertToPercentage(n) {
if (n <= 1) {
return +n * 100 + '%';
}
return n;
}
/** Force a hex value to have 2 characters */
function pad2(c) {
return c.length === 1 ? '0' + c : '' + c;
}
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
/**
* Handle bounds / percentage checking to conform to CSS color spec
* <http://www.w3.org/TR/css3-color/>
* *Assumes:* r, g, b in [0, 255] or [0, 1]
* *Returns:* { r, g, b } in [0, 255]
*/
function rgbToRgb(r, g, b) {
return {
r: bound01(r, 255) * 255,
g: bound01(g, 255) * 255,
b: bound01(b, 255) * 255,
};
}
/**
* Converts an RGB color value to HSL.
* *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
* *Returns:* { h, s, l } in [0,1]
*/
function rgbToHsl(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
let s = 0;
const l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
}
else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h, s, l };
}
/**
* Converts an HSL color value to RGB.
*
* *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
* *Returns:* { r, g, b } in the set [0, 255]
*/
function hslToRgb(h, s, l) {
let r;
let g;
let b;
h = bound01(h, 360);
s = bound01(s, 100);
l = bound01(l, 100);
function hue2rgb(p, q, t) {
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
}
if (s === 0) {
r = g = b = l; // achromatic
}
else {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return { r: r * 255, g: g * 255, b: b * 255 };
}
/**
* Converts an RGB color value to HSV
*
* *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
* *Returns:* { h, s, v } in [0,1]
*/
function rgbToHsv(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
const v = max;
const d = max - min;
const s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0; // achromatic
}
else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h: h, s: s, v: v };
}
/**
* Converts an HSV color value to RGB.
*
* *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
* *Returns:* { r, g, b } in the set [0, 255]
*/
function hsvToRgb(h, s, v) {
h = bound01(h, 360) * 6;
s = bound01(s, 100);
v = bound01(v, 100);
const i = Math.floor(h);
const f = h - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
const mod = i % 6;
const r = [v, q, p, p, t, v][mod];
const g = [t, v, v, q, p, p][mod];
const b = [p, p, t, v, v, q][mod];
return { r: r * 255, g: g * 255, b: b * 255 };
}
/**
* Converts an RGB color to hex
*
* Assumes r, g, and b are contained in the set [0, 255]
* Returns a 3 or 6 character hex
*/
function rgbToHex(r, g, b, allow3Char) {
const hex = [
pad2(Math.round(r).toString(16)),
pad2(Math.round(g).toString(16)),
pad2(Math.round(b).toString(16)),
];
// Return a 3 character hex if possible
if (allow3Char &&
hex[0].charAt(0) === hex[0].charAt(1) &&
hex[1].charAt(0) === hex[1].charAt(1) &&
hex[2].charAt(0) === hex[2].charAt(1)) {
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
}
return hex.join('');
}
/**
* Converts an RGBA color plus alpha transparency to hex
*
* Assumes r, g, b are contained in the set [0, 255] and
* a in [0, 1]. Returns a 4 or 8 character rgba hex
*/
function rgbaToHex(r, g, b, a, allow4Char) {
const hex = [
pad2(Math.round(r).toString(16)),
pad2(Math.round(g).toString(16)),
pad2(Math.round(b).toString(16)),
pad2(convertDecimalToHex(a)),
];
// Return a 4 character hex if possible
if (allow4Char &&
hex[0].charAt(0) === hex[0].charAt(1) &&
hex[1].charAt(0) === hex[1].charAt(1) &&
hex[2].charAt(0) === hex[2].charAt(1) &&
hex[3].charAt(0) === hex[3].charAt(1)) {
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
}
return hex.join('');
}
/**
* Converts an RGBA color to an ARGB Hex8 string
* Rarely used, but required for "toFilter()"
*/
function rgbaToArgbHex(r, g, b, a) {
const hex = [
pad2(convertDecimalToHex(a)),
pad2(Math.round(r).toString(16)),
pad2(Math.round(g).toString(16)),
pad2(Math.round(b).toString(16)),
];
return hex.join('');
}
/** Converts a decimal to a hex value */
function convertDecimalToHex(d) {
return Math.round(parseFloat(d) * 255).toString(16);
}
/** Converts a hex value to a decimal */
function convertHexToDecimal(h) {
return parseIntFromHex(h) / 255;
}
/** Parse a base-16 hex value into a base-10 integer */
function parseIntFromHex(val) {
return parseInt(val, 16);
}
// https://github.com/bahamas10/css-color-names/blob/master/css-color-names.json

@@ -154,59 +439,2 @@ const names = {

/**
* Take input from [0, n] and return it as [0, 1]
*/
function bound01(n, max) {
if (isOnePointZero(n)) {
n = '100%';
}
const processPercent = isPercentage(n);
n = Math.min(max, Math.max(0, parseFloat(n)));
// Automatically convert percentage into number
if (processPercent) {
n = parseInt(String(n * max), 10) / 100;
}
// Handle floating point rounding errors
if (Math.abs(n - max) < 0.000001) {
return 1;
}
// Convert into [0, 1] range if it isn't already
return (n % max) / parseFloat(String(max));
}
/** Force a number between 0 and 1 */
function clamp01(val) {
return Math.min(1, Math.max(0, val));
}
/**
* Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
* <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
*/
function isOnePointZero(n) {
return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1;
}
/** Check to see if string passed in is a percentage */
function isPercentage(n) {
return typeof n === 'string' && n.indexOf('%') !== -1;
}
/**
* Return a valid alpha value [0,1] with all invalid values being set to 1
*/
function boundAlpha(a) {
a = parseFloat(a);
if (isNaN(a) || a < 0 || a > 1) {
a = 1;
}
return a;
}
/** Replace a decimal with it's percentage value */
function convertToPercentage(n) {
if (n <= 1) {
return n * 100 + '%';
}
return n;
}
/** Force a hex value to have 2 characters */
function pad2(c) {
return c.length === 1 ? '0' + c : '' + c;
}
/**
* Given a string or object, convert that input to RGB

@@ -380,6 +608,2 @@ *

}
/** Parse a base-16 hex value into a base-10 integer */
function parseIntFromHex(val) {
return parseInt(val, 16);
}
/**

@@ -393,215 +617,2 @@ * Check to see if it looks like a CSS unit

// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
/**
* Handle bounds / percentage checking to conform to CSS color spec
* <http://www.w3.org/TR/css3-color/>
* *Assumes:* r, g, b in [0, 255] or [0, 1]
* *Returns:* { r, g, b } in [0, 255]
*/
function rgbToRgb(r, g, b) {
return {
r: bound01(r, 255) * 255,
g: bound01(g, 255) * 255,
b: bound01(b, 255) * 255,
};
}
/**
* Converts an RGB color value to HSL.
* *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
* *Returns:* { h, s, l } in [0,1]
*/
function rgbToHsl(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
let s = 0;
const l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
}
else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h, s, l };
}
/**
* Converts an HSL color value to RGB.
*
* *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
* *Returns:* { r, g, b } in the set [0, 255]
*/
function hslToRgb(h, s, l) {
let r;
let g;
let b;
h = bound01(h, 360);
s = bound01(s, 100);
l = bound01(l, 100);
function hue2rgb(p, q, t) {
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
}
if (s === 0) {
r = g = b = l; // achromatic
}
else {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return { r: r * 255, g: g * 255, b: b * 255 };
}
/**
* Converts an RGB color value to HSV
*
* *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
* *Returns:* { h, s, v } in [0,1]
*/
function rgbToHsv(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
const v = max;
const d = max - min;
const s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0; // achromatic
}
else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h: h, s: s, v: v };
}
/**
* Converts an HSV color value to RGB.
*
* *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
* *Returns:* { r, g, b } in the set [0, 255]
*/
function hsvToRgb(h, s, v) {
h = bound01(h, 360) * 6;
s = bound01(s, 100);
v = bound01(v, 100);
const i = Math.floor(h);
const f = h - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
const mod = i % 6;
const r = [v, q, p, p, t, v][mod];
const g = [t, v, v, q, p, p][mod];
const b = [p, p, t, v, v, q][mod];
return { r: r * 255, g: g * 255, b: b * 255 };
}
/**
* Converts an RGB color to hex
*
* Assumes r, g, and b are contained in the set [0, 255]
* Returns a 3 or 6 character hex
*/
function rgbToHex(r, g, b, allow3Char) {
const hex = [
pad2(Math.round(r).toString(16)),
pad2(Math.round(g).toString(16)),
pad2(Math.round(b).toString(16)),
];
// Return a 3 character hex if possible
if (allow3Char &&
hex[0].charAt(0) === hex[0].charAt(1) &&
hex[1].charAt(0) === hex[1].charAt(1) &&
hex[2].charAt(0) === hex[2].charAt(1)) {
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
}
return hex.join('');
}
/**
* Converts an RGBA color plus alpha transparency to hex
*
* Assumes r, g, b are contained in the set [0, 255] and
* a in [0, 1]. Returns a 4 or 8 character rgba hex
*/
function rgbaToHex(r, g, b, a, allow4Char) {
const hex = [
pad2(Math.round(r).toString(16)),
pad2(Math.round(g).toString(16)),
pad2(Math.round(b).toString(16)),
pad2(convertDecimalToHex(a)),
];
// Return a 4 character hex if possible
if (allow4Char &&
hex[0].charAt(0) === hex[0].charAt(1) &&
hex[1].charAt(0) === hex[1].charAt(1) &&
hex[2].charAt(0) === hex[2].charAt(1) &&
hex[3].charAt(0) === hex[3].charAt(1)) {
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
}
return hex.join('');
}
/**
* Converts an RGBA color to an ARGB Hex8 string
* Rarely used, but required for "toFilter()"
*/
function rgbaToArgbHex(r, g, b, a) {
const hex = [
pad2(convertDecimalToHex(a)),
pad2(Math.round(r).toString(16)),
pad2(Math.round(g).toString(16)),
pad2(Math.round(b).toString(16)),
];
return hex.join('');
}
/** Converts a decimal to a hex value */
function convertDecimalToHex(d) {
return Math.round(parseFloat(d) * 255).toString(16);
}
/** Converts a hex value to a decimal */
function convertHexToDecimal(h) {
return parseIntFromHex(h) / 255;
}
class TinyColor {

@@ -874,4 +885,3 @@ constructor(color = '', opts = {}) {

* Lighten the color a given amount. Providing 100 will always return white.
*
* @param amount - The amount to lighten by. The valid range is 0 to 100.
* @param amount - valid between 1-100
*/

@@ -884,2 +894,6 @@ lighten(amount = 10) {

}
/**
* Brighten the color a given amount, from 0 to 100.
* @param amount - valid between 1-100
*/
brighten(amount = 10) {

@@ -892,2 +906,7 @@ const rgb = this.toRgb();

}
/**
* Darken the color a given amount, from 0 to 100.
* Providing 100 will always return black.
* @param amount - valid between 1-100
*/
darken(amount = 10) {

@@ -899,2 +918,23 @@ const hsl = this.toHsl();

}
/**
* Mix the color with pure white, from 0 to 100.
* Providing 0 will do nothing, providing 100 will always return white.
* @param amount - valid between 1-100
*/
tint(amount = 10) {
return this.mix('white', amount);
}
/**
* Mix the color with pure black, from 0 to 100.
* Providing 0 will do nothing, providing 100 will always return black.
* @param amount - valid between 1-100
*/
shade(amount = 10) {
return this.mix('black', amount);
}
/**
* Desaturate the color a given amount, from 0 to 100.
* Providing 100 will is the same as calling greyscale
* @param amount - valid between 1-100
*/
desaturate(amount = 10) {

@@ -906,2 +946,6 @@ const hsl = this.toHsl();

}
/**
* Saturate the color a given amount, from 0 to 100.
* @param amount - valid between 1-100
*/
saturate(amount = 10) {

@@ -913,2 +957,6 @@ const hsl = this.toHsl();

}
/**
* Completely desaturates a color into greyscale.
* Same as calling `desaturate(100)`
*/
greyscale() {

@@ -927,2 +975,14 @@ return this.desaturate(100);

}
mix(color, amount = 50) {
const rgb1 = this.toRgb();
const rgb2 = new TinyColor(color).toRgb();
const p = amount / 100;
const rgba = {
r: (rgb2.r - rgb1.r) * p + rgb1.r,
g: (rgb2.g - rgb1.g) * p + rgb1.g,
b: (rgb2.b - rgb1.b) * p + rgb1.b,
a: (rgb2.a - rgb1.a) * p + rgb1.a,
};
return new TinyColor(rgba);
}
analogous(results = 6, slices = 30) {

@@ -969,38 +1029,20 @@ const hsl = this.toHsl();

triad() {
const hsl = this.toHsl();
const h = hsl.h;
return [
this,
new TinyColor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
new TinyColor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }),
];
return this.polyad(3);
}
tetrad() {
const hsl = this.toHsl();
const h = hsl.h;
return [
this,
new TinyColor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
new TinyColor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
new TinyColor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }),
];
return this.polyad(4);
}
/**
* If input is an object, force 1 into "1.0" to handle ratios properly
* String input requires "1.0" as input, so 1 will be treated as 1
* Get polyad colors, like (for 1, 2, 3, 4, 5, 6, 7, 8, etc...)
* monad, dyad, triad, tetrad, pentad, hexad, heptad, octad, etc...
*/
fromRatio(color, opts) {
if (typeof color === 'object') {
const newColor = {};
for (const key of Object.keys(color)) {
if (key === 'a') {
newColor[key] = color[key];
}
else {
newColor[key] = convertToPercentage(color[key]);
}
}
color = newColor;
polyad(n) {
const hsl = this.toHsl();
const h = hsl.h;
const result = [this];
const increment = 360 / n;
for (let i = 1; i < n; i++) {
result.push(new TinyColor({ h: (h + i * increment) % 360, s: hsl.s, l: hsl.l }));
}
return new TinyColor(color, opts);
return result;
}

@@ -1013,25 +1055,4 @@ /**

}
random() {
return this.fromRatio({
r: Math.random(),
g: Math.random(),
b: Math.random(),
});
}
}
function mix(color1, color2, amount) {
amount = amount === 0 ? 0 : amount || 50;
const rgb1 = new TinyColor(color1).toRgb();
const rgb2 = new TinyColor(color2).toRgb();
const p = amount / 100;
const rgba = {
r: (rgb2.r - rgb1.r) * p + rgb1.r,
g: (rgb2.g - rgb1.g) * p + rgb1.g,
b: (rgb2.b - rgb1.b) * p + rgb1.b,
a: (rgb2.a - rgb1.a) * p + rgb1.a,
};
return new TinyColor(rgba);
}
// Readability Functions

@@ -1131,3 +1152,257 @@ // ---------------------

export { names, TinyColor, mix, readability, isReadable, mostReadable, toMsFilter };
/**
* If input is an object, force 1 into "1.0" to handle ratios properly
* String input requires "1.0" as input, so 1 will be treated as 1
*/
function fromRatio(ratio, opts) {
const newColor = {
r: convertToPercentage(ratio.r),
g: convertToPercentage(ratio.g),
b: convertToPercentage(ratio.b),
};
if (ratio.a !== undefined) {
newColor.a = +ratio.a;
}
return new TinyColor(newColor, opts);
}
function fromLegacyRandom() {
return new TinyColor({
r: Math.random(),
g: Math.random(),
b: Math.random(),
});
}
const bounds = [
{
name: 'monochrome',
hueRange: null,
lowerBounds: [[0, 0], [100, 0]],
},
{
name: 'red',
hueRange: [-26, 18],
lowerBounds: [
[20, 100],
[30, 92],
[40, 89],
[50, 85],
[60, 78],
[70, 70],
[80, 60],
[90, 55],
[100, 50],
],
},
{
name: 'orange',
hueRange: [19, 46],
lowerBounds: [[20, 100], [30, 93], [40, 88], [50, 86], [60, 85], [70, 70], [100, 70]],
},
{
name: 'yellow',
hueRange: [47, 62],
lowerBounds: [[25, 100], [40, 94], [50, 89], [60, 86], [70, 84], [80, 82], [90, 80], [100, 75]],
},
{
name: 'green',
hueRange: [63, 178],
lowerBounds: [[30, 100], [40, 90], [50, 85], [60, 81], [70, 74], [80, 64], [90, 50], [100, 40]],
},
{
name: 'blue',
hueRange: [179, 257],
lowerBounds: [
[20, 100],
[30, 86],
[40, 80],
[50, 74],
[60, 60],
[70, 52],
[80, 44],
[90, 39],
[100, 35],
],
},
{
name: 'purple',
hueRange: [258, 282],
lowerBounds: [
[20, 100],
[30, 87],
[40, 79],
[50, 70],
[60, 65],
[70, 59],
[80, 52],
[90, 45],
[100, 42],
],
},
{
name: 'pink',
hueRange: [283, 334],
lowerBounds: [[20, 100], [30, 90], [40, 86], [60, 84], [80, 80], [90, 75], [100, 73]],
},
];
// randomColor by David Merfield under the CC0 license
function fromRandom(options = {}) {
// Check if we need to generate multiple colors
if (options.count !== undefined) {
const totalColors = options.count;
const colors = [];
options.count = undefined;
while (totalColors > colors.length) {
// Since we're generating multiple colors,
// incremement the seed. Otherwise we'd just
// generate the same color each time...
if (options.seed) {
options.seed += 1;
}
colors.push(fromRandom(options)[0]);
}
options.count = totalColors;
return colors;
}
// First we pick a hue (H)
const h = pickHue(options.hue, options.seed);
// Then use H to determine saturation (S)
const s = pickSaturation(h, options);
// Then use S and H to determine brightness (B).
const v = pickBrightness(h, s, options);
const res = { h, s, v };
if (options.alpha !== undefined) {
res.a = options.alpha;
}
// Then we return the HSB color in the desired format
return [new TinyColor(res)];
}
function pickHue(hue, seed) {
const hueRange = getHueRange(hue);
let res = randomWithin(hueRange, seed);
// Instead of storing red as two seperate ranges,
// we group them, using negative numbers
if (res < 0) {
res = 360 + res;
}
return res;
}
function pickSaturation(hue, options) {
if (options.hue === 'monochrome') {
return 0;
}
if (options.luminosity === 'random') {
return randomWithin([0, 100], options.seed);
}
const saturationRange = getColorInfo(hue).saturationRange;
let sMin = saturationRange[0];
let sMax = saturationRange[1];
switch (options.luminosity) {
case 'bright':
sMin = 55;
break;
case 'dark':
sMin = sMax - 10;
break;
case 'light':
sMax = 55;
break;
}
return randomWithin([sMin, sMax], options.seed);
}
function pickBrightness(H, S, options) {
let bMin = getMinimumBrightness(H, S);
let bMax = 100;
switch (options.luminosity) {
case 'dark':
bMax = bMin + 20;
break;
case 'light':
bMin = (bMax + bMin) / 2;
break;
case 'random':
bMin = 0;
bMax = 100;
break;
}
return randomWithin([bMin, bMax], options.seed);
}
function getMinimumBrightness(H, S) {
const lowerBounds = getColorInfo(H).lowerBounds;
for (let i = 0; i < lowerBounds.length - 1; i++) {
const s1 = lowerBounds[i][0];
const v1 = lowerBounds[i][1];
const s2 = lowerBounds[i + 1][0];
const v2 = lowerBounds[i + 1][1];
if (S >= s1 && S <= s2) {
const m = (v2 - v1) / (s2 - s1);
const b = v1 - m * s1;
return m * S + b;
}
}
return 0;
}
function getHueRange(colorInput) {
const num = parseInt(colorInput, 10);
if (!Number.isNaN(num) && num < 360 && num > 0) {
return [num, num];
}
if (typeof colorInput === 'string') {
const namedColor = bounds.find(n => n.name === colorInput);
if (namedColor) {
const color = defineColor(namedColor);
if (color.hueRange) {
return color.hueRange;
}
}
const parsed = new TinyColor(colorInput);
if (parsed.isValid) {
const hue = parsed.toHsv().h;
return [hue, hue];
}
}
return [0, 360];
}
function getColorInfo(hue) {
// Maps red colors to make picking hue easier
if (hue >= 334 && hue <= 360) {
hue -= 360;
}
for (const bound of bounds) {
const color = defineColor(bound);
if (color.hueRange && hue >= color.hueRange[0] && hue <= color.hueRange[1]) {
return color;
}
}
throw Error('Color not found');
}
function randomWithin(range, seed) {
if (seed === undefined) {
return Math.floor(range[0] + Math.random() * (range[1] + 1 - range[0]));
}
else {
// Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
const max = range[1] || 1;
const min = range[0] || 0;
seed = (seed * 9301 + 49297) % 233280;
const rnd = seed / 233280.0;
return Math.floor(min + rnd * (max - min));
}
}
function defineColor(bound) {
const sMin = bound.lowerBounds[0][0];
const sMax = bound.lowerBounds[bound.lowerBounds.length - 1][0];
const bMin = bound.lowerBounds[bound.lowerBounds.length - 1][1];
const bMax = bound.lowerBounds[0][1];
return {
name: bound.name,
hueRange: bound.hueRange,
lowerBounds: bound.lowerBounds,
saturationRange: [sMin, sMax],
brightnessRange: [bMin, bMax],
};
}
export { names, TinyColor, readability, isReadable, mostReadable, toMsFilter, fromRatio, fromLegacyRandom, inputToRGB, stringInputToObject, isValidCSSUnit, fromRandom };
//# sourceMappingURL=tinycolor.es2015.js.map

@@ -78,1 +78,3 @@ /**

export declare function convertHexToDecimal(h: string): number;
/** Parse a base-16 hex value into a base-10 integer */
export declare function parseIntFromHex(val: string): number;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const format_input_1 = require("./format-input");
const util_1 = require("./util");

@@ -224,5 +223,10 @@ // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:

function convertHexToDecimal(h) {
return format_input_1.parseIntFromHex(h) / 255;
return parseIntFromHex(h) / 255;
}
exports.convertHexToDecimal = convertHexToDecimal;
/** Parse a base-16 hex value into a base-10 integer */
function parseIntFromHex(val) {
return parseInt(val, 16);
}
exports.parseIntFromHex = parseIntFromHex;
//# sourceMappingURL=conversion.js.map

@@ -33,4 +33,2 @@ import { HSL, HSLA, HSV, HSVA, RGB, RGBA } from './interfaces';

export declare function stringInputToObject(color: string): any;
/** Parse a base-16 hex value into a base-10 integer */
export declare function parseIntFromHex(val: string): number;
/**

@@ -37,0 +35,0 @@ * Check to see if it looks like a CSS unit

@@ -139,5 +139,5 @@ "use strict";

return {
r: parseIntFromHex(match[1]),
g: parseIntFromHex(match[2]),
b: parseIntFromHex(match[3]),
r: conversion_1.parseIntFromHex(match[1]),
g: conversion_1.parseIntFromHex(match[2]),
b: conversion_1.parseIntFromHex(match[3]),
a: conversion_1.convertHexToDecimal(match[4]),

@@ -150,5 +150,5 @@ format: named ? 'name' : 'hex8',

return {
r: parseIntFromHex(match[1]),
g: parseIntFromHex(match[2]),
b: parseIntFromHex(match[3]),
r: conversion_1.parseIntFromHex(match[1]),
g: conversion_1.parseIntFromHex(match[2]),
b: conversion_1.parseIntFromHex(match[3]),
format: named ? 'name' : 'hex',

@@ -160,5 +160,5 @@ };

return {
r: parseIntFromHex(match[1] + match[1]),
g: parseIntFromHex(match[2] + match[2]),
b: parseIntFromHex(match[3] + match[3]),
r: conversion_1.parseIntFromHex(match[1] + match[1]),
g: conversion_1.parseIntFromHex(match[2] + match[2]),
b: conversion_1.parseIntFromHex(match[3] + match[3]),
a: conversion_1.convertHexToDecimal(match[4] + match[4]),

@@ -171,5 +171,5 @@ format: named ? 'name' : 'hex8',

return {
r: parseIntFromHex(match[1] + match[1]),
g: parseIntFromHex(match[2] + match[2]),
b: parseIntFromHex(match[3] + match[3]),
r: conversion_1.parseIntFromHex(match[1] + match[1]),
g: conversion_1.parseIntFromHex(match[2] + match[2]),
b: conversion_1.parseIntFromHex(match[3] + match[3]),
format: named ? 'name' : 'hex',

@@ -181,7 +181,2 @@ };

exports.stringInputToObject = stringInputToObject;
/** Parse a base-16 hex value into a base-10 integer */
function parseIntFromHex(val) {
return parseInt(val, 16);
}
exports.parseIntFromHex = parseIntFromHex;
/**

@@ -188,0 +183,0 @@ * Check to see if it looks like a CSS unit

@@ -130,10 +130,43 @@ import { HSL, HSLA, HSV, HSVA, RGB, RGBA } from './interfaces';

* Lighten the color a given amount. Providing 100 will always return white.
*
* @param amount - The amount to lighten by. The valid range is 0 to 100.
* @param amount - valid between 1-100
*/
lighten(amount?: number): TinyColor;
/**
* Brighten the color a given amount, from 0 to 100.
* @param amount - valid between 1-100
*/
brighten(amount?: number): TinyColor;
/**
* Darken the color a given amount, from 0 to 100.
* Providing 100 will always return black.
* @param amount - valid between 1-100
*/
darken(amount?: number): TinyColor;
/**
* Mix the color with pure white, from 0 to 100.
* Providing 0 will do nothing, providing 100 will always return white.
* @param amount - valid between 1-100
*/
tint(amount?: number): TinyColor;
/**
* Mix the color with pure black, from 0 to 100.
* Providing 0 will do nothing, providing 100 will always return black.
* @param amount - valid between 1-100
*/
shade(amount?: number): TinyColor;
/**
* Desaturate the color a given amount, from 0 to 100.
* Providing 100 will is the same as calling greyscale
* @param amount - valid between 1-100
*/
desaturate(amount?: number): TinyColor;
/**
* Saturate the color a given amount, from 0 to 100.
* @param amount - valid between 1-100
*/
saturate(amount?: number): TinyColor;
/**
* Completely desaturates a color into greyscale.
* Same as calling `desaturate(100)`
*/
greyscale(): TinyColor;

@@ -145,2 +178,3 @@ /**

spin(amount: number): TinyColor;
mix(color: ColorInput, amount?: number): TinyColor;
analogous(results?: number, slices?: number): TinyColor[];

@@ -156,6 +190,6 @@ /**

/**
* If input is an object, force 1 into "1.0" to handle ratios properly
* String input requires "1.0" as input, so 1 will be treated as 1
* Get polyad colors, like (for 1, 2, 3, 4, 5, 6, 7, 8, etc...)
* monad, dyad, triad, tetrad, pentad, hexad, heptad, octad, etc...
*/
fromRatio(color: any, opts?: any): TinyColor;
polyad(n: number): TinyColor[];
/**

@@ -165,3 +199,2 @@ * compare color vs current color

equals(color?: ColorInput): boolean;
random(): TinyColor;
}

@@ -274,4 +274,3 @@ "use strict";

* Lighten the color a given amount. Providing 100 will always return white.
*
* @param amount - The amount to lighten by. The valid range is 0 to 100.
* @param amount - valid between 1-100
*/

@@ -284,2 +283,6 @@ lighten(amount = 10) {

}
/**
* Brighten the color a given amount, from 0 to 100.
* @param amount - valid between 1-100
*/
brighten(amount = 10) {

@@ -292,2 +295,7 @@ const rgb = this.toRgb();

}
/**
* Darken the color a given amount, from 0 to 100.
* Providing 100 will always return black.
* @param amount - valid between 1-100
*/
darken(amount = 10) {

@@ -299,2 +307,23 @@ const hsl = this.toHsl();

}
/**
* Mix the color with pure white, from 0 to 100.
* Providing 0 will do nothing, providing 100 will always return white.
* @param amount - valid between 1-100
*/
tint(amount = 10) {
return this.mix('white', amount);
}
/**
* Mix the color with pure black, from 0 to 100.
* Providing 0 will do nothing, providing 100 will always return black.
* @param amount - valid between 1-100
*/
shade(amount = 10) {
return this.mix('black', amount);
}
/**
* Desaturate the color a given amount, from 0 to 100.
* Providing 100 will is the same as calling greyscale
* @param amount - valid between 1-100
*/
desaturate(amount = 10) {

@@ -306,2 +335,6 @@ const hsl = this.toHsl();

}
/**
* Saturate the color a given amount, from 0 to 100.
* @param amount - valid between 1-100
*/
saturate(amount = 10) {

@@ -313,2 +346,6 @@ const hsl = this.toHsl();

}
/**
* Completely desaturates a color into greyscale.
* Same as calling `desaturate(100)`
*/
greyscale() {

@@ -327,2 +364,14 @@ return this.desaturate(100);

}
mix(color, amount = 50) {
const rgb1 = this.toRgb();
const rgb2 = new TinyColor(color).toRgb();
const p = amount / 100;
const rgba = {
r: (rgb2.r - rgb1.r) * p + rgb1.r,
g: (rgb2.g - rgb1.g) * p + rgb1.g,
b: (rgb2.b - rgb1.b) * p + rgb1.b,
a: (rgb2.a - rgb1.a) * p + rgb1.a,
};
return new TinyColor(rgba);
}
analogous(results = 6, slices = 30) {

@@ -369,38 +418,20 @@ const hsl = this.toHsl();

triad() {
const hsl = this.toHsl();
const h = hsl.h;
return [
this,
new TinyColor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
new TinyColor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }),
];
return this.polyad(3);
}
tetrad() {
const hsl = this.toHsl();
const h = hsl.h;
return [
this,
new TinyColor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
new TinyColor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
new TinyColor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }),
];
return this.polyad(4);
}
/**
* If input is an object, force 1 into "1.0" to handle ratios properly
* String input requires "1.0" as input, so 1 will be treated as 1
* Get polyad colors, like (for 1, 2, 3, 4, 5, 6, 7, 8, etc...)
* monad, dyad, triad, tetrad, pentad, hexad, heptad, octad, etc...
*/
fromRatio(color, opts) {
if (typeof color === 'object') {
const newColor = {};
for (const key of Object.keys(color)) {
if (key === 'a') {
newColor[key] = color[key];
}
else {
newColor[key] = util_1.convertToPercentage(color[key]);
}
}
color = newColor;
polyad(n) {
const hsl = this.toHsl();
const h = hsl.h;
const result = [this];
const increment = 360 / n;
for (let i = 1; i < n; i++) {
result.push(new TinyColor({ h: (h + i * increment) % 360, s: hsl.s, l: hsl.l }));
}
return new TinyColor(color, opts);
return result;
}

@@ -413,11 +444,4 @@ /**

}
random() {
return this.fromRatio({
r: Math.random(),
g: Math.random(),
b: Math.random(),
});
}
}
exports.TinyColor = TinyColor;
//# sourceMappingURL=index.js.map
{
"name": "@ctrl/tinycolor",
"version": "1.0.0",
"version": "1.1.0",
"description": "Fast, small color manipulation and conversion for JavaScript",

@@ -24,2 +24,3 @@ "author": "Scott Cooper <scttcper@gmail.com>",

"module": "./bundles/tinycolor.es2015.js",
"sideEffects": false,
"typings": "./public_api.d.ts",

@@ -42,25 +43,25 @@ "scripts": {

"devDependencies": {
"@commitlint/cli": "^6.1.3",
"@commitlint/config-conventional": "^6.1.3",
"@types/fs-extra": "^5.0.2",
"@types/jest": "^22.2.3",
"@types/node": "^10.0.0",
"commitizen": "^2.9.6",
"cz-conventional-changelog": "^2.1.0",
"fs-extra": "^5.0.0",
"husky": "^1.0.0-rc.2",
"jest": "^22.4.3",
"prettier": "^1.12.1",
"rimraf": "^2.6.2",
"rollup": "^0.58.2",
"rollup-plugin-sourcemaps": "^0.4.2",
"semantic-release": "^15.1.7",
"travis-deploy-once": "^5.0.0",
"ts-jest": "^22.4.4",
"ts-node": "^6.0.2",
"tslint": "^5.9.1",
"tslint-config-prettier": "^1.12.0",
"tslint-config-standard": "^7.0.0",
"typedoc": "^0.11.1",
"typescript": "^2.8.3"
"@commitlint/cli": "6.1.3",
"@commitlint/config-conventional": "6.1.3",
"@types/fs-extra": "5.0.2",
"@types/jest": "22.2.3",
"@types/node": "10.0.1",
"commitizen": "2.9.6",
"cz-conventional-changelog": "2.1.0",
"fs-extra": "6.0.0",
"husky": "1.0.0-rc.2",
"jest": "22.4.3",
"prettier": "1.12.1",
"rimraf": "2.6.2",
"rollup": "0.58.2",
"rollup-plugin-sourcemaps": "0.4.2",
"semantic-release": "15.1.8",
"travis-deploy-once": "5.0.0",
"ts-jest": "22.4.4",
"ts-node": "6.0.2",
"tslint": "5.9.1",
"tslint-config-prettier": "1.12.0",
"tslint-config-standard": "7.0.0",
"typedoc": "0.11.1",
"typescript": "2.8.3"
},

@@ -67,0 +68,0 @@ "release": {

export * from './index';
export { default as names } from './css-color-names';
export * from './mix';
export * from './readability';
export * from './to-ms-filter';
export * from './from-ratio';
export * from './format-input';
export * from './random';

@@ -9,5 +9,7 @@ "use strict";

exports.names = css_color_names_1.default;
__export(require("./mix"));
__export(require("./readability"));
__export(require("./to-ms-filter"));
__export(require("./from-ratio"));
__export(require("./format-input"));
__export(require("./random"));
//# sourceMappingURL=public_api.js.map
# tinycolor [![npm](https://img.shields.io/npm/v/%40ctrl%2Ftinycolor.svg?maxAge=3600)](https://www.npmjs.com/package/%40ctrl%2Ftinycolor) [![build status](https://img.shields.io/travis/TypeCtrl/tinycolor.svg)](https://travis-ci.org/TypeCtrl/tinycolor) [![coverage status](https://codecov.io/gh/typectrl/tinycolor/branch/master/graph/badge.svg)](https://codecov.io/gh/typectrl/tinycolor)
> TinyColor is a small library for color manipulation and conversion

@@ -6,1 +7,632 @@

### Changes from tinycolor2
* reformatted into TypeScript / es2015 and requires node >= 8
* tree shakeable "module" export and no package `sideEffects`
* new `fromRandom`, an implementation of [randomColor](https://github.com/davidmerfield/fromRandom/) by David Merfield that returns a TinyColor object
* several functions moved out of the tinycolor class and are no longer `tinycolor.<function>`
* `readability`, `fromRatio` moved out
* `random` moved out and renamed to `fromLegacyRandom`
* `toFilter` has been moved out and renamed to `toMsFilter`
* `mix`, `equals` use the current TinyColor object as the first parameter
* `new TinyColor('#000').equals('#000') // true`
* added polyad colors [126](https://github.com/bgrins/TinyColor/pull/126)
* color wheel values (360) are allowed to over or under-spin and still return valid colors [108](https://github.com/bgrins/TinyColor/pull/108)
* added `tint()` and `shade()` [159](https://github.com/bgrins/TinyColor/pull/159)
* `isValid` is now a property instead of a function
## Install
```sh
npm install @ctrl/tinycolor
```
## Use
```ts
import { TinyColor } from '@ctrl/tinycolor';
const color = new TinyColor('red').toHexString(); // '#ff0000'
```
## Accepted String Input
The string parsing is very permissive. It is meant to make typing a color as input as easy as possible. All commas, percentages, parenthesis are optional, and most input allow either 0-1, 0%-100%, or 0-n (where n is either 100, 255, or 360 depending on the value).
HSL and HSV both require either 0%-100% or 0-1 for the `S`/`L`/`V` properties. The `H` (hue) can have values between 0%-100% or 0-360.
RGB input requires either 0-255 or 0%-100%.
If you call `tinycolor.fromRatio`, RGB and Hue input can also accept 0-1.
Here are some examples of string input:
### Hex, 8-digit (RGBA) Hex
```ts
new TinyColor('#000');
new TinyColor('000');
new TinyColor('#369C');
new TinyColor('369C');
new TinyColor('#f0f0f6');
new TinyColor('f0f0f6');
new TinyColor('#f0f0f688');
new TinyColor('f0f0f688');
```
### RGB, RGBA
```ts
new TinyColor('rgb (255, 0, 0)');
new TinyColor('rgb 255 0 0');
new TinyColor('rgba (255, 0, 0, .5)');
new TinyColor({ r: 255, g: 0, b: 0 });
import { fromRatio } from '@ctrl/tinycolor';
fromRatio({ r: 1, g: 0, b: 0 });
fromRatio({ r: 0.5, g: 0.5, b: 0.5 });
```
### HSL, HSLA
```ts
new TinyColor('hsl(0, 100%, 50%)');
new TinyColor('hsla(0, 100%, 50%, .5)');
new TinyColor('hsl(0, 100%, 50%)');
new TinyColor('hsl 0 1.0 0.5');
new TinyColor({ h: 0, s: 1, l: 0.5 });
import { fromRatio } from '@ctrl/tinycolor';
fromRatio({ h: 1, s: 0, l: 0 });
fromRatio({ h: 0.5, s: 0.5, l: 0.5 });
```
### HSV, HSVA
```ts
new TinyColor('hsv(0, 100%, 100%)');
new TinyColor('hsva(0, 100%, 100%, .5)');
new TinyColor('hsv (0 100% 100%)');
new TinyColor('hsv 0 1 1');
new TinyColor({ h: 0, s: 100, v: 100 });
import { fromRatio } from '@ctrl/tinycolor';
fromRatio({ h: 1, s: 0, v: 0 });
fromRatio({ h: 0.5, s: 0.5, v: 0.5 });
```
### Named
```ts
new TinyColor('RED');
new TinyColor('blanchedalmond');
new TinyColor('darkblue');
```
### Accepted Object Input
If you are calling this from code, you may want to use object input. Here are some examples of the different types of accepted object inputs:
```ts
{ r: 255, g: 0, b: 0 }
{ r: 255, g: 0, b: 0, a: .5 }
{ h: 0, s: 100, l: 50 }
{ h: 0, s: 100, v: 100 }
```
## Methods
### getFormat
Returns the format used to create the tinycolor instance
```ts
const color = new TinyColor('red');
color.getFormat(); // "name"
color = new TinyColor({ r: 255, g: 255, b: 255 });
color.getFormat(); // "rgb"
```
### getOriginalInput
Returns the input passed into the constructer used to create the tinycolor instance
```ts
const color = new TinyColor('red');
color.getOriginalInput(); // "red"
color = new TinyColor({ r: 255, g: 255, b: 255 });
color.getOriginalInput(); // "{r: 255, g: 255, b: 255}"
```
### isValid
A boolean indicating whether the color was successfully parsed. Note: if the color is not valid then it will act like `black` when being used with other methods.
```ts
const color1 = new TinyColor('red');
color1.isValid; // true
color1.toHexString(); // "#ff0000"
const color2 = new TinyColor('not a color');
color2.isValid; // false
color2.toString(); // "#000000"
```
### getBrightness
Returns the perceived brightness of a color, from `0-255`, as defined by [Web Content Accessibility Guidelines (Version 1.0)](http://www.w3.org/TR/AERT#color-contrast).
```ts
const color1 = new TinyColor('#fff');
color1.getBrightness(); // 255
const color2 = new TinyColor('#000');
color2.getBrightness(); // 0
```
### isLight
Return a boolean indicating whether the color's perceived brightness is light.
```ts
const color1 = new TinyColor('#fff');
color1.isLight(); // true
const color2 = new TinyColor('#000');
color2.isLight(); // false
```
### isDark
Return a boolean indicating whether the color's perceived brightness is dark.
```ts
const color1 = new TinyColor('#fff');
color1.isDark(); // false
const color2 = new TinyColor('#000');
color2.isDark(); // true
```
### getLuminance
Returns the perceived luminance of a color, from `0-1` as defined by [Web Content Accessibility Guidelines (Version 2.0).](http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef)
```ts
const color1 = new TinyColor('#fff');
color1.getLuminance(); // 1
const color2 = new TinyColor('#000');
color2.getLuminance(); // 0
```
### getAlpha
Returns the alpha value of a color, from `0-1`.
```ts
const color1 = new TinyColor('rgba(255, 0, 0, .5)');
color1.getAlpha(); // 0.5
const color2 = new TinyColor('rgb(255, 0, 0)');
color2.getAlpha(); // 1
const color3 = new TinyColor('transparent');
color3.getAlpha(); // 0
```
### setAlpha
Sets the alpha value on a current color. Accepted range is in between `0-1`.
```ts
const color = new TinyColor('red');
color.getAlpha(); // 1
color.setAlpha(0.5);
color.getAlpha(); // .5
color.toRgbString(); // "rgba(255, 0, 0, .5)"
```
### String Representations
The following methods will return a property for the `alpha` value, which can be ignored: `toHsv`, `toHsl`, `toRgb`
### toHsv
```ts
const color = new TinyColor('red');
color.toHsv(); // { h: 0, s: 1, v: 1, a: 1 }
```
### toHsvString
```ts
const color = new TinyColor('red');
color.toHsvString(); // "hsv(0, 100%, 100%)"
color.setAlpha(0.5);
color.toHsvString(); // "hsva(0, 100%, 100%, 0.5)"
```
### toHsl
```ts
const color = new TinyColor('red');
color.toHsl(); // { h: 0, s: 1, l: 0.5, a: 1 }
```
### toHslString
```ts
const color = new TinyColor('red');
color.toHslString(); // "hsl(0, 100%, 50%)"
color.setAlpha(0.5);
color.toHslString(); // "hsla(0, 100%, 50%, 0.5)"
```
### toHex
```ts
const color = new TinyColor('red');
color.toHex(); // "ff0000"
```
### toHexString
```ts
const color = new TinyColor('red');
color.toHexString(); // "#ff0000"
```
### toHex8
```ts
const color = new TinyColor('red');
color.toHex8(); // "ff0000ff"
```
### toHex8String
```ts
const color = new TinyColor('red');
color.toHex8String(); // "#ff0000ff"
```
### toRgb
```ts
const color = new TinyColor('red');
color.toRgb(); // { r: 255, g: 0, b: 0, a: 1 }
```
### toRgbString
```ts
const color = new TinyColor('red');
color.toRgbString(); // "rgb(255, 0, 0)"
color.setAlpha(0.5);
color.toRgbString(); // "rgba(255, 0, 0, 0.5)"
```
### toPercentageRgb
```ts
const color = new TinyColor('red');
color.toPercentageRgb(); // { r: "100%", g: "0%", b: "0%", a: 1 }
```
### toPercentageRgbString
```ts
const color = new TinyColor('red');
color.toPercentageRgbString(); // "rgb(100%, 0%, 0%)"
color.setAlpha(0.5);
color.toPercentageRgbString(); // "rgba(100%, 0%, 0%, 0.5)"
```
### toName
```ts
const color = new TinyColor('red');
color.toName(); // "red"
```
### toFilter
```ts
import { toMsFilter } from '@ctrl/tinycolor';
toMsFilter('red', 'blue'); // 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffff0000,endColorstr=#ff0000ff)'
```
### toString
Print to a string, depending on the input format. You can also override this by passing one of `"rgb", "prgb", "hex6", "hex3", "hex8", "name", "hsl", "hsv"` into the function.
```ts
const color1 = new TinyColor('red');
color1.toString(); // "red"
color1.toString('hsv'); // "hsv(0, 100%, 100%)"
const color2 = new TinyColor('rgb(255, 0, 0)');
color2.toString(); // "rgb(255, 0, 0)"
color2.setAlpha(0.5);
color2.toString(); // "rgba(255, 0, 0, 0.5)"
```
### Color Modification
These methods manipulate the current color, and return it for chaining. For instance:
```ts
new TinyColor('red')
.lighten()
.desaturate()
.toHexString(); // '#f53d3d'
```
### lighten
`lighten: function(amount = 10) -> TinyColor`. Lighten the color a given amount, from 0 to 100. Providing 100 will always return white.
```ts
new TinyColor('#f00').lighten().toString(); // '#ff3333'
new TinyColor('#f00').lighten(100).toString(); // '#ffffff'
```
### brighten
`brighten: function(amount = 10) -> TinyColor`. Brighten the color a given amount, from 0 to 100.
```ts
new TinyColor('#f00').brighten().toString(); // '#ff1919'
```
### darken
`darken: function(amount = 10) -> TinyColor`. Darken the color a given amount, from 0 to 100. Providing 100 will always return black.
```ts
new TinyColor('#f00').darken().toString(); // '#cc0000'
new TinyColor('#f00').darken(100).toString(); // '#000000'
```
### tint
Mix the color with pure white, from 0 to 100. Providing 0 will do nothing, providing 100 will always return white.
```ts
new TinyColor('#f00').tint().toString(); // "#ff1a1a"
new TinyColor('#f00').tint(100).toString(); // "#ffffff"
```
### shade
Mix the color with pure black, from 0 to 100. Providing 0 will do nothing, providing 100 will always return black.
```ts
new TinyColor('#f00').shade().toString(); // "#e60000"
new TinyColor('#f00').shade(100).toString(); // "#000000"
```
### desaturate
`desaturate: function(amount = 10) -> TinyColor`. Desaturate the color a given amount, from 0 to 100. Providing 100 will is the same as calling `greyscale`.
```ts
new TinyColor('#f00').desaturate().toString(); // "#f20d0d"
new TinyColor('#f00').desaturate(100).toString(); // "#808080"
```
### saturate
`saturate: function(amount = 10) -> TinyColor`. Saturate the color a given amount, from 0 to 100.
```ts
new TinyColor('hsl(0, 10%, 50%)').saturate().toString(); // "hsl(0, 20%, 50%)"
```
### greyscale
`greyscale: function() -> TinyColor`. Completely desaturates a color into greyscale. Same as calling `desaturate(100)`.
```ts
new TinyColor('#f00').greyscale().toString(); // "#808080"
```
### spin
`spin: function(amount = 0) -> TinyColor`. Spin the hue a given amount, from -360 to 360. Calling with 0, 360, or -360 will do nothing (since it sets the hue back to what it was before).
```ts
new TinyColor('#f00').spin(180).toString(); // "#00ffff"
new TinyColor('#f00').spin(-90).toString(); // "#7f00ff"
new TinyColor('#f00').spin(90).toString(); // "#80ff00"
// spin(0) and spin(360) do nothing
new TinyColor('#f00').spin(0).toString(); // "#ff0000"
new TinyColor('#f00').spin(360).toString(); // "#ff0000"
```
### Color Combinations
Combination functions return an array of TinyColor objects unless otherwise noted.
### analogous
`analogous: function(, results = 6, slices = 30) -> array<TinyColor>`.
```ts
const colors = new TinyColor('#f00').analogous();
colors.map(t => t.toHexString()); // [ "#ff0000", "#ff0066", "#ff0033", "#ff0000", "#ff3300", "#ff6600" ]
```
### monochromatic
`monochromatic: function(, results = 6) -> array<TinyColor>`.
```ts
const colors = new TinyColor('#f00').monochromatic();
colors.map(t => t.toHexString()); // [ "#ff0000", "#2a0000", "#550000", "#800000", "#aa0000", "#d40000" ]
```
### splitcomplement
`splitcomplement: function() -> array<TinyColor>`.
```ts
const colors = new TinyColor('#f00').splitcomplement();
colors.map(t => t.toHexString()); // [ "#ff0000", "#ccff00", "#0066ff" ]
```
### triad
`triad: function() -> array<TinyColor>`.
```ts
const colors = new TinyColor('#f00').triad();
colors.map(t => t.toHexString()); // [ "#ff0000", "#00ff00", "#0000ff" ]
```
### tetrad
```ts
const colors = new TinyColor('#f00').tetrad();
colors.map(t => t.toHexString()); // [ "#ff0000", "#80ff00", "#00ffff", "#7f00ff" ]
```
### polyad
```ts
const colors = new TinyColor('#f00').polyad(3);
colors.map(t => t.toHexString()); // [ "#ff0000", "#80ff00", "#00ffff", "#7f00ff" ]
```
### complement
`complement: function() -> TinyColor`.
```ts
new TinyColor('#f00').complement().toHexString(); // "#00ffff"
```
## Color Utilities
### equals
```ts
import { equals } from '@ctrl/tinycolor';
equals(color1, color2);
```
### fromRandom
Returns a random TinyColor object. This is an implementation of [randomColor](https://github.com/davidmerfield/fromRandom/) by David Merfield.
The main changes are input parsing and output formatting are handled by TinyColor.
You can pass an options object to influence the type of color it produces. The options object accepts the following properties:
`hue` – Controls the hue of the generated color. You can pass a string representing a color name: `red`, `orange`, `yellow`, `green`, `blue`, `purple`, `pink` and `monochrome` are currently supported. If you pass a hexidecimal color string such as #00FFFF, its hue value will be extracted and use that to generate colors.
`luminosity` – Controls the luminosity of the generated color. You can specify a string containing bright, light or dark.
`count` – An integer which specifies the number of colors to generate.
`seed` - An integer or string which when passed will cause randomColor to return the same color each time.
`alpha` – A decimal between 0 and 1. Only relevant when using a format with an alpha channel (rgba and hsla). Defaults to a random value.
```ts
import { fromRandom } from '@ctrl/tinycolor';
// Returns a TinyColor for an attractive color
fromRandom();
// Returns an array of ten green colors
fromRandom({
count: 10,
hue: 'green',
});
// Returns a hex code for a light blue
fromRandom({
luminosity: 'light',
hue: 'blue',
});
// Returns a hex code for a 'truly random' color
fromRandom({
luminosity: 'random',
hue: 'random',
});
// Returns a dark RGB color with specified alpha
fromRandom({
luminosity: 'dark',
alpha: 0.5,
});
```
### Readability
TinyColor assesses readability based on the [Web Content Accessibility Guidelines (Version 2.0)](http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef).
#### readability
`readability: function(TinyColor, TinyColor) -> Object`.
Returns the contrast ratio between two colors.
```ts
import { readability } from '@ctrl/tinycolor';
readability('#000', '#000'); // 1
readability('#000', '#111'); // 1.1121078324840545
readability('#000', '#fff'); // 21
```
Use the values in your own calculations, or use one of the convenience functions below.
#### isReadable
`isReadable: function(TinyColor, TinyColor, Object) -> Boolean`. Ensure that foreground and background color combinations meet WCAG guidelines. `Object` is optional, defaulting to `{level: "AA",size: "small"}`. `level` can be `"AA"` or "AAA" and `size` can be `"small"` or `"large"`.
Here are links to read more about the [AA](http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html) and [AAA](http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast7.html) requirements.
```ts
import { isReadable } from '@ctrl/tinycolor';
isReadable("#000", "#111"); // false
isReadable("#ff0088", "#5c1a72", { level: "AA", size: "small" }); // false
isReadable("#ff0088", "#5c1a72", { level: "AA", size: "large" }), // true
```
#### mostReadable
`mostReadable: function(TinyColor, [TinyColor, TinyColor ...], Object) -> Boolean`.
Given a base color and a list of possible foreground or background colors for that base, returns the most readable color.
If none of the colors in the list is readable, `mostReadable` will return the better of black or white if `includeFallbackColors:true`.
```ts
import { mostReadable } from '@ctrl/tinycolor';
mostReadable('#000', ['#f00', '#0f0', '#00f']).toHexString(); // "#00ff00"
mostReadable('#123', ['#124', '#125'], { includeFallbackColors: false }).toHexString(); // "#112255"
mostReadable('#123', ['#124', '#125'], { includeFallbackColors: true }).toHexString(); // "#ffffff"
mostReadable('#ff0088', ['#2e0c3a'], {
includeFallbackColors: true,
level: 'AAA',
size: 'large',
}).toHexString(); // "#2e0c3a",
mostReadable('#ff0088', ['#2e0c3a'], {
includeFallbackColors: true,
level: 'AAA',
size: 'small',
}).toHexString(); // "#000000",
```
See [index.html](https://github.com/bgrins/TinyColor/blob/master/index.html) in the project for a demo.
## Common operations
### clone
`clone: function() -> TinyColor`.
Instantiate a new TinyColor object with the same color. Any changes to the new one won't affect the old one.
```ts
const color1 = new TinyColor('#F00');
const color2 = color1.clone();
color2.setAlpha(0.5);
color1.toString(); // "#ff0000"
color2.toString(); // "rgba(255, 0, 0, 0.5)"
```
/**
* Take input from [0, n] and return it as [0, 1]
*/
export declare function bound01(n: any, max: number): number;
export declare function bound01(n: any, max: number): any;
/** Force a number between 0 and 1 */

@@ -19,4 +19,4 @@ export declare function clamp01(val: number): number;

/** Replace a decimal with it's percentage value */
export declare function convertToPercentage(n: number): string | number;
export declare function convertToPercentage(n: number | string): string | number;
/** Force a hex value to have 2 characters */
export declare function pad2(c: string): string;

@@ -11,3 +11,3 @@ "use strict";

const processPercent = isPercentage(n);
n = Math.min(max, Math.max(0, parseFloat(n)));
n = max === 360 ? n : Math.min(max, Math.max(0, parseFloat(n)));
// Automatically convert percentage into number

@@ -22,3 +22,14 @@ if (processPercent) {

// Convert into [0, 1] range if it isn't already
return (n % max) / parseFloat(String(max));
if (max === 360) {
// If n is a hue given in degrees,
// wrap around out-of-range values into [0, 360] range
// then convert into [0, 1].
n = (n < 0 ? n % max + max : n % max) / parseFloat(String(max));
}
else {
// If n not a hue given in degrees
// Convert into [0, 1] range if it isn't already.
n = (n % max) / parseFloat(String(max));
}
return n;
}

@@ -58,3 +69,3 @@ exports.bound01 = bound01;

if (n <= 1) {
return n * 100 + '%';
return +n * 100 + '%';
}

@@ -61,0 +72,0 @@ return n;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc