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