UNPKG

jebcolors

Version:

npm module that contains colors, gradients and a class used to modify the colors or gradients

698 lines 25.7 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.upgradecolor = exports.megacolor = exports.supercolor = exports.GradientableColor = exports.Color = void 0; var functions_1 = require("./functions"); var regex_1 = require("./regex"); var errors_1 = require("./errors"); var color_convert_1 = __importDefault(require("color-convert")); var Gradient_1 = require("./Gradient"); var seedrandom_1 = __importDefault(require("seedrandom")); /** * Class with basic functions of a color * (If you want to add the gradient creator use class GradientableColor) */ var Color = /** @class */ (function () { function Color(code) { this._lightdarkconst = 1.5; this._code = functions_1.getFullCode(code); this._rgb = this.getRGB(); this._hsl = this.getHSL(); this._luminance = this.getLuminance(); // Didn't know how to name this number, so I named is 'Color Jeb Constant' to be mamon this._jeb = this.YiqFormula(); this._dark = this._jeb < 128; } // Static Methods /** * Tests if a given code is a valid code and returns a CodeEvalutation {type, valid} * @param code The code of the color * @returns a CodeEvaluation object * @example * Color.test('#c00') * // return * {type: 'rgb', valid: true} * * Color.test('#ff0000') * // return * {type: 'rrggbb', valid: true} * * Color.test('red') * // return * {type: 'css', valid:true} * * Color.test('aaa') * // return * {type: 'invalid', valid:false} */ Color.test = function (code) { return functions_1.evaluateCode(code); }; /** * Gets the contrast values of 2 supercolors * @param color1 the first supercolor (the background supercolor) * @param color2 the second supercolor (the fore color supercolor) * @returns A Contrast Object * @example * Color.contrast("#ffffff","#000000") * * // return * * { * passes: { * normal: { minimal: true, perfect: true }, * bold: { minimal: true, perfect: true } * } * } */ Color.contrast = function (color1, color2) { if (color1 instanceof Color && color2 instanceof Color) { // Formula (Ratio): https://www.w3.org/TR/WCAG20/#contrast-ratiodef // Contrast Conditions: https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast (normal) // Contrast Conditions: https://www.w3.org/TR/WCAG20/#visual-audio-contrast7 (bold) var maxL = Math.max(color1.luminance, color2.luminance); var minL = Math.min(color1.luminance, color2.luminance); var ratio = (maxL + 0.05) / (minL + 0.05); var contrast = { passes: { normal: { minimal: ratio >= 4.5, perfect: ratio >= 7 }, bold: { minimal: ratio >= 3, perfect: ratio >= 4.5 } } }; return contrast; } else { throw errors_1.layer8Error("Must provide 2 instances of Color, in contrast() in Color(), providen were: " + typeof color1 + " and " + typeof color2); } }; /** * Creates a new Color instance for the given 3 values * @param RGB An array with [red, green, blue] values [0,255] * @returns A supercolor (Color instance) */ Color.rgb = function (RGB) { var _a = RGB.map(function (rgbav) { return Color.normalize(rgbav, 'RGB'); }), red = _a[0], green = _a[1], blue = _a[2]; var rrggbb = color_convert_1.default.rgb.hex([red, green, blue]); return exports.supercolor("#" + rrggbb); }; /** * Creates a new Color instance for the given 3 values * @param HSL An array with [hue, saturation, lightness] values [0,360], [0,100] & [0,100] * @returns A supercolor (Color instance) */ Color.hsl = function (HSL) { var hue = HSL[0], saturation = HSL[1], lightness = HSL[2]; hue = Color.normalize(hue, 'H'); saturation = Color.normalize(saturation, 'SL'); lightness = Color.normalize(lightness, 'SL'); var rrggbb = color_convert_1.default.hsl.hex([hue, saturation, lightness]); return exports.supercolor("#" + rrggbb); }; Color.normalize = function (value, to) { var normalize = function (value, min, max) { return Math.min(Math.max(value, min), max); }; if (to === 'RGB') return ~~(normalize(value, 0, 255)); else if (to === 'H') { value = value % 360; return (value < 0 ? value + 360 : value); } else if (to === 'SL') return normalize(value, 0, 100); else if (to === 'JEB') return normalize(value, 0, 255); else throw errors_1.layer8Error("to is different from allowed values, given was: " + to); }; /** * Returns a random supercolor * @returns A random supercolor */ Color.random = function () { var ran = function () { return Math.floor(Math.random() * 255) + 1; }; var _a = [ran(), ran(), ran()], red = _a[0], green = _a[1], blue = _a[2]; return Color.rgb([red, green, blue]); }; /** * Returns a random supercolor based on a seed * @param seed The seed * @returns A random supercolor */ Color.seed = function (seed) { var ran = seedrandom_1.default(seed); var randoms = [ran(), ran(), ran()]; var _a = randoms.map(function (rannum) { return Math.floor(rannum * 255) + 1; }), red = _a[0], green = _a[1], blue = _a[2]; return Color.rgb([red, green, blue]); }; // Private Methods Color.prototype.getRGB = function () { var result = regex_1.rrggbbREGEX.exec(this._code); if (!result) throw errors_1.internalError('Trying to get RGBA values in Color()'); // [_,rr,bb,gg] var red = result[1]; var green = result[2]; var blue = result[3]; return [ functions_1.hex(red), functions_1.hex(green), functions_1.hex(blue), ]; }; Color.prototype.getHSL = function () { var _a = this._rgb, red = _a[0], green = _a[1], blue = _a[2]; var _b = color_convert_1.default.rgb.hsl(red, green, blue), hue = _b[0], saturation = _b[1], lightness = _b[2]; return [hue, saturation, lightness]; }; Color.prototype.getLuminance = function () { var rgb = this._rgb; var calculated = rgb.map(function (value) { // Formula: https://www.w3.org/TR/WCAG20/#relativeluminancedef value /= 255; value = value <= 0.03928 ? value / 12.92 : Math.pow(((value + 0.055) / 1.055), 2.4); return value; }); var luminance = 0.2126 * calculated[0] + 0.7152 * calculated[1] + 0.0722 * calculated[2]; return luminance; }; Color.prototype.YiqFormula = function () { // Formula: https://24ways.org/2010/calculating-color-contrast var _a = this._rgb, red = _a[0], green = _a[1], blue = _a[2]; var yiq = ((red * 299) + (green * 587) + (blue * 114)) / 1000; return yiq; }; Object.defineProperty(Color.prototype, "code", { // Getters /** * Hexadecimal code of the color */ get: function () { return this._code; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "red", { /** * Red value of the color */ get: function () { return this._rgb[0]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "green", { /** * Green value of the color */ get: function () { return this._rgb[1]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "blue", { /** * Blue value of the color */ get: function () { return this._rgb[2]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "rgb", { /** * Array of the 3 colors [red, green, blue] */ get: function () { return this._rgb; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "hue", { /** * Hue of the color */ get: function () { return this._hsl[0]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "saturation", { /** * Saturation of the color */ get: function () { return this._hsl[1]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "lightness", { /** * Lightness of the color */ get: function () { return this._hsl[2]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "hsl", { /** * Array of the 3 hsl values [hue, saturation, lightness] */ get: function () { return this._hsl; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "cmyk", { /** * Array with the values of the color [cyan, magenta, yellow, black] */ get: function () { return color_convert_1.default.rgb.cmyk(this._rgb); }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "luminance", { /** * Luminance of the color */ get: function () { return this._luminance; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "jeb", { /** * A constant of the color based on YIQ used to get if the color is dark */ get: function () { return this._jeb; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "isDark", { /** * Boolean saying if the color is a dark color */ get: function () { return this._dark; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "isLight", { /** * Boolean saying if the color is a light color */ get: function () { return !this._dark; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "text", { /** * Returns white o black, depending of the jeb constant of the color * This is to get the best color for a text assuming, that the supercolor is the background color */ get: function () { return this.isDark ? '#ffffff' : '#000000'; }, enumerable: false, configurable: true }); // Public Methods /** * Makes the color transparent * @param alpha The alpha that the color is going to have, in range [0,100] 0 - trasparent, 100 - opaque * @returns A string representing a rgba color 'rgba(255,0,0,.5)' for instance * @example * htmlElement.style.backgroundColor = supercolor("red").alpha(50) // half-transparent red */ Color.prototype.alpha = function (alpha) { var _a = this.rgb, red = _a[0], green = _a[1], blue = _a[2]; alpha /= 100; return "rgba(" + red + "," + green + "," + blue + "," + alpha + ")"; }; /** * Multiplies the saturation os a color in factor times * @param factor The times you want to multiply the saturation of the color * @returns A supercolor */ Color.prototype.saturate = function (factor) { // eslint-disable-next-line prefer-const var _a = this.hsl, hue = _a[0], saturation = _a[1], lightness = _a[2]; saturation = saturation * factor; return Color.hsl([hue, saturation, lightness]); }; /** * Divivdes the saturation os a color in factor times * @param factor The times you want to divide the saturation of the color * @returns A supercolor */ Color.prototype.desaturate = function (factor) { // eslint-disable-next-line prefer-const var _a = this.hsl, hue = _a[0], saturation = _a[1], lightness = _a[2]; saturation = saturation / factor; return Color.hsl([hue, saturation, lightness]); }; /** * Multiplies the lightness os a color in factor times * @param factor The times you want to multiply the lightness of the color * @returns A supercolor */ Color.prototype.lighten = function (factor) { // eslint-disable-next-line prefer-const var _a = this.hsl, hue = _a[0], saturation = _a[1], lightness = _a[2]; lightness = lightness * factor; return Color.hsl([hue, saturation, lightness]); }; /** * Divides the lightness os a color in factor times * @param factor The times you want to divide the lightness of the color * @returns A supercolor */ Color.prototype.darken = function (factor) { // eslint-disable-next-line prefer-const var _a = this.hsl, hue = _a[0], saturation = _a[1], lightness = _a[2]; lightness = lightness / factor; return Color.hsl([hue, saturation, lightness]); }; /** * Rotates the hue os a color in degrees degress * @param degrees The times you want to multiply the saturation of the color * @returns A supercolor */ Color.prototype.rotate = function (degrees) { // eslint-disable-next-line prefer-const var _a = this.hsl, hue = _a[0], saturation = _a[1], lightness = _a[2]; hue = Color.normalize(hue + degrees, 'H'); return Color.hsl([hue, saturation, lightness]); }; // Cromatic circle are 360 degrees in 12 steps, so each step is 30 degrees /** * Rotates the hue of a color step steps (1 step = 30 degrees) * @param steps The steps * @returns a supercolor */ Color.prototype.next = function (steps) { return this.rotate(steps * 30); }; /** * Rotates (in the opposite direction) the hue of a color step steps (1 step = 30 degrees) * @param steps The steps * @returns a supercolor */ Color.prototype.previous = function (steps) { return this.next(steps * -1); }; Object.defineProperty(Color.prototype, "negative", { // Public methods that not require parameters, so they are properties /** * The negative of the color */ get: function () { var _a = this.rgb, red = _a[0], green = _a[1], blue = _a[2]; red = Color.normalize(255 - red, 'RGB'); green = Color.normalize(255 - green, 'RGB'); blue = Color.normalize(255 - blue, 'RGB'); return Color.rgb([red, green, blue]); }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "complementary", { /** * The complementary color (hue rotated 180 degrees) */ get: function () { return this.next(6); }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "analogous", { /** * The analogous colors */ get: function () { return [this.previous(1), this.next(1)]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "splitComplementary", { /** * The split complementary colors */ get: function () { return [this.previous(5), this.next(5)]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "triadic", { /** * The triadic colors */ get: function () { return [this.previous(4), this.next(4)]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "hover", { /** * The color a little bit darker */ get: function () { return this.darken(this._lightdarkconst); }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "disabled", { /** * The color a little bit lighter */ get: function () { return this.lighten(this._lightdarkconst); }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "monocromatic", { /** * The monocromatic colors */ get: function () { return [this.disabled, this.hover]; }, enumerable: false, configurable: true }); Object.defineProperty(Color.prototype, "grayscale", { /** * The color converted to a grayscale */ get: function () { // Formula: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale var _a = this.rgb, red = _a[0], green = _a[1], blue = _a[2]; var value = red * 0.3 + green * 0.59 + blue * 0.11; return Color.rgb([value, value, value]); }, enumerable: false, configurable: true }); // Prototype Functions /** * Converts the supercolor to a string * @returns The hexadecimal hexcode */ Color.prototype.toString = function () { return this.code; }; return Color; }()); exports.Color = Color; var GradientableColor = /** @class */ (function (_super) { __extends(GradientableColor, _super); function GradientableColor(code) { var _this = _super.call(this, code) || this; _this._gradientWithAnalogous = _this.gAnalogous(); _this._gradientWithComplementary = _this.gComplementary(); _this._gradientWithDarker = _this.gDarker(); _this._gradientWithLighter = _this.gLighter(); _this._gradientWithMonocromatic = _this.gMonocromatic(); _this._gradientWithNegative = _this.gNegative(); _this._gradientWithSplitComplementary = _this.gSplitComplementary(); _this._gradientWithTriadic = _this.gTriadic(); return _this; } // Private methods that creates the gradient GradientableColor.prototype.gNegative = function () { return Gradient_1.supergradient([this, this.negative]); }; GradientableColor.prototype.gComplementary = function () { return Gradient_1.supergradient([this, this.next(3), this.complementary]); }; GradientableColor.prototype.gAnalogous = function () { var _a = this.analogous, prethis = _a[0], postthis = _a[1]; return Gradient_1.supergradient([prethis, this, postthis]); }; GradientableColor.prototype.gSplitComplementary = function () { var _a = this.splitComplementary, prethis = _a[0], postthis = _a[1]; return Gradient_1.supergradient([prethis, this, postthis]); }; GradientableColor.prototype.gTriadic = function () { var _a = this.triadic, prethis = _a[0], postthis = _a[1]; return Gradient_1.supergradient([prethis, this, postthis]); }; GradientableColor.prototype.gLighter = function () { return Gradient_1.supergradient([this, this.disabled]); }; GradientableColor.prototype.gDarker = function () { return Gradient_1.supergradient([this, this.hover]); }; GradientableColor.prototype.gMonocromatic = function () { return Gradient_1.supergradient([this.disabled, this, this.hover]); }; Object.defineProperty(GradientableColor.prototype, "gradientWithAnalogous", { // Properties (the gradients) /** * A gradient that contains the color in middle and is surrounded by its analogous */ get: function () { return this._gradientWithAnalogous; }, enumerable: false, configurable: true }); Object.defineProperty(GradientableColor.prototype, "gradientWithComplementary", { /** * A gradient that starts with the color and ends with its complementary * (There is a middle color in between to avoid crossing the gray) */ get: function () { return this._gradientWithComplementary; }, enumerable: false, configurable: true }); Object.defineProperty(GradientableColor.prototype, "gradientWithDarker", { /** * A gradient that starts with the color and ends with a darker version of the color */ get: function () { return this._gradientWithDarker; }, enumerable: false, configurable: true }); Object.defineProperty(GradientableColor.prototype, "gradientWithLighter", { /** * A gradient that starts with the color and ends with a lighter version of the color */ get: function () { return this._gradientWithLighter; }, enumerable: false, configurable: true }); Object.defineProperty(GradientableColor.prototype, "gradientWithMonocromatic", { /** * A gradient that contains the color in middle and is surrounded by its lighter and darker versions */ get: function () { return this._gradientWithMonocromatic; }, enumerable: false, configurable: true }); Object.defineProperty(GradientableColor.prototype, "gradientWithNegative", { /** * A gradient that starts with the color and ends with its negative * (There is a middle color in between to avoid crossing the gray) */ get: function () { return this._gradientWithNegative; }, enumerable: false, configurable: true }); Object.defineProperty(GradientableColor.prototype, "gradientWithSplitComplementary", { /** * A gradient that contains the color in middle and is surrounded by its split complementaries */ get: function () { return this._gradientWithSplitComplementary; }, enumerable: false, configurable: true }); Object.defineProperty(GradientableColor.prototype, "gradientWithTriadic", { /** * A gradient that contains the color in middle and is surrounded by its triadic */ get: function () { return this._gradientWithTriadic; }, enumerable: false, configurable: true }); return GradientableColor; }(Color)); exports.GradientableColor = GradientableColor; var supercolor = function (code) { return new Color(code); }; exports.supercolor = supercolor; var megacolor = function (code) { return new GradientableColor(code); }; exports.megacolor = megacolor; var upgradecolor = function (codeOrColor) { if (codeOrColor instanceof Color) { return exports.megacolor(codeOrColor.code); } else if (typeof codeOrColor === 'string') { return exports.supercolor(codeOrColor); } else { throw errors_1.layer8Error("Argument in upgradecolor() must be a string or a Color instance, the provided was: " + typeof codeOrColor); } }; exports.upgradecolor = upgradecolor; //# sourceMappingURL=Color.js.map