UNPKG

@uiw/color-convert

Version:
444 lines (437 loc) 10.6 kB
import _extends from "@babel/runtime/helpers/extends"; var RGB_MAX = 255; var HUE_MAX = 360; var SV_MAX = 100; /** * ```js * rgbaToHsva({ r: 255, g: 255, b: 255, a: 1 }) //=> { h: 0, s: 0, v: 100, a: 1 } * ``` */ export var rgbaToHsva = _ref => { var { r, g, b, a } = _ref; var max = Math.max(r, g, b); var delta = max - Math.min(r, g, b); // prettier-ignore var hh = delta ? max === r ? (g - b) / delta : max === g ? 2 + (b - r) / delta : 4 + (r - g) / delta : 0; return { h: 60 * (hh < 0 ? hh + 6 : hh), s: max ? delta / max * SV_MAX : 0, v: max / RGB_MAX * SV_MAX, a }; }; export var hsvaToHslString = hsva => { var { h, s, l } = hsvaToHsla(hsva); // return `hsl(${h}, ${s}%, ${l}%)`; return "hsl(" + h + ", " + Math.round(s) + "%, " + Math.round(l) + "%)"; }; export var hsvaToHsvString = _ref2 => { var { h, s, v } = _ref2; return "hsv(" + h + ", " + s + "%, " + v + "%)"; }; export var hsvaToHsvaString = _ref3 => { var { h, s, v, a } = _ref3; return "hsva(" + h + ", " + s + "%, " + v + "%, " + a + ")"; }; export var hsvaToHslaString = hsva => { var { h, s, l, a } = hsvaToHsla(hsva); return "hsla(" + h + ", " + s + "%, " + l + "%, " + a + ")"; }; export var hslStringToHsla = str => { var [h, s, l, a] = (str.match(/\d+/g) || []).map(Number); return { h, s, l, a }; }; export var hslaStringToHsva = hslString => { var matcher = /hsla?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i; var match = matcher.exec(hslString); if (!match) return { h: 0, s: 0, v: 0, a: 1 }; return hslaToHsva({ h: parseHue(match[1], match[2]), s: Number(match[3]), l: Number(match[4]), a: match[5] === undefined ? 1 : Number(match[5]) / (match[6] ? 100 : 1) }); }; export var hslStringToHsva = hslaStringToHsva; export var hslaToHsva = _ref4 => { var { h, s, l, a } = _ref4; s *= (l < 50 ? l : SV_MAX - l) / SV_MAX; return { h: h, s: s > 0 ? 2 * s / (l + s) * SV_MAX : 0, v: l + s, a }; }; export var hsvaToHsla = _ref5 => { var { h, s, v, a } = _ref5; var hh = (200 - s) * v / SV_MAX; return { h, s: hh > 0 && hh < 200 ? s * v / SV_MAX / (hh <= SV_MAX ? hh : 200 - hh) * SV_MAX : 0, l: hh / 2, a }; }; export var hsvaStringToHsva = hsvString => { var matcher = /hsva?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i; var match = matcher.exec(hsvString); if (!match) return { h: 0, s: 0, v: 0, a: 1 }; return { h: parseHue(match[1], match[2]), s: Number(match[3]), v: Number(match[4]), a: match[5] === undefined ? 1 : Number(match[5]) / (match[6] ? SV_MAX : 1) }; }; /** * Valid CSS <angle> units. * https://developer.mozilla.org/en-US/docs/Web/CSS/angle */ var angleUnits = { grad: HUE_MAX / 400, turn: HUE_MAX, rad: HUE_MAX / (Math.PI * 2) }; export var parseHue = function parseHue(value, unit) { if (unit === void 0) { unit = 'deg'; } return Number(value) * (angleUnits[unit] || 1); }; export var hsvStringToHsva = hsvaStringToHsva; export var rgbaStringToHsva = rgbaString => { var matcher = /rgba?\(?\s*(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i; var match = matcher.exec(rgbaString); if (!match) return { h: 0, s: 0, v: 0, a: 1 }; return rgbaToHsva({ r: Number(match[1]) / (match[2] ? SV_MAX / RGB_MAX : 1), g: Number(match[3]) / (match[4] ? SV_MAX / RGB_MAX : 1), b: Number(match[5]) / (match[6] ? SV_MAX / RGB_MAX : 1), a: match[7] === undefined ? 1 : Number(match[7]) / (match[8] ? SV_MAX : 1) }); }; export var rgbStringToHsva = rgbaStringToHsva; /** Converts an RGBA color plus alpha transparency to hex */ export var rgbaToHex = _ref6 => { var { r, g, b } = _ref6; var bin = r << 16 | g << 8 | b; return "#" + (h => new Array(7 - h.length).join('0') + h)(bin.toString(16)); }; export var rgbaToHexa = _ref7 => { var { r, g, b, a } = _ref7; var alpha = typeof a === 'number' && (a * 255 | 1 << 8).toString(16).slice(1); return "" + rgbaToHex({ r, g, b, a }) + (alpha ? alpha : ''); }; export var hexToHsva = hex => rgbaToHsva(hexToRgba(hex)); export var hexToRgba = hex => { var htemp = hex.replace('#', ''); if (/^#?/.test(hex) && htemp.length === 3) { hex = "#" + htemp.charAt(0) + htemp.charAt(0) + htemp.charAt(1) + htemp.charAt(1) + htemp.charAt(2) + htemp.charAt(2); } var reg = new RegExp("[A-Za-z0-9]{2}", 'g'); var [r, g, b = 0, a] = hex.match(reg).map(v => parseInt(v, 16)); return { r, g, b, a: (a != null ? a : 255) / RGB_MAX }; }; /** * Converts HSVA to RGBA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV * @param color HSVA color as an array [0-360, 0-1, 0-1, 0-1] */ export var hsvaToRgba = _ref8 => { var { h, s, v, a } = _ref8; var _h = h / 60, _s = s / SV_MAX, _v = v / SV_MAX, hi = Math.floor(_h) % 6; var f = _h - Math.floor(_h), _p = RGB_MAX * _v * (1 - _s), _q = RGB_MAX * _v * (1 - _s * f), _t = RGB_MAX * _v * (1 - _s * (1 - f)); _v *= RGB_MAX; var rgba = {}; switch (hi) { case 0: rgba.r = _v; rgba.g = _t; rgba.b = _p; break; case 1: rgba.r = _q; rgba.g = _v; rgba.b = _p; break; case 2: rgba.r = _p; rgba.g = _v; rgba.b = _t; break; case 3: rgba.r = _p; rgba.g = _q; rgba.b = _v; break; case 4: rgba.r = _t; rgba.g = _p; rgba.b = _v; break; case 5: rgba.r = _v; rgba.g = _p; rgba.b = _q; break; } rgba.r = Math.round(rgba.r); rgba.g = Math.round(rgba.g); rgba.b = Math.round(rgba.b); return _extends({}, rgba, { a }); }; export var hsvaToRgbString = hsva => { var { r, g, b } = hsvaToRgba(hsva); return "rgb(" + r + ", " + g + ", " + b + ")"; }; export var hsvaToRgbaString = hsva => { var { r, g, b, a } = hsvaToRgba(hsva); return "rgba(" + r + ", " + g + ", " + b + ", " + a + ")"; }; export var rgbaToRgb = _ref9 => { var { r, g, b } = _ref9; return { r, g, b }; }; export var hslaToHsl = _ref10 => { var { h, s, l } = _ref10; return { h, s, l }; }; export var hsvaToHex = hsva => rgbaToHex(hsvaToRgba(hsva)); export var hsvaToHexa = hsva => rgbaToHexa(hsvaToRgba(hsva)); export var hsvaToHsv = _ref11 => { var { h, s, v } = _ref11; return { h, s, v }; }; export var hexToXY = hex => rgbToXY(rgbaToRgb(hexToRgba(hex))); export var xyToHex = xy => rgbaToHex(_extends({}, xyToRgb(xy), { a: 255 })); /** * Converts XY to RGB. Based on formula from https://developers.meethue.com/develop/application-design-guidance/color-conversion-formulas-rgb-to-xy-and-back/ * @param color XY color and brightness as an array [0-1, 0-1, 0-1] */ export var xyToRgb = _ref12 => { var { x, y, bri = 255 } = _ref12; var red = x * 3.2406255 + y * -1.537208 + bri * -0.4986286; var green = x * -0.9689307 + y * 1.8757561 + bri * 0.0415175; var blue = x * 0.0557101 + y * -0.2040211 + bri * 1.0569959; var translate = function translate(color) { return color <= 0.0031308 ? 12.92 * color : 1.055 * Math.pow(color, 1 / 2.4) - 0.055; }; return { r: Math.round(255 * translate(red)), g: Math.round(255 * translate(green)), b: Math.round(255 * translate(blue)) }; }; /** * Converts RGB to XY. Based on formula from https://developers.meethue.com/develop/application-design-guidance/color-conversion-formulas-rgb-to-xy-and-back/ * @param color RGB color as an array [0-255, 0-255, 0-255] */ export var rgbToXY = _ref13 => { var { r, g, b } = _ref13; var translateColor = function translateColor(color) { return color <= 0.04045 ? color / 12.92 : Math.pow((color + 0.055) / 1.055, 2.4); }; var red = translateColor(r / 255); var green = translateColor(g / 255); var blue = translateColor(b / 255); var xyz = {}; xyz.x = red * 0.4124 + green * 0.3576 + blue * 0.1805; xyz.y = red * 0.2126 + green * 0.7152 + blue * 0.0722; xyz.bri = red * 0.0193 + green * 0.1192 + blue * 0.9505; return xyz; }; export var color = str => { var rgb; var hsl; var hsv; var rgba; var hsla; var hsva; var xy; var hex; var hexa; if (typeof str === 'string' && validHex(str)) { hsva = hexToHsva(str); hex = str; } else if (typeof str !== 'string') { hsva = str; } if (hsva) { hsv = hsvaToHsv(hsva); hsla = hsvaToHsla(hsva); rgba = hsvaToRgba(hsva); hexa = rgbaToHexa(rgba); hex = hsvaToHex(hsva); hsl = hslaToHsl(hsla); rgb = rgbaToRgb(rgba); xy = rgbToXY(rgb); } return { rgb, hsl, hsv, rgba, hsla, hsva, hex, hexa, xy }; }; export var getContrastingColor = str => { if (!str) { return '#ffffff'; } var col = color(str); var yiq = (col.rgb.r * 299 + col.rgb.g * 587 + col.rgb.b * 114) / 1000; return yiq >= 128 ? '#000000' : '#ffffff'; }; export var equalColorObjects = (first, second) => { if (first === second) return true; for (var prop in first) { // The following allows for a type-safe calling of this function (first & second have to be HSL, HSV, or RGB) // with type-unsafe iterating over object keys. TS does not allow this without an index (`[key: string]: number`) // on an object to define how iteration is normally done. To ensure extra keys are not allowed on our types, // we must cast our object to unknown (as RGB demands `r` be a key, while `Record<string, x>` does not care if // there is or not), and then as a type TS can iterate over. if (first[prop] !== second[prop]) return false; } return true; }; export var equalColorString = (first, second) => { return first.replace(/\s/g, '') === second.replace(/\s/g, ''); }; export var equalHex = (first, second) => { if (first.toLowerCase() === second.toLowerCase()) return true; // To compare colors like `#FFF` and `ffffff` we convert them into RGB objects return equalColorObjects(hexToRgba(first), hexToRgba(second)); }; export var validHex = hex => /^#?([A-Fa-f0-9]{3,4}){1,2}$/.test(hex);