]> git.proxmox.com Git - extjs.git/blob - extjs/packages/ux/classic/src/colorpick/ColorUtils.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / ux / classic / src / colorpick / ColorUtils.js
1 /**
2 * @private
3 */
4 Ext.define('Ext.ux.colorpick.ColorUtils', function (ColorUtils) {
5 var oldIE = Ext.isIE && Ext.ieVersion < 10;
6
7 return {
8 singleton: true,
9
10 constructor: function () {
11 ColorUtils = this;
12 },
13
14 backgroundTpl: oldIE ?
15 'filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, ' +
16 'startColorstr=\'#{alpha}{hex}\', endColorstr=\'#{alpha}{hex}\');' :
17 'background: {rgba};',
18
19 setBackground: oldIE ? function (el, color) {
20 if (el) {
21 var tpl = Ext.XTemplate.getTpl(ColorUtils, 'backgroundTpl'),
22 data = {
23 hex: ColorUtils.rgb2hex(color.r, color.g, color.b),
24 alpha: Math.floor(color.a * 255).toString(16)
25 },
26 bgStyle = tpl.apply(data);
27
28 el.applyStyles(bgStyle);
29 }
30 } : function (el, color) {
31 if (el) {
32 var tpl = Ext.XTemplate.getTpl(ColorUtils, 'backgroundTpl'),
33 data = {
34 rgba: ColorUtils.getRGBAString(color)
35 },
36 bgStyle = tpl.apply(data);
37
38 el.applyStyles(bgStyle);
39 }
40 },
41
42 // parse and format functions under objects that match supported format config
43 // values of the color picker; parse() methods recieve the supplied color value
44 // as a string (i.e "FFAAAA") and return an object form, just like the one
45 // ColorPickerModel vm "selectedColor" uses. That same object form is used as a
46 // parameter to the format() methods, where the appropriate string form is expected
47 // for the return result
48 formats: {
49 // "FFAA00"
50 HEX6: function(colorO) {
51 return ColorUtils.rgb2hex(colorO.r, colorO.g, colorO.b);
52 },
53
54 // "FFAA00FF" (last 2 are opacity)
55 HEX8: function(colorO) {
56 var hex = ColorUtils.rgb2hex(colorO.r, colorO.g, colorO.b),
57 opacityHex = Math.round(colorO.a * 255).toString(16);
58
59 if (opacityHex.length < 2) {
60 hex += '0';
61 }
62
63 hex += opacityHex.toUpperCase();
64
65 return hex;
66 }
67 },
68
69 hexRe: /#?([0-9a-f]{3,8})/i,
70 rgbaAltRe: /rgba\(\s*([\w#\d]+)\s*,\s*([\d\.]+)\s*\)/,
71 rgbaRe: /rgba\(\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*\)/,
72 rgbRe: /rgb\(\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*\)/,
73
74 /**
75 * Turn a string to a color object. Supports these formats:
76 *
77 * - "#ABC" (HEX short)
78 * - "#ABCDEF" (HEX)
79 * - "#ABCDEFDD" (HEX with opacity)
80 * - "red" (named colors - see
81 * [Web Colors](http://en.wikipedia.org/wiki/Web_colors) for a full list)
82 * - "rgba(r,g,b,a)" i.e "rgba(255,0,0,1)" (a == alpha == 0-1)
83 * - "rgba(red, 0.4)"
84 * - "rgba(#ABC, 0.9)"
85 * - "rgba(#ABCDEF, 0.8)"
86 *
87 * @param {String} color The color string to parse.
88 * @return {Object} Object with various color properties.
89 * @return {Number} return.r The red component (0-255).
90 * @return {Number} return.g The green component (0-255).
91 * @return {Number} return.b The blue component (0-255).
92 * @return {Number} return.a The red component (0-1).
93 * @return {Number} return.h The hue component (0-1).
94 * @return {Number} return.s The saturation component (0-1).
95 * @return {Number} return.v The value component (0-1).
96 */
97 parseColor: function (color) {
98 if (!color) {
99 return null;
100 }
101
102 var me = this,
103 rgb = me.colorMap[color],
104 match, ret, hsv;
105
106 if (rgb) {
107 ret = {
108 r: rgb[0],
109 g: rgb[1],
110 b: rgb[2],
111 a: 1
112 };
113 }
114 else if (color === 'transparent') {
115 ret = {
116 r: 0,
117 g: 0,
118 b: 0,
119 a: 0
120 };
121 }
122 else {
123 match = me.hexRe.exec(color);
124 if (match) {
125 match = match[1]; // the captured hex
126 switch (match.length) {
127 default:
128 return null;
129
130 case 3:
131 ret = {
132 //double the number (e.g. 6 - > 66, a -> aa) and convert to decimal
133 r: parseInt(match[0] + match[0], 16),
134 g: parseInt(match[1] + match[1], 16),
135 b: parseInt(match[2] + match[2], 16),
136 a: 1
137 };
138 break;
139
140 case 6:
141 case 8:
142 ret = {
143 r: parseInt(match.substr(0,2), 16),
144 g: parseInt(match.substr(2,2), 16),
145 b: parseInt(match.substr(4,2), 16),
146 a: parseInt(match.substr(6,2) || 'ff', 16) / 255
147 };
148 break;
149 }
150 }
151 else {
152 match = me.rgbaRe.exec(color);
153 if (match) {
154 // proper css => rgba(r,g,b,a)
155 ret = {
156 r: parseFloat(match[1]),
157 g: parseFloat(match[2]),
158 b: parseFloat(match[3]),
159 a: parseFloat(match[4])
160 };
161 }
162 else {
163 match = me.rgbaAltRe.exec(color);
164 if (match) {
165 // scss shorthands =? rgba(red, 0.4), rgba(#222, 0.9), rgba(#444433, 0.8)
166 ret = me.parseColor(match[1]);
167 // we have HSV filled in, so poke on "a" and we're done
168 ret.a = parseFloat(match[2]);
169 return ret;
170 }
171
172 match = me.rgbRe.exec(color);
173 if (match) {
174 ret = {
175 r: parseFloat(match[1]),
176 g: parseFloat(match[2]),
177 b: parseFloat(match[3]),
178 a: 1
179 };
180 }
181 else {
182 return null;
183 }
184 }
185 }
186 }
187
188 hsv = this.rgb2hsv(ret.r, ret.g, ret.b);
189
190 return Ext.apply(ret, hsv);
191 },
192
193 /**
194 *
195 * @param rgba
196 * @return {String}
197 */
198 getRGBAString: function(rgba) {
199 return "rgba(" + rgba.r + "," + rgba.g + "," + rgba.b + "," + rgba.a + ")";
200 },
201
202 /**
203 * Returns a rgb css string whith this color (without the alpha channel)
204 * @param rgb
205 * @return {String}
206 */
207 getRGBString: function(rgb) {
208 return "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
209 },
210
211 /**
212 * Following standard math to convert from hsl to rgb
213 * Check out wikipedia page for more information on how this works
214 * h => [0,1]
215 * s,l => [0,1]
216 * @param h
217 * @param s
218 * @param v
219 * @return {Object} An object with "r", "g" and "b" color properties.
220 */
221 hsv2rgb: function(h, s, v) {
222 h = h * 360;
223
224 if (h === 360) {
225 h = 0;
226 }
227
228 var c = v * s;
229
230 var hprime = h / 60;
231
232 var x = c * (1 - Math.abs(hprime % 2 - 1));
233
234 var rgb = [0, 0, 0];
235
236 switch (Math.floor(hprime)) {
237 case 0:
238 rgb = [c, x, 0];
239 break;
240 case 1:
241 rgb = [x, c, 0];
242 break;
243 case 2:
244 rgb = [0, c, x];
245 break;
246 case 3:
247 rgb = [0, x, c];
248 break;
249 case 4:
250 rgb = [x, 0, c];
251 break;
252 case 5:
253 rgb = [c, 0, x];
254 break;
255 default:
256 // <debug>
257 console.error("unknown color " + h + ' ' + s + " " + v);
258 // </debug>
259 break;
260 }
261
262 var m = v - c;
263
264 rgb[0] += m;
265 rgb[1] += m;
266 rgb[2] += m;
267
268 rgb[0] = Math.round(rgb[0] * 255);
269 rgb[1] = Math.round(rgb[1] * 255);
270 rgb[2] = Math.round(rgb[2] * 255);
271
272 return {
273 r: rgb[0],
274 g: rgb[1],
275 b: rgb[2]
276 };
277 },
278
279 /**
280 * http://en.wikipedia.org/wiki/HSL_and_HSV
281 * @param {Number} r The red component (0-255).
282 * @param {Number} g The green component (0-255).
283 * @param {Number} b The blue component (0-255).
284 * @return {Object} An object with "h", "s" and "v" color properties.
285 */
286 rgb2hsv: function(r,g,b) {
287 r = r / 255;
288 g = g / 255;
289 b = b / 255;
290
291 var M = Math.max(r,g,b);
292 var m = Math.min(r,g,b);
293 var c = M - m;
294
295 var hprime = 0;
296 if (c !== 0) {
297 if (M === r) {
298 hprime = ((g - b) / c) % 6;
299 } else if (M === g) {
300 hprime = ((b - r) / c) + 2;
301 } else if (M === b) {
302 hprime = ((r - g) / c) + 4;
303 }
304 }
305
306 var h = hprime * 60;
307 if (h === 360) {
308 h = 0;
309 }
310
311 var v = M;
312
313 var s = 0;
314 if (c !== 0) {
315 s = c/v;
316 }
317
318 h = h / 360;
319
320 if (h < 0) {
321 h = h + 1;
322 }
323
324 return {
325 h: h,
326 s: s,
327 v: v
328 };
329 },
330
331 /**
332 *
333 * @param r
334 * @param g
335 * @param b
336 * @return {String}
337 */
338 rgb2hex: function(r, g, b) {
339 r = r.toString(16);
340 g = g.toString(16);
341 b = b.toString(16);
342
343 if (r.length < 2) {
344 r = '0' + r;
345 }
346
347 if (g.length < 2) {
348 g = '0' + g;
349 }
350
351 if (b.length < 2) {
352 b = '0' + b;
353 }
354
355 return (r + g + b).toUpperCase();
356 },
357
358 colorMap: {
359 aliceblue: [240, 248, 255],
360 antiquewhite: [250, 235, 215],
361 aqua: [0, 255, 255],
362 aquamarine: [127, 255, 212],
363 azure: [240, 255, 255],
364 beige: [245, 245, 220],
365 bisque: [255, 228, 196],
366 black: [0, 0, 0],
367 blanchedalmond: [255, 235, 205],
368 blue: [0, 0, 255],
369 blueviolet: [138, 43, 226],
370 brown: [165, 42, 42],
371 burlywood: [222, 184, 135],
372 cadetblue: [95, 158, 160],
373 chartreuse: [127, 255, 0],
374 chocolate: [210, 105, 30],
375 coral: [255, 127, 80],
376 cornflowerblue: [100, 149, 237],
377 cornsilk: [255, 248, 220],
378 crimson: [220, 20, 60],
379 cyan: [0, 255, 255],
380 darkblue: [0, 0, 139],
381 darkcyan: [0, 139, 139],
382 darkgoldenrod: [184, 132, 11],
383 darkgray: [169, 169, 169],
384 darkgreen: [0, 100, 0],
385 darkgrey: [169, 169, 169],
386 darkkhaki: [189, 183, 107],
387 darkmagenta: [139, 0, 139],
388 darkolivegreen: [85, 107, 47],
389 darkorange: [255, 140, 0],
390 darkorchid: [153, 50, 204],
391 darkred: [139, 0, 0],
392 darksalmon: [233, 150, 122],
393 darkseagreen: [143, 188, 143],
394 darkslateblue: [72, 61, 139],
395 darkslategray: [47, 79, 79],
396 darkslategrey: [47, 79, 79],
397 darkturquoise: [0, 206, 209],
398 darkviolet: [148, 0, 211],
399 deeppink: [255, 20, 147],
400 deepskyblue: [0, 191, 255],
401 dimgray: [105, 105, 105],
402 dimgrey: [105, 105, 105],
403 dodgerblue: [30, 144, 255],
404 firebrick: [178, 34, 34],
405 floralwhite: [255, 255, 240],
406 forestgreen: [34, 139, 34],
407 fuchsia: [255, 0, 255],
408 gainsboro: [220, 220, 220],
409 ghostwhite: [248, 248, 255],
410 gold: [255, 215, 0],
411 goldenrod: [218, 165, 32],
412 gray: [128, 128, 128],
413 green: [0, 128, 0],
414 greenyellow: [173, 255, 47],
415 grey: [128, 128, 128],
416 honeydew: [240, 255, 240],
417 hotpink: [255, 105, 180],
418 indianred: [205, 92, 92],
419 indigo: [75, 0, 130],
420 ivory: [255, 255, 240],
421 khaki: [240, 230, 140],
422 lavender: [230, 230, 250],
423 lavenderblush: [255, 240, 245],
424 lawngreen: [124, 252, 0],
425 lemonchiffon: [255, 250, 205],
426 lightblue: [173, 216, 230],
427 lightcoral: [240, 128, 128],
428 lightcyan: [224, 255, 255],
429 lightgoldenrodyellow: [250, 250, 210],
430 lightgray: [211, 211, 211],
431 lightgreen: [144, 238, 144],
432 lightgrey: [211, 211, 211],
433 lightpink: [255, 182, 193],
434 lightsalmon: [255, 160, 122],
435 lightseagreen: [32, 178, 170],
436 lightskyblue: [135, 206, 250],
437 lightslategray: [119, 136, 153],
438 lightslategrey: [119, 136, 153],
439 lightsteelblue: [176, 196, 222],
440 lightyellow: [255, 255, 224],
441 lime: [0, 255, 0],
442 limegreen: [50, 205, 50],
443 linen: [250, 240, 230],
444 magenta: [255, 0, 255],
445 maroon: [128, 0, 0],
446 mediumaquamarine: [102, 205, 170],
447 mediumblue: [0, 0, 205],
448 mediumorchid: [186, 85, 211],
449 mediumpurple: [147, 112, 219],
450 mediumseagreen: [60, 179, 113],
451 mediumslateblue: [123, 104, 238],
452 mediumspringgreen: [0, 250, 154],
453 mediumturquoise: [72, 209, 204],
454 mediumvioletred: [199, 21, 133],
455 midnightblue: [25, 25, 112],
456 mintcream: [245, 255, 250],
457 mistyrose: [255, 228, 225],
458 moccasin: [255, 228, 181],
459 navajowhite: [255, 222, 173],
460 navy: [0, 0, 128],
461 oldlace: [253, 245, 230],
462 olive: [128, 128, 0],
463 olivedrab: [107, 142, 35],
464 orange: [255, 165, 0],
465 orangered: [255, 69, 0],
466 orchid: [218, 112, 214],
467 palegoldenrod: [238, 232, 170],
468 palegreen: [152, 251, 152],
469 paleturquoise: [175, 238, 238],
470 palevioletred: [219, 112, 147],
471 papayawhip: [255, 239, 213],
472 peachpuff: [255, 218, 185],
473 peru: [205, 133, 63],
474 pink: [255, 192, 203],
475 plum: [221, 160, 203],
476 powderblue: [176, 224, 230],
477 purple: [128, 0, 128],
478 red: [255, 0, 0],
479 rosybrown: [188, 143, 143],
480 royalblue: [65, 105, 225],
481 saddlebrown: [139, 69, 19],
482 salmon: [250, 128, 114],
483 sandybrown: [244, 164, 96],
484 seagreen: [46, 139, 87],
485 seashell: [255, 245, 238],
486 sienna: [160, 82, 45],
487 silver: [192, 192, 192],
488 skyblue: [135, 206, 235],
489 slateblue: [106, 90, 205],
490 slategray: [119, 128, 144],
491 slategrey: [119, 128, 144],
492 snow: [255, 255, 250],
493 springgreen: [0, 255, 127],
494 steelblue: [70, 130, 180],
495 tan: [210, 180, 140],
496 teal: [0, 128, 128],
497 thistle: [216, 191, 216],
498 tomato: [255, 99, 71],
499 turquoise: [64, 224, 208],
500 violet: [238, 130, 238],
501 wheat: [245, 222, 179],
502 white: [255, 255, 255],
503 whitesmoke: [245, 245, 245],
504 yellow: [255, 255, 0],
505 yellowgreen: [154, 205, 5]
506 }
507 };
508 },
509 function (ColorUtils) {
510 var formats = ColorUtils.formats,
511 lowerized = {};
512
513 formats['#HEX6'] = function (color) {
514 return '#' + formats.HEX6(color);
515 };
516
517 formats['#HEX8'] = function (color) {
518 return '#' + formats.HEX8(color);
519 };
520
521 Ext.Object.each(formats, function (name, fn) {
522 lowerized[name.toLowerCase()] = function (color) {
523 var ret = fn(color);
524 return ret.toLowerCase();
525 }
526 });
527
528 Ext.apply(formats, lowerized);
529 });