color.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. var LRU = require("../core/LRU");
  2. var kCSSColorTable = {
  3. 'transparent': [0, 0, 0, 0],
  4. 'aliceblue': [240, 248, 255, 1],
  5. 'antiquewhite': [250, 235, 215, 1],
  6. 'aqua': [0, 255, 255, 1],
  7. 'aquamarine': [127, 255, 212, 1],
  8. 'azure': [240, 255, 255, 1],
  9. 'beige': [245, 245, 220, 1],
  10. 'bisque': [255, 228, 196, 1],
  11. 'black': [0, 0, 0, 1],
  12. 'blanchedalmond': [255, 235, 205, 1],
  13. 'blue': [0, 0, 255, 1],
  14. 'blueviolet': [138, 43, 226, 1],
  15. 'brown': [165, 42, 42, 1],
  16. 'burlywood': [222, 184, 135, 1],
  17. 'cadetblue': [95, 158, 160, 1],
  18. 'chartreuse': [127, 255, 0, 1],
  19. 'chocolate': [210, 105, 30, 1],
  20. 'coral': [255, 127, 80, 1],
  21. 'cornflowerblue': [100, 149, 237, 1],
  22. 'cornsilk': [255, 248, 220, 1],
  23. 'crimson': [220, 20, 60, 1],
  24. 'cyan': [0, 255, 255, 1],
  25. 'darkblue': [0, 0, 139, 1],
  26. 'darkcyan': [0, 139, 139, 1],
  27. 'darkgoldenrod': [184, 134, 11, 1],
  28. 'darkgray': [169, 169, 169, 1],
  29. 'darkgreen': [0, 100, 0, 1],
  30. 'darkgrey': [169, 169, 169, 1],
  31. 'darkkhaki': [189, 183, 107, 1],
  32. 'darkmagenta': [139, 0, 139, 1],
  33. 'darkolivegreen': [85, 107, 47, 1],
  34. 'darkorange': [255, 140, 0, 1],
  35. 'darkorchid': [153, 50, 204, 1],
  36. 'darkred': [139, 0, 0, 1],
  37. 'darksalmon': [233, 150, 122, 1],
  38. 'darkseagreen': [143, 188, 143, 1],
  39. 'darkslateblue': [72, 61, 139, 1],
  40. 'darkslategray': [47, 79, 79, 1],
  41. 'darkslategrey': [47, 79, 79, 1],
  42. 'darkturquoise': [0, 206, 209, 1],
  43. 'darkviolet': [148, 0, 211, 1],
  44. 'deeppink': [255, 20, 147, 1],
  45. 'deepskyblue': [0, 191, 255, 1],
  46. 'dimgray': [105, 105, 105, 1],
  47. 'dimgrey': [105, 105, 105, 1],
  48. 'dodgerblue': [30, 144, 255, 1],
  49. 'firebrick': [178, 34, 34, 1],
  50. 'floralwhite': [255, 250, 240, 1],
  51. 'forestgreen': [34, 139, 34, 1],
  52. 'fuchsia': [255, 0, 255, 1],
  53. 'gainsboro': [220, 220, 220, 1],
  54. 'ghostwhite': [248, 248, 255, 1],
  55. 'gold': [255, 215, 0, 1],
  56. 'goldenrod': [218, 165, 32, 1],
  57. 'gray': [128, 128, 128, 1],
  58. 'green': [0, 128, 0, 1],
  59. 'greenyellow': [173, 255, 47, 1],
  60. 'grey': [128, 128, 128, 1],
  61. 'honeydew': [240, 255, 240, 1],
  62. 'hotpink': [255, 105, 180, 1],
  63. 'indianred': [205, 92, 92, 1],
  64. 'indigo': [75, 0, 130, 1],
  65. 'ivory': [255, 255, 240, 1],
  66. 'khaki': [240, 230, 140, 1],
  67. 'lavender': [230, 230, 250, 1],
  68. 'lavenderblush': [255, 240, 245, 1],
  69. 'lawngreen': [124, 252, 0, 1],
  70. 'lemonchiffon': [255, 250, 205, 1],
  71. 'lightblue': [173, 216, 230, 1],
  72. 'lightcoral': [240, 128, 128, 1],
  73. 'lightcyan': [224, 255, 255, 1],
  74. 'lightgoldenrodyellow': [250, 250, 210, 1],
  75. 'lightgray': [211, 211, 211, 1],
  76. 'lightgreen': [144, 238, 144, 1],
  77. 'lightgrey': [211, 211, 211, 1],
  78. 'lightpink': [255, 182, 193, 1],
  79. 'lightsalmon': [255, 160, 122, 1],
  80. 'lightseagreen': [32, 178, 170, 1],
  81. 'lightskyblue': [135, 206, 250, 1],
  82. 'lightslategray': [119, 136, 153, 1],
  83. 'lightslategrey': [119, 136, 153, 1],
  84. 'lightsteelblue': [176, 196, 222, 1],
  85. 'lightyellow': [255, 255, 224, 1],
  86. 'lime': [0, 255, 0, 1],
  87. 'limegreen': [50, 205, 50, 1],
  88. 'linen': [250, 240, 230, 1],
  89. 'magenta': [255, 0, 255, 1],
  90. 'maroon': [128, 0, 0, 1],
  91. 'mediumaquamarine': [102, 205, 170, 1],
  92. 'mediumblue': [0, 0, 205, 1],
  93. 'mediumorchid': [186, 85, 211, 1],
  94. 'mediumpurple': [147, 112, 219, 1],
  95. 'mediumseagreen': [60, 179, 113, 1],
  96. 'mediumslateblue': [123, 104, 238, 1],
  97. 'mediumspringgreen': [0, 250, 154, 1],
  98. 'mediumturquoise': [72, 209, 204, 1],
  99. 'mediumvioletred': [199, 21, 133, 1],
  100. 'midnightblue': [25, 25, 112, 1],
  101. 'mintcream': [245, 255, 250, 1],
  102. 'mistyrose': [255, 228, 225, 1],
  103. 'moccasin': [255, 228, 181, 1],
  104. 'navajowhite': [255, 222, 173, 1],
  105. 'navy': [0, 0, 128, 1],
  106. 'oldlace': [253, 245, 230, 1],
  107. 'olive': [128, 128, 0, 1],
  108. 'olivedrab': [107, 142, 35, 1],
  109. 'orange': [255, 165, 0, 1],
  110. 'orangered': [255, 69, 0, 1],
  111. 'orchid': [218, 112, 214, 1],
  112. 'palegoldenrod': [238, 232, 170, 1],
  113. 'palegreen': [152, 251, 152, 1],
  114. 'paleturquoise': [175, 238, 238, 1],
  115. 'palevioletred': [219, 112, 147, 1],
  116. 'papayawhip': [255, 239, 213, 1],
  117. 'peachpuff': [255, 218, 185, 1],
  118. 'peru': [205, 133, 63, 1],
  119. 'pink': [255, 192, 203, 1],
  120. 'plum': [221, 160, 221, 1],
  121. 'powderblue': [176, 224, 230, 1],
  122. 'purple': [128, 0, 128, 1],
  123. 'red': [255, 0, 0, 1],
  124. 'rosybrown': [188, 143, 143, 1],
  125. 'royalblue': [65, 105, 225, 1],
  126. 'saddlebrown': [139, 69, 19, 1],
  127. 'salmon': [250, 128, 114, 1],
  128. 'sandybrown': [244, 164, 96, 1],
  129. 'seagreen': [46, 139, 87, 1],
  130. 'seashell': [255, 245, 238, 1],
  131. 'sienna': [160, 82, 45, 1],
  132. 'silver': [192, 192, 192, 1],
  133. 'skyblue': [135, 206, 235, 1],
  134. 'slateblue': [106, 90, 205, 1],
  135. 'slategray': [112, 128, 144, 1],
  136. 'slategrey': [112, 128, 144, 1],
  137. 'snow': [255, 250, 250, 1],
  138. 'springgreen': [0, 255, 127, 1],
  139. 'steelblue': [70, 130, 180, 1],
  140. 'tan': [210, 180, 140, 1],
  141. 'teal': [0, 128, 128, 1],
  142. 'thistle': [216, 191, 216, 1],
  143. 'tomato': [255, 99, 71, 1],
  144. 'turquoise': [64, 224, 208, 1],
  145. 'violet': [238, 130, 238, 1],
  146. 'wheat': [245, 222, 179, 1],
  147. 'white': [255, 255, 255, 1],
  148. 'whitesmoke': [245, 245, 245, 1],
  149. 'yellow': [255, 255, 0, 1],
  150. 'yellowgreen': [154, 205, 50, 1]
  151. };
  152. function clampCssByte(i) {
  153. // Clamp to integer 0 .. 255.
  154. i = Math.round(i); // Seems to be what Chrome does (vs truncation).
  155. return i < 0 ? 0 : i > 255 ? 255 : i;
  156. }
  157. function clampCssAngle(i) {
  158. // Clamp to integer 0 .. 360.
  159. i = Math.round(i); // Seems to be what Chrome does (vs truncation).
  160. return i < 0 ? 0 : i > 360 ? 360 : i;
  161. }
  162. function clampCssFloat(f) {
  163. // Clamp to float 0.0 .. 1.0.
  164. return f < 0 ? 0 : f > 1 ? 1 : f;
  165. }
  166. function parseCssInt(str) {
  167. // int or percentage.
  168. if (str.length && str.charAt(str.length - 1) === '%') {
  169. return clampCssByte(parseFloat(str) / 100 * 255);
  170. }
  171. return clampCssByte(parseInt(str, 10));
  172. }
  173. function parseCssFloat(str) {
  174. // float or percentage.
  175. if (str.length && str.charAt(str.length - 1) === '%') {
  176. return clampCssFloat(parseFloat(str) / 100);
  177. }
  178. return clampCssFloat(parseFloat(str));
  179. }
  180. function cssHueToRgb(m1, m2, h) {
  181. if (h < 0) {
  182. h += 1;
  183. } else if (h > 1) {
  184. h -= 1;
  185. }
  186. if (h * 6 < 1) {
  187. return m1 + (m2 - m1) * h * 6;
  188. }
  189. if (h * 2 < 1) {
  190. return m2;
  191. }
  192. if (h * 3 < 2) {
  193. return m1 + (m2 - m1) * (2 / 3 - h) * 6;
  194. }
  195. return m1;
  196. }
  197. function lerpNumber(a, b, p) {
  198. return a + (b - a) * p;
  199. }
  200. function setRgba(out, r, g, b, a) {
  201. out[0] = r;
  202. out[1] = g;
  203. out[2] = b;
  204. out[3] = a;
  205. return out;
  206. }
  207. function copyRgba(out, a) {
  208. out[0] = a[0];
  209. out[1] = a[1];
  210. out[2] = a[2];
  211. out[3] = a[3];
  212. return out;
  213. }
  214. var colorCache = new LRU(20);
  215. var lastRemovedArr = null;
  216. function putToCache(colorStr, rgbaArr) {
  217. // Reuse removed array
  218. if (lastRemovedArr) {
  219. copyRgba(lastRemovedArr, rgbaArr);
  220. }
  221. lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || rgbaArr.slice());
  222. }
  223. /**
  224. * @param {string} colorStr
  225. * @param {Array.<number>} out
  226. * @return {Array.<number>}
  227. * @memberOf module:zrender/util/color
  228. */
  229. function parse(colorStr, rgbaArr) {
  230. if (!colorStr) {
  231. return;
  232. }
  233. rgbaArr = rgbaArr || [];
  234. var cached = colorCache.get(colorStr);
  235. if (cached) {
  236. return copyRgba(rgbaArr, cached);
  237. } // colorStr may be not string
  238. colorStr = colorStr + ''; // Remove all whitespace, not compliant, but should just be more accepting.
  239. var str = colorStr.replace(/ /g, '').toLowerCase(); // Color keywords (and transparent) lookup.
  240. if (str in kCSSColorTable) {
  241. copyRgba(rgbaArr, kCSSColorTable[str]);
  242. putToCache(colorStr, rgbaArr);
  243. return rgbaArr;
  244. } // #abc and #abc123 syntax.
  245. if (str.charAt(0) === '#') {
  246. if (str.length === 4) {
  247. var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
  248. if (!(iv >= 0 && iv <= 0xfff)) {
  249. setRgba(rgbaArr, 0, 0, 0, 1);
  250. return; // Covers NaN.
  251. }
  252. setRgba(rgbaArr, (iv & 0xf00) >> 4 | (iv & 0xf00) >> 8, iv & 0xf0 | (iv & 0xf0) >> 4, iv & 0xf | (iv & 0xf) << 4, 1);
  253. putToCache(colorStr, rgbaArr);
  254. return rgbaArr;
  255. } else if (str.length === 7) {
  256. var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
  257. if (!(iv >= 0 && iv <= 0xffffff)) {
  258. setRgba(rgbaArr, 0, 0, 0, 1);
  259. return; // Covers NaN.
  260. }
  261. setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, 1);
  262. putToCache(colorStr, rgbaArr);
  263. return rgbaArr;
  264. }
  265. return;
  266. }
  267. var op = str.indexOf('(');
  268. var ep = str.indexOf(')');
  269. if (op !== -1 && ep + 1 === str.length) {
  270. var fname = str.substr(0, op);
  271. var params = str.substr(op + 1, ep - (op + 1)).split(',');
  272. var alpha = 1; // To allow case fallthrough.
  273. switch (fname) {
  274. case 'rgba':
  275. if (params.length !== 4) {
  276. setRgba(rgbaArr, 0, 0, 0, 1);
  277. return;
  278. }
  279. alpha = parseCssFloat(params.pop());
  280. // jshint ignore:line
  281. // Fall through.
  282. case 'rgb':
  283. if (params.length !== 3) {
  284. setRgba(rgbaArr, 0, 0, 0, 1);
  285. return;
  286. }
  287. setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), alpha);
  288. putToCache(colorStr, rgbaArr);
  289. return rgbaArr;
  290. case 'hsla':
  291. if (params.length !== 4) {
  292. setRgba(rgbaArr, 0, 0, 0, 1);
  293. return;
  294. }
  295. params[3] = parseCssFloat(params[3]);
  296. hsla2rgba(params, rgbaArr);
  297. putToCache(colorStr, rgbaArr);
  298. return rgbaArr;
  299. case 'hsl':
  300. if (params.length !== 3) {
  301. setRgba(rgbaArr, 0, 0, 0, 1);
  302. return;
  303. }
  304. hsla2rgba(params, rgbaArr);
  305. putToCache(colorStr, rgbaArr);
  306. return rgbaArr;
  307. default:
  308. return;
  309. }
  310. }
  311. setRgba(rgbaArr, 0, 0, 0, 1);
  312. return;
  313. }
  314. /**
  315. * @param {Array.<number>} hsla
  316. * @param {Array.<number>} rgba
  317. * @return {Array.<number>} rgba
  318. */
  319. function hsla2rgba(hsla, rgba) {
  320. var h = (parseFloat(hsla[0]) % 360 + 360) % 360 / 360; // 0 .. 1
  321. // NOTE(deanm): According to the CSS spec s/l should only be
  322. // percentages, but we don't bother and let float or percentage.
  323. var s = parseCssFloat(hsla[1]);
  324. var l = parseCssFloat(hsla[2]);
  325. var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
  326. var m1 = l * 2 - m2;
  327. rgba = rgba || [];
  328. setRgba(rgba, clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), clampCssByte(cssHueToRgb(m1, m2, h) * 255), clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), 1);
  329. if (hsla.length === 4) {
  330. rgba[3] = hsla[3];
  331. }
  332. return rgba;
  333. }
  334. /**
  335. * @param {Array.<number>} rgba
  336. * @return {Array.<number>} hsla
  337. */
  338. function rgba2hsla(rgba) {
  339. if (!rgba) {
  340. return;
  341. } // RGB from 0 to 255
  342. var R = rgba[0] / 255;
  343. var G = rgba[1] / 255;
  344. var B = rgba[2] / 255;
  345. var vMin = Math.min(R, G, B); // Min. value of RGB
  346. var vMax = Math.max(R, G, B); // Max. value of RGB
  347. var delta = vMax - vMin; // Delta RGB value
  348. var L = (vMax + vMin) / 2;
  349. var H;
  350. var S; // HSL results from 0 to 1
  351. if (delta === 0) {
  352. H = 0;
  353. S = 0;
  354. } else {
  355. if (L < 0.5) {
  356. S = delta / (vMax + vMin);
  357. } else {
  358. S = delta / (2 - vMax - vMin);
  359. }
  360. var deltaR = ((vMax - R) / 6 + delta / 2) / delta;
  361. var deltaG = ((vMax - G) / 6 + delta / 2) / delta;
  362. var deltaB = ((vMax - B) / 6 + delta / 2) / delta;
  363. if (R === vMax) {
  364. H = deltaB - deltaG;
  365. } else if (G === vMax) {
  366. H = 1 / 3 + deltaR - deltaB;
  367. } else if (B === vMax) {
  368. H = 2 / 3 + deltaG - deltaR;
  369. }
  370. if (H < 0) {
  371. H += 1;
  372. }
  373. if (H > 1) {
  374. H -= 1;
  375. }
  376. }
  377. var hsla = [H * 360, S, L];
  378. if (rgba[3] != null) {
  379. hsla.push(rgba[3]);
  380. }
  381. return hsla;
  382. }
  383. /**
  384. * @param {string} color
  385. * @param {number} level
  386. * @return {string}
  387. * @memberOf module:zrender/util/color
  388. */
  389. function lift(color, level) {
  390. var colorArr = parse(color);
  391. if (colorArr) {
  392. for (var i = 0; i < 3; i++) {
  393. if (level < 0) {
  394. colorArr[i] = colorArr[i] * (1 - level) | 0;
  395. } else {
  396. colorArr[i] = (255 - colorArr[i]) * level + colorArr[i] | 0;
  397. }
  398. if (colorArr[i] > 255) {
  399. colorArr[i] = 255;
  400. } else if (color[i] < 0) {
  401. colorArr[i] = 0;
  402. }
  403. }
  404. return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
  405. }
  406. }
  407. /**
  408. * @param {string} color
  409. * @return {string}
  410. * @memberOf module:zrender/util/color
  411. */
  412. function toHex(color) {
  413. var colorArr = parse(color);
  414. if (colorArr) {
  415. return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + +colorArr[2]).toString(16).slice(1);
  416. }
  417. }
  418. /**
  419. * Map value to color. Faster than lerp methods because color is represented by rgba array.
  420. * @param {number} normalizedValue A float between 0 and 1.
  421. * @param {Array.<Array.<number>>} colors List of rgba color array
  422. * @param {Array.<number>} [out] Mapped gba color array
  423. * @return {Array.<number>} will be null/undefined if input illegal.
  424. */
  425. function fastLerp(normalizedValue, colors, out) {
  426. if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
  427. return;
  428. }
  429. out = out || [];
  430. var value = normalizedValue * (colors.length - 1);
  431. var leftIndex = Math.floor(value);
  432. var rightIndex = Math.ceil(value);
  433. var leftColor = colors[leftIndex];
  434. var rightColor = colors[rightIndex];
  435. var dv = value - leftIndex;
  436. out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
  437. out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
  438. out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
  439. out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
  440. return out;
  441. }
  442. /**
  443. * @deprecated
  444. */
  445. var fastMapToColor = fastLerp;
  446. /**
  447. * @param {number} normalizedValue A float between 0 and 1.
  448. * @param {Array.<string>} colors Color list.
  449. * @param {boolean=} fullOutput Default false.
  450. * @return {(string|Object)} Result color. If fullOutput,
  451. * return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
  452. * @memberOf module:zrender/util/color
  453. */
  454. function lerp(normalizedValue, colors, fullOutput) {
  455. if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
  456. return;
  457. }
  458. var value = normalizedValue * (colors.length - 1);
  459. var leftIndex = Math.floor(value);
  460. var rightIndex = Math.ceil(value);
  461. var leftColor = parse(colors[leftIndex]);
  462. var rightColor = parse(colors[rightIndex]);
  463. var dv = value - leftIndex;
  464. var color = stringify([clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)), clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)), clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)), clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))], 'rgba');
  465. return fullOutput ? {
  466. color: color,
  467. leftIndex: leftIndex,
  468. rightIndex: rightIndex,
  469. value: value
  470. } : color;
  471. }
  472. /**
  473. * @deprecated
  474. */
  475. var mapToColor = lerp;
  476. /**
  477. * @param {string} color
  478. * @param {number=} h 0 ~ 360, ignore when null.
  479. * @param {number=} s 0 ~ 1, ignore when null.
  480. * @param {number=} l 0 ~ 1, ignore when null.
  481. * @return {string} Color string in rgba format.
  482. * @memberOf module:zrender/util/color
  483. */
  484. function modifyHSL(color, h, s, l) {
  485. color = parse(color);
  486. if (color) {
  487. color = rgba2hsla(color);
  488. h != null && (color[0] = clampCssAngle(h));
  489. s != null && (color[1] = parseCssFloat(s));
  490. l != null && (color[2] = parseCssFloat(l));
  491. return stringify(hsla2rgba(color), 'rgba');
  492. }
  493. }
  494. /**
  495. * @param {string} color
  496. * @param {number=} alpha 0 ~ 1
  497. * @return {string} Color string in rgba format.
  498. * @memberOf module:zrender/util/color
  499. */
  500. function modifyAlpha(color, alpha) {
  501. color = parse(color);
  502. if (color && alpha != null) {
  503. color[3] = clampCssFloat(alpha);
  504. return stringify(color, 'rgba');
  505. }
  506. }
  507. /**
  508. * @param {Array.<number>} arrColor like [12,33,44,0.4]
  509. * @param {string} type 'rgba', 'hsva', ...
  510. * @return {string} Result color. (If input illegal, return undefined).
  511. */
  512. function stringify(arrColor, type) {
  513. if (!arrColor || !arrColor.length) {
  514. return;
  515. }
  516. var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
  517. if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
  518. colorStr += ',' + arrColor[3];
  519. }
  520. return type + '(' + colorStr + ')';
  521. }
  522. exports.parse = parse;
  523. exports.lift = lift;
  524. exports.toHex = toHex;
  525. exports.fastLerp = fastLerp;
  526. exports.fastMapToColor = fastMapToColor;
  527. exports.lerp = lerp;
  528. exports.mapToColor = mapToColor;
  529. exports.modifyHSL = modifyHSL;
  530. exports.modifyAlpha = modifyAlpha;
  531. exports.stringify = stringify;