UNPKG

@iimm/shared

Version:

shared utils on browser and react env

344 lines (330 loc) 9.96 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } // from https://github.com/ant-design/ant-design/blob/4.x-stable/components/style/color/tinyColor.less import { ColorMatchers as matchers, ColorNameHexs as names } from "../defines"; import { parseIntFromHex, convertHexToDecimal, bound01, pad2, convertDecimalToHex, boundAlpha } from "./numericalHandler"; /** 将文本颜色转化为对象 */ export var stringColorToObjectColor = function stringColorToObjectColor() { var color = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; color = color.trim().toLowerCase(); var named = false; if (names[color]) { color = names[color]; named = true; } else if (color === 'transparent') { return { r: 0, g: 0, b: 0, a: 0, format: 'name', type: 'rgba' }; } // Try to match string input using regular expressions. // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] // Just return an object and let the conversion functions handle that. // This way the result will be the same whether the tinycolor is initialized with string or object. var match; if (match = matchers.rgb.exec(color)) { return { r: match[1], g: match[2], b: match[3], type: 'rgb' }; } if (match = matchers.rgba.exec(color)) { return { r: match[1], g: match[2], b: match[3], a: match[4], type: 'rgba' }; } if (match = matchers.hsl.exec(color)) { return { h: match[1], s: match[2], l: match[3], type: 'hsl' }; } if (match = matchers.hsla.exec(color)) { return { h: match[1], s: match[2], l: match[3], a: match[4], type: 'hsla' }; } if (match = matchers.hsv.exec(color)) { return { h: match[1], s: match[2], v: match[3], type: 'hsv' }; } if (match = matchers.hsva.exec(color)) { return { h: match[1], s: match[2], v: match[3], a: match[4], type: 'hsva' }; } if (match = matchers.hex8.exec(color)) { return { r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), a: convertHexToDecimal(match[4]), format: named ? 'name' : 'hex8', type: 'rgba' }; } if (match = matchers.hex6.exec(color)) { return { r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), format: named ? 'name' : 'hex', type: 'rgb' }; } if (match = matchers.hex4.exec(color)) { return { r: parseIntFromHex(match[1] + '' + match[1]), g: parseIntFromHex(match[2] + '' + match[2]), b: parseIntFromHex(match[3] + '' + match[3]), a: convertHexToDecimal(match[4] + '' + match[4]), format: named ? 'name' : 'hex8', type: 'rgba' }; } if (match = matchers.hex3.exec(color)) { return { r: parseIntFromHex(match[1] + '' + match[1]), g: parseIntFromHex(match[2] + '' + match[2]), b: parseIntFromHex(match[3] + '' + match[3]), format: named ? 'name' : 'hex', type: 'rgb' }; } return false; }; // hslToRgb // 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] export var hslToRgb = function hslToRgb(h, s, l) { var r, g, 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 { var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var 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] **/ export var rgbToHsv = function rgbToHsv(r, g, b) { r = bound01(r, 255); g = bound01(g, 255); b = bound01(b, 255); var max = Math.max(r, g, b), min = Math.min(r, g, b); var h; var v = max; var d = max - min; var s = max === 0 ? 0 : d / max; if (max === min) { h = 0; // achromatic } else { // eslint-disable-next-line default-case 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] */ export var hsvToRgb = function hsvToRgb(h, s, v) { h = bound01(h, 360) * 6; s = bound01(s, 100); v = bound01(v, 100); var i = Math.floor(h), f = h - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod = i % 6, r = [v, q, p, p, t, v][mod], g = [t, v, v, q, p, p][mod], b = [p, p, t, v, v, q][mod]; return { r: r * 255, g: g * 255, b: b * 255 }; }; /** Converts an RGB color to hex(without #) Assumes r, g, and b are contained in the set [0, 255] Returns a 3 or 6 character hex */ export var rgbToHex = function rgbToHex(r, g, b, allow3Char) { var 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(lowerCase,without #) Assumes r, g, b are contained in the set [0, 255] and a in [0, 1]. Returns a 4 or 8 character rgba hex */ export var rgbaToHex = function rgbaToHex(r, g, b, a, allow4Char) { var 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()" */ export var rgbaToArgbHex = function rgbaToArgbHex(r, g, b, a) { var 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(''); }; // isValidCSSUnit // Take in a single string / number and check to see if it looks like a CSS unit // (see matchers above for definition). var isValidCSSUnit = function isValidCSSUnit(color) { return !!matchers.CSS_UNIT.exec(color); }; // rgbToRgb // 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 }; } // Replace a decimal with it's percentage value function convertToPercentage(n) { if (n <= 1) { n = n * 100 + '%'; } return n; } /** Given a string or object, convert that input to RGB @example ``` Possible string inputs: "red" "#f00" or "f00" "#ff0000" or "ff0000" "#ff000000" or "ff000000" "rgb 255 0 0" or "rgb (255, 0, 0)" "rgb 1.0 0 0" or "rgb (1, 0, 0)" "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" ``` */ export var colorToRGBObjColor = function colorToRGBObjColor(color) { var rgb = { r: 0, g: 0, b: 0 }; var a = 1; var s = null; var v = null; var l = null; var ok = false; var format = false; if (typeof color === 'string') { color = stringColorToObjectColor(color); } if (_typeof(color) === 'object') { if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { rgb = rgbToRgb(color.r, color.g, color.b); ok = true; format = String(color.r).slice(-1) === '%' ? 'prgb' : 'rgb'; } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { s = convertToPercentage(color.s); v = convertToPercentage(color.v); rgb = hsvToRgb(color.h, s, v); ok = true; format = 'hsv'; } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { s = convertToPercentage(color.s); l = convertToPercentage(color.l); rgb = hslToRgb(color.h, s, l); ok = true; format = 'hsl'; } if (color.hasOwnProperty('a')) { a = color.a; } } a = boundAlpha(a); return { ok: ok, format: color.format || format, r: Math.min(255, Math.max(rgb.r, 0)), g: Math.min(255, Math.max(rgb.g, 0)), b: Math.min(255, Math.max(rgb.b, 0)), a: a }; };