bb7e45cdc01d47082e43dbe19ddef4b04f800edc7db67e0e20e0bee0e2f159563a75251f0be81749119ac2c5b38dace8776f1addb5dbe1319a2e0aa4d93047 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* MIT license */
  2. var colorNames = require('color-name');
  3. module.exports = {
  4. getRgba: getRgba,
  5. getHsla: getHsla,
  6. getRgb: getRgb,
  7. getHsl: getHsl,
  8. getHwb: getHwb,
  9. getAlpha: getAlpha,
  10. hexString: hexString,
  11. rgbString: rgbString,
  12. rgbaString: rgbaString,
  13. percentString: percentString,
  14. percentaString: percentaString,
  15. hslString: hslString,
  16. hslaString: hslaString,
  17. hwbString: hwbString,
  18. keyword: keyword
  19. }
  20. function getRgba(string) {
  21. if (!string) {
  22. return;
  23. }
  24. var abbr = /^#([a-fA-F0-9]{3,4})$/i,
  25. hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i,
  26. rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
  27. per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
  28. keyword = /(\w+)/;
  29. var rgb = [0, 0, 0],
  30. a = 1,
  31. match = string.match(abbr),
  32. hexAlpha = "";
  33. if (match) {
  34. match = match[1];
  35. hexAlpha = match[3];
  36. for (var i = 0; i < rgb.length; i++) {
  37. rgb[i] = parseInt(match[i] + match[i], 16);
  38. }
  39. if (hexAlpha) {
  40. a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100;
  41. }
  42. }
  43. else if (match = string.match(hex)) {
  44. hexAlpha = match[2];
  45. match = match[1];
  46. for (var i = 0; i < rgb.length; i++) {
  47. rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);
  48. }
  49. if (hexAlpha) {
  50. a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100;
  51. }
  52. }
  53. else if (match = string.match(rgba)) {
  54. for (var i = 0; i < rgb.length; i++) {
  55. rgb[i] = parseInt(match[i + 1]);
  56. }
  57. a = parseFloat(match[4]);
  58. }
  59. else if (match = string.match(per)) {
  60. for (var i = 0; i < rgb.length; i++) {
  61. rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);
  62. }
  63. a = parseFloat(match[4]);
  64. }
  65. else if (match = string.match(keyword)) {
  66. if (match[1] == "transparent") {
  67. return [0, 0, 0, 0];
  68. }
  69. rgb = colorNames[match[1]];
  70. if (!rgb) {
  71. return;
  72. }
  73. }
  74. for (var i = 0; i < rgb.length; i++) {
  75. rgb[i] = scale(rgb[i], 0, 255);
  76. }
  77. if (!a && a != 0) {
  78. a = 1;
  79. }
  80. else {
  81. a = scale(a, 0, 1);
  82. }
  83. rgb[3] = a;
  84. return rgb;
  85. }
  86. function getHsla(string) {
  87. if (!string) {
  88. return;
  89. }
  90. var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
  91. var match = string.match(hsl);
  92. if (match) {
  93. var alpha = parseFloat(match[4]);
  94. var h = scale(parseInt(match[1]), 0, 360),
  95. s = scale(parseFloat(match[2]), 0, 100),
  96. l = scale(parseFloat(match[3]), 0, 100),
  97. a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
  98. return [h, s, l, a];
  99. }
  100. }
  101. function getHwb(string) {
  102. if (!string) {
  103. return;
  104. }
  105. var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
  106. var match = string.match(hwb);
  107. if (match) {
  108. var alpha = parseFloat(match[4]);
  109. var h = scale(parseInt(match[1]), 0, 360),
  110. w = scale(parseFloat(match[2]), 0, 100),
  111. b = scale(parseFloat(match[3]), 0, 100),
  112. a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
  113. return [h, w, b, a];
  114. }
  115. }
  116. function getRgb(string) {
  117. var rgba = getRgba(string);
  118. return rgba && rgba.slice(0, 3);
  119. }
  120. function getHsl(string) {
  121. var hsla = getHsla(string);
  122. return hsla && hsla.slice(0, 3);
  123. }
  124. function getAlpha(string) {
  125. var vals = getRgba(string);
  126. if (vals) {
  127. return vals[3];
  128. }
  129. else if (vals = getHsla(string)) {
  130. return vals[3];
  131. }
  132. else if (vals = getHwb(string)) {
  133. return vals[3];
  134. }
  135. }
  136. // generators
  137. function hexString(rgba, a) {
  138. var a = (a !== undefined && rgba.length === 3) ? a : rgba[3];
  139. return "#" + hexDouble(rgba[0])
  140. + hexDouble(rgba[1])
  141. + hexDouble(rgba[2])
  142. + (
  143. (a >= 0 && a < 1)
  144. ? hexDouble(Math.round(a * 255))
  145. : ""
  146. );
  147. }
  148. function rgbString(rgba, alpha) {
  149. if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
  150. return rgbaString(rgba, alpha);
  151. }
  152. return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";
  153. }
  154. function rgbaString(rgba, alpha) {
  155. if (alpha === undefined) {
  156. alpha = (rgba[3] !== undefined ? rgba[3] : 1);
  157. }
  158. return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]
  159. + ", " + alpha + ")";
  160. }
  161. function percentString(rgba, alpha) {
  162. if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
  163. return percentaString(rgba, alpha);
  164. }
  165. var r = Math.round(rgba[0]/255 * 100),
  166. g = Math.round(rgba[1]/255 * 100),
  167. b = Math.round(rgba[2]/255 * 100);
  168. return "rgb(" + r + "%, " + g + "%, " + b + "%)";
  169. }
  170. function percentaString(rgba, alpha) {
  171. var r = Math.round(rgba[0]/255 * 100),
  172. g = Math.round(rgba[1]/255 * 100),
  173. b = Math.round(rgba[2]/255 * 100);
  174. return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";
  175. }
  176. function hslString(hsla, alpha) {
  177. if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {
  178. return hslaString(hsla, alpha);
  179. }
  180. return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";
  181. }
  182. function hslaString(hsla, alpha) {
  183. if (alpha === undefined) {
  184. alpha = (hsla[3] !== undefined ? hsla[3] : 1);
  185. }
  186. return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "
  187. + alpha + ")";
  188. }
  189. // hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
  190. // (hwb have alpha optional & 1 is default value)
  191. function hwbString(hwb, alpha) {
  192. if (alpha === undefined) {
  193. alpha = (hwb[3] !== undefined ? hwb[3] : 1);
  194. }
  195. return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"
  196. + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";
  197. }
  198. function keyword(rgb) {
  199. return reverseNames[rgb.slice(0, 3)];
  200. }
  201. // helpers
  202. function scale(num, min, max) {
  203. return Math.min(Math.max(min, num), max);
  204. }
  205. function hexDouble(num) {
  206. var str = num.toString(16).toUpperCase();
  207. return (str.length < 2) ? "0" + str : str;
  208. }
  209. //create a list of reverse color names
  210. var reverseNames = {};
  211. for (var name in colorNames) {
  212. reverseNames[colorNames[name]] = name;
  213. }