color-string.js 5.7 KB

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