788e11537e4eadf5e318b01374417bcdf810f8456ee6c9e59c2cfdc0a1754d8eec2a6c5d60384bbc1e9756cda905fa570c440070083c6a9efce277fd7cb37f 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. import LRU from '../core/LRU.js';
  2. var kCSSColorTable = {
  3. 'transparent': [0, 0, 0, 0], 'aliceblue': [240, 248, 255, 1],
  4. 'antiquewhite': [250, 235, 215, 1], 'aqua': [0, 255, 255, 1],
  5. 'aquamarine': [127, 255, 212, 1], 'azure': [240, 255, 255, 1],
  6. 'beige': [245, 245, 220, 1], 'bisque': [255, 228, 196, 1],
  7. 'black': [0, 0, 0, 1], 'blanchedalmond': [255, 235, 205, 1],
  8. 'blue': [0, 0, 255, 1], 'blueviolet': [138, 43, 226, 1],
  9. 'brown': [165, 42, 42, 1], 'burlywood': [222, 184, 135, 1],
  10. 'cadetblue': [95, 158, 160, 1], 'chartreuse': [127, 255, 0, 1],
  11. 'chocolate': [210, 105, 30, 1], 'coral': [255, 127, 80, 1],
  12. 'cornflowerblue': [100, 149, 237, 1], 'cornsilk': [255, 248, 220, 1],
  13. 'crimson': [220, 20, 60, 1], 'cyan': [0, 255, 255, 1],
  14. 'darkblue': [0, 0, 139, 1], 'darkcyan': [0, 139, 139, 1],
  15. 'darkgoldenrod': [184, 134, 11, 1], 'darkgray': [169, 169, 169, 1],
  16. 'darkgreen': [0, 100, 0, 1], 'darkgrey': [169, 169, 169, 1],
  17. 'darkkhaki': [189, 183, 107, 1], 'darkmagenta': [139, 0, 139, 1],
  18. 'darkolivegreen': [85, 107, 47, 1], 'darkorange': [255, 140, 0, 1],
  19. 'darkorchid': [153, 50, 204, 1], 'darkred': [139, 0, 0, 1],
  20. 'darksalmon': [233, 150, 122, 1], 'darkseagreen': [143, 188, 143, 1],
  21. 'darkslateblue': [72, 61, 139, 1], 'darkslategray': [47, 79, 79, 1],
  22. 'darkslategrey': [47, 79, 79, 1], 'darkturquoise': [0, 206, 209, 1],
  23. 'darkviolet': [148, 0, 211, 1], 'deeppink': [255, 20, 147, 1],
  24. 'deepskyblue': [0, 191, 255, 1], 'dimgray': [105, 105, 105, 1],
  25. 'dimgrey': [105, 105, 105, 1], 'dodgerblue': [30, 144, 255, 1],
  26. 'firebrick': [178, 34, 34, 1], 'floralwhite': [255, 250, 240, 1],
  27. 'forestgreen': [34, 139, 34, 1], 'fuchsia': [255, 0, 255, 1],
  28. 'gainsboro': [220, 220, 220, 1], 'ghostwhite': [248, 248, 255, 1],
  29. 'gold': [255, 215, 0, 1], 'goldenrod': [218, 165, 32, 1],
  30. 'gray': [128, 128, 128, 1], 'green': [0, 128, 0, 1],
  31. 'greenyellow': [173, 255, 47, 1], 'grey': [128, 128, 128, 1],
  32. 'honeydew': [240, 255, 240, 1], 'hotpink': [255, 105, 180, 1],
  33. 'indianred': [205, 92, 92, 1], 'indigo': [75, 0, 130, 1],
  34. 'ivory': [255, 255, 240, 1], 'khaki': [240, 230, 140, 1],
  35. 'lavender': [230, 230, 250, 1], 'lavenderblush': [255, 240, 245, 1],
  36. 'lawngreen': [124, 252, 0, 1], 'lemonchiffon': [255, 250, 205, 1],
  37. 'lightblue': [173, 216, 230, 1], 'lightcoral': [240, 128, 128, 1],
  38. 'lightcyan': [224, 255, 255, 1], 'lightgoldenrodyellow': [250, 250, 210, 1],
  39. 'lightgray': [211, 211, 211, 1], 'lightgreen': [144, 238, 144, 1],
  40. 'lightgrey': [211, 211, 211, 1], 'lightpink': [255, 182, 193, 1],
  41. 'lightsalmon': [255, 160, 122, 1], 'lightseagreen': [32, 178, 170, 1],
  42. 'lightskyblue': [135, 206, 250, 1], 'lightslategray': [119, 136, 153, 1],
  43. 'lightslategrey': [119, 136, 153, 1], 'lightsteelblue': [176, 196, 222, 1],
  44. 'lightyellow': [255, 255, 224, 1], 'lime': [0, 255, 0, 1],
  45. 'limegreen': [50, 205, 50, 1], 'linen': [250, 240, 230, 1],
  46. 'magenta': [255, 0, 255, 1], 'maroon': [128, 0, 0, 1],
  47. 'mediumaquamarine': [102, 205, 170, 1], 'mediumblue': [0, 0, 205, 1],
  48. 'mediumorchid': [186, 85, 211, 1], 'mediumpurple': [147, 112, 219, 1],
  49. 'mediumseagreen': [60, 179, 113, 1], 'mediumslateblue': [123, 104, 238, 1],
  50. 'mediumspringgreen': [0, 250, 154, 1], 'mediumturquoise': [72, 209, 204, 1],
  51. 'mediumvioletred': [199, 21, 133, 1], 'midnightblue': [25, 25, 112, 1],
  52. 'mintcream': [245, 255, 250, 1], 'mistyrose': [255, 228, 225, 1],
  53. 'moccasin': [255, 228, 181, 1], 'navajowhite': [255, 222, 173, 1],
  54. 'navy': [0, 0, 128, 1], 'oldlace': [253, 245, 230, 1],
  55. 'olive': [128, 128, 0, 1], 'olivedrab': [107, 142, 35, 1],
  56. 'orange': [255, 165, 0, 1], 'orangered': [255, 69, 0, 1],
  57. 'orchid': [218, 112, 214, 1], 'palegoldenrod': [238, 232, 170, 1],
  58. 'palegreen': [152, 251, 152, 1], 'paleturquoise': [175, 238, 238, 1],
  59. 'palevioletred': [219, 112, 147, 1], 'papayawhip': [255, 239, 213, 1],
  60. 'peachpuff': [255, 218, 185, 1], 'peru': [205, 133, 63, 1],
  61. 'pink': [255, 192, 203, 1], 'plum': [221, 160, 221, 1],
  62. 'powderblue': [176, 224, 230, 1], 'purple': [128, 0, 128, 1],
  63. 'red': [255, 0, 0, 1], 'rosybrown': [188, 143, 143, 1],
  64. 'royalblue': [65, 105, 225, 1], 'saddlebrown': [139, 69, 19, 1],
  65. 'salmon': [250, 128, 114, 1], 'sandybrown': [244, 164, 96, 1],
  66. 'seagreen': [46, 139, 87, 1], 'seashell': [255, 245, 238, 1],
  67. 'sienna': [160, 82, 45, 1], 'silver': [192, 192, 192, 1],
  68. 'skyblue': [135, 206, 235, 1], 'slateblue': [106, 90, 205, 1],
  69. 'slategray': [112, 128, 144, 1], 'slategrey': [112, 128, 144, 1],
  70. 'snow': [255, 250, 250, 1], 'springgreen': [0, 255, 127, 1],
  71. 'steelblue': [70, 130, 180, 1], 'tan': [210, 180, 140, 1],
  72. 'teal': [0, 128, 128, 1], 'thistle': [216, 191, 216, 1],
  73. 'tomato': [255, 99, 71, 1], 'turquoise': [64, 224, 208, 1],
  74. 'violet': [238, 130, 238, 1], 'wheat': [245, 222, 179, 1],
  75. 'white': [255, 255, 255, 1], 'whitesmoke': [245, 245, 245, 1],
  76. 'yellow': [255, 255, 0, 1], 'yellowgreen': [154, 205, 50, 1]
  77. };
  78. function clampCssByte(i) {
  79. i = Math.round(i);
  80. return i < 0 ? 0 : i > 255 ? 255 : i;
  81. }
  82. function clampCssAngle(i) {
  83. i = Math.round(i);
  84. return i < 0 ? 0 : i > 360 ? 360 : i;
  85. }
  86. function clampCssFloat(f) {
  87. return f < 0 ? 0 : f > 1 ? 1 : f;
  88. }
  89. function parseCssInt(val) {
  90. var str = val;
  91. if (str.length && str.charAt(str.length - 1) === '%') {
  92. return clampCssByte(parseFloat(str) / 100 * 255);
  93. }
  94. return clampCssByte(parseInt(str, 10));
  95. }
  96. function parseCssFloat(val) {
  97. var str = val;
  98. if (str.length && str.charAt(str.length - 1) === '%') {
  99. return clampCssFloat(parseFloat(str) / 100);
  100. }
  101. return clampCssFloat(parseFloat(str));
  102. }
  103. function cssHueToRgb(m1, m2, h) {
  104. if (h < 0) {
  105. h += 1;
  106. }
  107. else if (h > 1) {
  108. h -= 1;
  109. }
  110. if (h * 6 < 1) {
  111. return m1 + (m2 - m1) * h * 6;
  112. }
  113. if (h * 2 < 1) {
  114. return m2;
  115. }
  116. if (h * 3 < 2) {
  117. return m1 + (m2 - m1) * (2 / 3 - h) * 6;
  118. }
  119. return m1;
  120. }
  121. function lerpNumber(a, b, p) {
  122. return a + (b - a) * p;
  123. }
  124. function setRgba(out, r, g, b, a) {
  125. out[0] = r;
  126. out[1] = g;
  127. out[2] = b;
  128. out[3] = a;
  129. return out;
  130. }
  131. function copyRgba(out, a) {
  132. out[0] = a[0];
  133. out[1] = a[1];
  134. out[2] = a[2];
  135. out[3] = a[3];
  136. return out;
  137. }
  138. var colorCache = new LRU(20);
  139. var lastRemovedArr = null;
  140. function putToCache(colorStr, rgbaArr) {
  141. if (lastRemovedArr) {
  142. copyRgba(lastRemovedArr, rgbaArr);
  143. }
  144. lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
  145. }
  146. export function parse(colorStr, rgbaArr) {
  147. if (!colorStr) {
  148. return;
  149. }
  150. rgbaArr = rgbaArr || [];
  151. var cached = colorCache.get(colorStr);
  152. if (cached) {
  153. return copyRgba(rgbaArr, cached);
  154. }
  155. colorStr = colorStr + '';
  156. var str = colorStr.replace(/ /g, '').toLowerCase();
  157. if (str in kCSSColorTable) {
  158. copyRgba(rgbaArr, kCSSColorTable[str]);
  159. putToCache(colorStr, rgbaArr);
  160. return rgbaArr;
  161. }
  162. var strLen = str.length;
  163. if (str.charAt(0) === '#') {
  164. if (strLen === 4 || strLen === 5) {
  165. var iv = parseInt(str.slice(1, 4), 16);
  166. if (!(iv >= 0 && iv <= 0xfff)) {
  167. setRgba(rgbaArr, 0, 0, 0, 1);
  168. return;
  169. }
  170. setRgba(rgbaArr, ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), (iv & 0xf0) | ((iv & 0xf0) >> 4), (iv & 0xf) | ((iv & 0xf) << 4), strLen === 5 ? parseInt(str.slice(4), 16) / 0xf : 1);
  171. putToCache(colorStr, rgbaArr);
  172. return rgbaArr;
  173. }
  174. else if (strLen === 7 || strLen === 9) {
  175. var iv = parseInt(str.slice(1, 7), 16);
  176. if (!(iv >= 0 && iv <= 0xffffff)) {
  177. setRgba(rgbaArr, 0, 0, 0, 1);
  178. return;
  179. }
  180. setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, strLen === 9 ? parseInt(str.slice(7), 16) / 0xff : 1);
  181. putToCache(colorStr, rgbaArr);
  182. return rgbaArr;
  183. }
  184. return;
  185. }
  186. var op = str.indexOf('(');
  187. var ep = str.indexOf(')');
  188. if (op !== -1 && ep + 1 === strLen) {
  189. var fname = str.substr(0, op);
  190. var params = str.substr(op + 1, ep - (op + 1)).split(',');
  191. var alpha = 1;
  192. switch (fname) {
  193. case 'rgba':
  194. if (params.length !== 4) {
  195. return params.length === 3
  196. ? setRgba(rgbaArr, +params[0], +params[1], +params[2], 1)
  197. : setRgba(rgbaArr, 0, 0, 0, 1);
  198. }
  199. alpha = parseCssFloat(params.pop());
  200. case 'rgb':
  201. if (params.length >= 3) {
  202. setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), params.length === 3 ? alpha : parseCssFloat(params[3]));
  203. putToCache(colorStr, rgbaArr);
  204. return rgbaArr;
  205. }
  206. else {
  207. setRgba(rgbaArr, 0, 0, 0, 1);
  208. return;
  209. }
  210. case 'hsla':
  211. if (params.length !== 4) {
  212. setRgba(rgbaArr, 0, 0, 0, 1);
  213. return;
  214. }
  215. params[3] = parseCssFloat(params[3]);
  216. hsla2rgba(params, rgbaArr);
  217. putToCache(colorStr, rgbaArr);
  218. return rgbaArr;
  219. case 'hsl':
  220. if (params.length !== 3) {
  221. setRgba(rgbaArr, 0, 0, 0, 1);
  222. return;
  223. }
  224. hsla2rgba(params, rgbaArr);
  225. putToCache(colorStr, rgbaArr);
  226. return rgbaArr;
  227. default:
  228. return;
  229. }
  230. }
  231. setRgba(rgbaArr, 0, 0, 0, 1);
  232. return;
  233. }
  234. function hsla2rgba(hsla, rgba) {
  235. var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;
  236. var s = parseCssFloat(hsla[1]);
  237. var l = parseCssFloat(hsla[2]);
  238. var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
  239. var m1 = l * 2 - m2;
  240. rgba = rgba || [];
  241. 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);
  242. if (hsla.length === 4) {
  243. rgba[3] = hsla[3];
  244. }
  245. return rgba;
  246. }
  247. function rgba2hsla(rgba) {
  248. if (!rgba) {
  249. return;
  250. }
  251. var R = rgba[0] / 255;
  252. var G = rgba[1] / 255;
  253. var B = rgba[2] / 255;
  254. var vMin = Math.min(R, G, B);
  255. var vMax = Math.max(R, G, B);
  256. var delta = vMax - vMin;
  257. var L = (vMax + vMin) / 2;
  258. var H;
  259. var S;
  260. if (delta === 0) {
  261. H = 0;
  262. S = 0;
  263. }
  264. else {
  265. if (L < 0.5) {
  266. S = delta / (vMax + vMin);
  267. }
  268. else {
  269. S = delta / (2 - vMax - vMin);
  270. }
  271. var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
  272. var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
  273. var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;
  274. if (R === vMax) {
  275. H = deltaB - deltaG;
  276. }
  277. else if (G === vMax) {
  278. H = (1 / 3) + deltaR - deltaB;
  279. }
  280. else if (B === vMax) {
  281. H = (2 / 3) + deltaG - deltaR;
  282. }
  283. if (H < 0) {
  284. H += 1;
  285. }
  286. if (H > 1) {
  287. H -= 1;
  288. }
  289. }
  290. var hsla = [H * 360, S, L];
  291. if (rgba[3] != null) {
  292. hsla.push(rgba[3]);
  293. }
  294. return hsla;
  295. }
  296. export function lift(color, level) {
  297. var colorArr = parse(color);
  298. if (colorArr) {
  299. for (var i = 0; i < 3; i++) {
  300. if (level < 0) {
  301. colorArr[i] = colorArr[i] * (1 - level) | 0;
  302. }
  303. else {
  304. colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
  305. }
  306. if (colorArr[i] > 255) {
  307. colorArr[i] = 255;
  308. }
  309. else if (colorArr[i] < 0) {
  310. colorArr[i] = 0;
  311. }
  312. }
  313. return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
  314. }
  315. }
  316. export function toHex(color) {
  317. var colorArr = parse(color);
  318. if (colorArr) {
  319. return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
  320. }
  321. }
  322. export function fastLerp(normalizedValue, colors, out) {
  323. if (!(colors && colors.length)
  324. || !(normalizedValue >= 0 && normalizedValue <= 1)) {
  325. return;
  326. }
  327. out = out || [];
  328. var value = normalizedValue * (colors.length - 1);
  329. var leftIndex = Math.floor(value);
  330. var rightIndex = Math.ceil(value);
  331. var leftColor = colors[leftIndex];
  332. var rightColor = colors[rightIndex];
  333. var dv = value - leftIndex;
  334. out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
  335. out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
  336. out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
  337. out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
  338. return out;
  339. }
  340. export var fastMapToColor = fastLerp;
  341. export function lerp(normalizedValue, colors, fullOutput) {
  342. if (!(colors && colors.length)
  343. || !(normalizedValue >= 0 && normalizedValue <= 1)) {
  344. return;
  345. }
  346. var value = normalizedValue * (colors.length - 1);
  347. var leftIndex = Math.floor(value);
  348. var rightIndex = Math.ceil(value);
  349. var leftColor = parse(colors[leftIndex]);
  350. var rightColor = parse(colors[rightIndex]);
  351. var dv = value - leftIndex;
  352. var color = stringify([
  353. clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)),
  354. clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
  355. clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)),
  356. clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))
  357. ], 'rgba');
  358. return fullOutput
  359. ? {
  360. color: color,
  361. leftIndex: leftIndex,
  362. rightIndex: rightIndex,
  363. value: value
  364. }
  365. : color;
  366. }
  367. export var mapToColor = lerp;
  368. export function modifyHSL(color, h, s, l) {
  369. var colorArr = parse(color);
  370. if (color) {
  371. colorArr = rgba2hsla(colorArr);
  372. h != null && (colorArr[0] = clampCssAngle(h));
  373. s != null && (colorArr[1] = parseCssFloat(s));
  374. l != null && (colorArr[2] = parseCssFloat(l));
  375. return stringify(hsla2rgba(colorArr), 'rgba');
  376. }
  377. }
  378. export function modifyAlpha(color, alpha) {
  379. var colorArr = parse(color);
  380. if (colorArr && alpha != null) {
  381. colorArr[3] = clampCssFloat(alpha);
  382. return stringify(colorArr, 'rgba');
  383. }
  384. }
  385. export function stringify(arrColor, type) {
  386. if (!arrColor || !arrColor.length) {
  387. return;
  388. }
  389. var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
  390. if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
  391. colorStr += ',' + arrColor[3];
  392. }
  393. return type + '(' + colorStr + ')';
  394. }
  395. export function lum(color, backgroundLum) {
  396. var arr = parse(color);
  397. return arr
  398. ? (0.299 * arr[0] + 0.587 * arr[1] + 0.114 * arr[2]) * arr[3] / 255
  399. + (1 - arr[3]) * backgroundLum
  400. : 0;
  401. }
  402. export function random() {
  403. return stringify([
  404. Math.round(Math.random() * 255),
  405. Math.round(Math.random() * 255),
  406. Math.round(Math.random() * 255)
  407. ], 'rgb');
  408. }