OSDN Git Service

embr
[embrj/master.git] / js / colorpicker3.js
1 /**\r
2  *\r
3  * Color picker\r
4  * Author: Stefan Petre www.eyecon.ro\r
5  * \r
6  * Dual licensed under the MIT and GPL licenses\r
7  * \r
8  */\r
9 (function ($) {\r
10         var ColorPicker = function () {\r
11                 var\r
12                         ids = {},\r
13                         inAction,\r
14                         charMin = 65,\r
15                         visible,\r
16                         tpl = '<div class="colorpicker"><div class="colorpicker_color"><div><div></div></div></div><div class="colorpicker_hue"><div></div></div><div class="colorpicker_new_color"></div><div class="colorpicker_current_color"></div><div class="colorpicker_hex"><input type="text" maxlength="6" size="6" /></div><div class="colorpicker_rgb_r colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_g colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_h colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_s colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_submit"><button type="button" name="submit">Done</button></div></div>',\r
17                         defaults = {\r
18                                 eventName: 'click',\r
19                                 onShow: function () {},\r
20                                 onBeforeShow: function(){},\r
21                                 onHide: function () {},\r
22                                 onChange: function () {},\r
23                                 onSubmit: function () {},\r
24                                 color: 'ff0000',\r
25                                 livePreview: true,\r
26                                 flat: false\r
27                         },\r
28                         fillRGBFields = function  (hsb, cal) {\r
29                                 var rgb = HSBToRGB(hsb);\r
30                                 $(cal).data('colorpicker').fields\r
31                                         .eq(1).val(rgb.r).end()\r
32                                         .eq(2).val(rgb.g).end()\r
33                                         .eq(3).val(rgb.b).end();\r
34                         },\r
35                         fillHSBFields = function  (hsb, cal) {\r
36                                 $(cal).data('colorpicker').fields\r
37                                         .eq(4).val(hsb.h).end()\r
38                                         .eq(5).val(hsb.s).end()\r
39                                         .eq(6).val(hsb.b).end();\r
40                         },\r
41                         fillHexFields = function (hsb, cal) {\r
42                                 $(cal).data('colorpicker').fields\r
43                                         .eq(0).val(HSBToHex(hsb)).end();\r
44                         },\r
45                         setSelector = function (hsb, cal) {\r
46                                 $(cal).data('colorpicker').selector.css('backgroundColor', '#' + HSBToHex({h: hsb.h, s: 100, b: 100}));\r
47                                 $(cal).data('colorpicker').selectorIndic.css({\r
48                                         left: parseInt(150 * hsb.s/100, 10),\r
49                                         top: parseInt(150 * (100-hsb.b)/100, 10)\r
50                                 });\r
51                         },\r
52                         setHue = function (hsb, cal) {\r
53                                 $(cal).data('colorpicker').hue.css('top', parseInt(150 - 150 * hsb.h/360, 10));\r
54                         },\r
55                         setCurrentColor = function (hsb, cal) {\r
56                                 $(cal).data('colorpicker').currentColor.css('backgroundColor', '#' + HSBToHex(hsb));\r
57                         },\r
58                         setNewColor = function (hsb, cal) {\r
59                                 $(cal).data('colorpicker').newColor.css('backgroundColor', '#' + HSBToHex(hsb));\r
60                         },\r
61                         keyDown = function (ev) {\r
62                                 var pressedKey = ev.charCode || ev.keyCode || -1;\r
63                                 if ((pressedKey > charMin && pressedKey <= 90) || pressedKey == 32) {\r
64                                         return false;\r
65                                 }\r
66                                 var cal = $(this).parent().parent();\r
67                                 if (cal.data('colorpicker').livePreview === true) {\r
68                                         change.apply(this);\r
69                                 }\r
70                         },\r
71                         change = function (ev) {\r
72                                 var cal = $(this).parent().parent(), col;\r
73                                 if (this.parentNode.className.indexOf('_hex') > 0) {\r
74                                         cal.data('colorpicker').color = col = HexToHSB(fixHex(this.value));\r
75                                 } else if (this.parentNode.className.indexOf('_hsb') > 0) {\r
76                                         cal.data('colorpicker').color = col = fixHSB({\r
77                                                 h: parseInt(cal.data('colorpicker').fields.eq(4).val(), 10),\r
78                                                 s: parseInt(cal.data('colorpicker').fields.eq(5).val(), 10),\r
79                                                 b: parseInt(cal.data('colorpicker').fields.eq(6).val(), 10)\r
80                                         });\r
81                                 } else {\r
82                                         cal.data('colorpicker').color = col = RGBToHSB(fixRGB({\r
83                                                 r: parseInt(cal.data('colorpicker').fields.eq(1).val(), 10),\r
84                                                 g: parseInt(cal.data('colorpicker').fields.eq(2).val(), 10),\r
85                                                 b: parseInt(cal.data('colorpicker').fields.eq(3).val(), 10)\r
86                                         }));\r
87                                 }\r
88                                 if (ev) {\r
89                                         fillRGBFields(col, cal.get(0));\r
90                                         fillHexFields(col, cal.get(0));\r
91                                         fillHSBFields(col, cal.get(0));\r
92                                 }\r
93                                 setSelector(col, cal.get(0));\r
94                                 setHue(col, cal.get(0));\r
95                                 setNewColor(col, cal.get(0));\r
96                                 cal.data('colorpicker').onChange.apply(cal, [col, HSBToHex(col), HSBToRGB(col)]);\r
97                         },\r
98                         blur = function (ev) {\r
99                                 var cal = $(this).parent().parent();\r
100                                 cal.data('colorpicker').fields.parent().removeClass('colorpicker_focus');\r
101                         },\r
102                         focus = function () {\r
103                                 charMin = this.parentNode.className.indexOf('_hex') > 0 ? 70 : 65;\r
104                                 $(this).parent().parent().data('colorpicker').fields.parent().removeClass('colorpicker_focus');\r
105                                 $(this).parent().addClass('colorpicker_focus');\r
106                         },\r
107                         downIncrement = function (ev) {\r
108                                 var field = $(this).parent().find('input').focus();\r
109                                 var current = {\r
110                                         el: $(this).parent().addClass('colorpicker_slider'),\r
111                                         max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255),\r
112                                         y: ev.pageY,\r
113                                         field: field,\r
114                                         val: parseInt(field.val(), 10),\r
115                                         preview: $(this).parent().parent().data('colorpicker').livePreview                                      \r
116                                 };\r
117                                 $(document).bind('mouseup', current, upIncrement);\r
118                                 $(document).bind('mousemove', current, moveIncrement);\r
119                         },\r
120                         moveIncrement = function (ev) {\r
121                                 ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val + ev.pageY - ev.data.y, 10))));\r
122                                 if (ev.data.preview) {\r
123                                         change.apply(ev.data.field.get(0), [true]);\r
124                                 }\r
125                                 return false;\r
126                         },\r
127                         upIncrement = function (ev) {\r
128                                 change.apply(ev.data.field.get(0), [true]);\r
129                                 ev.data.el.removeClass('colorpicker_slider').find('input').focus();\r
130                                 $(document).unbind('mouseup', upIncrement);\r
131                                 $(document).unbind('mousemove', moveIncrement);\r
132                                 return false;\r
133                         },\r
134                         downHue = function (ev) {\r
135                                 var current = {\r
136                                         cal: $(this).parent(),\r
137                                         y: $(this).offset().top\r
138                                 };\r
139                                 current.preview = current.cal.data('colorpicker').livePreview;\r
140                                 $(document).bind('mouseup', current, upHue);\r
141                                 $(document).bind('mousemove', current, moveHue);\r
142                         },\r
143                         moveHue = function (ev) {\r
144                                 change.apply(\r
145                                         ev.data.cal.data('colorpicker')\r
146                                                 .fields\r
147                                                 .eq(4)\r
148                                                 .val(parseInt(360*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.y))))/150, 10))\r
149                                                 .get(0),\r
150                                         [ev.data.preview]\r
151                                 );\r
152                                 return false;\r
153                         },\r
154                         upHue = function (ev) {\r
155                                 fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));\r
156                                 fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));\r
157                                 $(document).unbind('mouseup', upHue);\r
158                                 $(document).unbind('mousemove', moveHue);\r
159                                 return false;\r
160                         },\r
161                         downSelector = function (ev) {\r
162                                 var current = {\r
163                                         cal: $(this).parent(),\r
164                                         pos: $(this).offset()\r
165                                 };\r
166                                 current.preview = current.cal.data('colorpicker').livePreview;\r
167                                 $(document).bind('mouseup', current, upSelector);\r
168                                 $(document).bind('mousemove', current, moveSelector);\r
169                         },\r
170                         moveSelector = function (ev) {\r
171                                 change.apply(\r
172                                         ev.data.cal.data('colorpicker')\r
173                                                 .fields\r
174                                                 .eq(6)\r
175                                                 .val(parseInt(100*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.pos.top))))/150, 10))\r
176                                                 .end()\r
177                                                 .eq(5)\r
178                                                 .val(parseInt(100*(Math.max(0,Math.min(150,(ev.pageX - ev.data.pos.left))))/150, 10))\r
179                                                 .get(0),\r
180                                         [ev.data.preview]\r
181                                 );\r
182                                 return false;\r
183                         },\r
184                         upSelector = function (ev) {\r
185                                 fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));\r
186                                 fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));\r
187                                 $(document).unbind('mouseup', upSelector);\r
188                                 $(document).unbind('mousemove', moveSelector);\r
189                                 return false;\r
190                         },\r
191                         enterSubmit = function (ev) {\r
192                                 $(this).addClass('colorpicker_focus');\r
193                         },\r
194                         leaveSubmit = function (ev) {\r
195                                 $(this).removeClass('colorpicker_focus');\r
196                         },\r
197                         clickSubmit = function (ev) {\r
198                                 var cal = $(this).parent();\r
199                                 var col = cal.data('colorpicker').color;\r
200                                 cal.data('colorpicker').origColor = col;\r
201                                 setCurrentColor(col, cal.get(0));\r
202                                 cal.data('colorpicker').onSubmit(col, HSBToHex(col), HSBToRGB(col), cal.data('colorpicker').el);\r
203                         },\r
204                         show = function (ev) {\r
205                                 var cal = $('#' + $(this).data('colorpickerId'));\r
206                                 cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]);\r
207                                 var pos = $(this).offset();\r
208                                 var viewPort = getViewport();\r
209                                 var top = pos.top + this.offsetHeight;\r
210                                 var left = pos.left;\r
211                                 if (top + 176 > viewPort.t + viewPort.h) {\r
212                                         top -= this.offsetHeight + 176;\r
213                                 }\r
214                                 if (left + 356 > viewPort.l + viewPort.w) {\r
215                                         left -= 356;\r
216                                 }\r
217                                 cal.css({left: left + 'px', top: top + 'px'});\r
218                                 if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) != false) {\r
219                                         cal.show();\r
220                                 }\r
221                                 $(document).bind('mousedown', {cal: cal}, hide);\r
222                                 return false;\r
223                         },\r
224                         hide = function (ev) {\r
225                                 if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {\r
226                                         if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {\r
227                                                 ev.data.cal.hide();\r
228                                         }\r
229                                         $(document).unbind('mousedown', hide);\r
230                                 }\r
231                         },\r
232                         isChildOf = function(parentEl, el, container) {\r
233                                 if (parentEl == el) {\r
234                                         return true;\r
235                                 }\r
236                                 if (parentEl.contains) {\r
237                                         return parentEl.contains(el);\r
238                                 }\r
239                                 if ( parentEl.compareDocumentPosition ) {\r
240                                         return !!(parentEl.compareDocumentPosition(el) & 16);\r
241                                 }\r
242                                 var prEl = el.parentNode;\r
243                                 while(prEl && prEl != container) {\r
244                                         if (prEl == parentEl)\r
245                                                 return true;\r
246                                         prEl = prEl.parentNode;\r
247                                 }\r
248                                 return false;\r
249                         },\r
250                         getViewport = function () {\r
251                                 var m = document.compatMode == 'CSS1Compat';\r
252                                 return {\r
253                                         l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),\r
254                                         t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),\r
255                                         w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),\r
256                                         h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)\r
257                                 };\r
258                         },\r
259                         fixHSB = function (hsb) {\r
260                                 return {\r
261                                         h: Math.min(360, Math.max(0, hsb.h)),\r
262                                         s: Math.min(100, Math.max(0, hsb.s)),\r
263                                         b: Math.min(100, Math.max(0, hsb.b))\r
264                                 };\r
265                         }, \r
266                         fixRGB = function (rgb) {\r
267                                 return {\r
268                                         r: Math.min(255, Math.max(0, rgb.r)),\r
269                                         g: Math.min(255, Math.max(0, rgb.g)),\r
270                                         b: Math.min(255, Math.max(0, rgb.b))\r
271                                 };\r
272                         },\r
273                         fixHex = function (hex) {\r
274                                 var len = 6 - hex.length;\r
275                                 if (len > 0) {\r
276                                         var o = [];\r
277                                         for (var i=0; i<len; i++) {\r
278                                                 o.push('0');\r
279                                         }\r
280                                         o.push(hex);\r
281                                         hex = o.join('');\r
282                                 }\r
283                                 return hex;\r
284                         }, \r
285                         HexToRGB = function (hex) {\r
286                                 var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);\r
287                                 return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};\r
288                         },\r
289                         HexToHSB = function (hex) {\r
290                                 return RGBToHSB(HexToRGB(hex));\r
291                         },\r
292                         RGBToHSB = function (rgb) {\r
293                                 var hsb = {\r
294                                         h: 0,\r
295                                         s: 0,\r
296                                         b: 0\r
297                                 };\r
298                                 var min = Math.min(rgb.r, rgb.g, rgb.b);\r
299                                 var max = Math.max(rgb.r, rgb.g, rgb.b);\r
300                                 var delta = max - min;\r
301                                 hsb.b = max;\r
302                                 if (max != 0) {\r
303                                         \r
304                                 }\r
305                                 hsb.s = max != 0 ? 255 * delta / max : 0;\r
306                                 if (hsb.s != 0) {\r
307                                         if (rgb.r == max) {\r
308                                                 hsb.h = (rgb.g - rgb.b) / delta;\r
309                                         } else if (rgb.g == max) {\r
310                                                 hsb.h = 2 + (rgb.b - rgb.r) / delta;\r
311                                         } else {\r
312                                                 hsb.h = 4 + (rgb.r - rgb.g) / delta;\r
313                                         }\r
314                                 } else {\r
315                                         hsb.h = -1;\r
316                                 }\r
317                                 hsb.h *= 60;\r
318                                 if (hsb.h < 0) {\r
319                                         hsb.h += 360;\r
320                                 }\r
321                                 hsb.s *= 100/255;\r
322                                 hsb.b *= 100/255;\r
323                                 return hsb;\r
324                         },\r
325                         HSBToRGB = function (hsb) {\r
326                                 var rgb = {};\r
327                                 var h = Math.round(hsb.h);\r
328                                 var s = Math.round(hsb.s*255/100);\r
329                                 var v = Math.round(hsb.b*255/100);\r
330                                 if(s == 0) {\r
331                                         rgb.r = rgb.g = rgb.b = v;\r
332                                 } else {\r
333                                         var t1 = v;\r
334                                         var t2 = (255-s)*v/255;\r
335                                         var t3 = (t1-t2)*(h%60)/60;\r
336                                         if(h==360) h = 0;\r
337                                         if(h<60) {rgb.r=t1;     rgb.b=t2; rgb.g=t2+t3}\r
338                                         else if(h<120) {rgb.g=t1; rgb.b=t2;     rgb.r=t1-t3}\r
339                                         else if(h<180) {rgb.g=t1; rgb.r=t2;     rgb.b=t2+t3}\r
340                                         else if(h<240) {rgb.b=t1; rgb.r=t2;     rgb.g=t1-t3}\r
341                                         else if(h<300) {rgb.b=t1; rgb.g=t2;     rgb.r=t2+t3}\r
342                                         else if(h<360) {rgb.r=t1; rgb.g=t2;     rgb.b=t1-t3}\r
343                                         else {rgb.r=0; rgb.g=0; rgb.b=0}\r
344                                 }\r
345                                 return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)};\r
346                         },\r
347                         RGBToHex = function (rgb) {\r
348                                 var hex = [\r
349                                         rgb.r.toString(16),\r
350                                         rgb.g.toString(16),\r
351                                         rgb.b.toString(16)\r
352                                 ];\r
353                                 $.each(hex, function (nr, val) {\r
354                                         if (val.length == 1) {\r
355                                                 hex[nr] = '0' + val;\r
356                                         }\r
357                                 });\r
358                                 return hex.join('');\r
359                         },\r
360                         HSBToHex = function (hsb) {\r
361                                 return RGBToHex(HSBToRGB(hsb));\r
362                         },\r
363                         restoreOriginal = function () {\r
364                                 var cal = $(this).parent();\r
365                                 var col = cal.data('colorpicker').origColor;\r
366                                 cal.data('colorpicker').color = col;\r
367                                 fillRGBFields(col, cal.get(0));\r
368                                 fillHexFields(col, cal.get(0));\r
369                                 fillHSBFields(col, cal.get(0));\r
370                                 setSelector(col, cal.get(0));\r
371                                 setHue(col, cal.get(0));\r
372                                 setNewColor(col, cal.get(0));\r
373                         };\r
374                 return {\r
375                         init: function (opt) {\r
376                                 opt = $.extend({}, defaults, opt||{});\r
377                                 if (typeof opt.color == 'string') {\r
378                                         opt.color = HexToHSB(opt.color);\r
379                                 } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) {\r
380                                         opt.color = RGBToHSB(opt.color);\r
381                                 } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) {\r
382                                         opt.color = fixHSB(opt.color);\r
383                                 } else {\r
384                                         return this;\r
385                                 }\r
386                                 return this.each(function () {\r
387                                         if (!$(this).data('colorpickerId')) {\r
388                                                 var options = $.extend({}, opt);\r
389                                                 options.origColor = opt.color;\r
390                                                 var id = 'collorpicker_' + parseInt(Math.random() * 1000);\r
391                                                 $(this).data('colorpickerId', id);\r
392                                                 var cal = $(tpl).attr('id', id);\r
393                                                 if (options.flat) {\r
394                                                         cal.appendTo(this).show();\r
395                                                 } else {\r
396                                                         cal.appendTo(document.body);\r
397                                                 }\r
398                                                 options.fields = cal\r
399                                                                                         .find('input')\r
400                                                                                                 .bind('keyup', keyDown)\r
401                                                                                                 .bind('change', change)\r
402                                                                                                 .bind('blur', blur)\r
403                                                                                                 .bind('focus', focus);\r
404                                                 cal\r
405                                                         .find('span').bind('mousedown', downIncrement).end()\r
406                                                         .find('>div.colorpicker_current_color').bind('click', restoreOriginal);\r
407                                                 options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector);\r
408                                                 options.selectorIndic = options.selector.find('div div');\r
409                                                 options.el = this;\r
410                                                 options.hue = cal.find('div.colorpicker_hue div');\r
411                                                 cal.find('div.colorpicker_hue').bind('mousedown', downHue);\r
412                                                 options.newColor = cal.find('div.colorpicker_new_color');\r
413                                                 options.currentColor = cal.find('div.colorpicker_current_color');\r
414                                                 cal.data('colorpicker', options);\r
415                                                 cal.find('div.colorpicker_submit')\r
416                                                         .bind('mouseenter', enterSubmit)\r
417                                                         .bind('mouseleave', leaveSubmit)\r
418                                                         .bind('click', clickSubmit);\r
419                                                 fillRGBFields(options.color, cal.get(0));\r
420                                                 fillHSBFields(options.color, cal.get(0));\r
421                                                 fillHexFields(options.color, cal.get(0));\r
422                                                 setHue(options.color, cal.get(0));\r
423                                                 setSelector(options.color, cal.get(0));\r
424                                                 setCurrentColor(options.color, cal.get(0));\r
425                                                 setNewColor(options.color, cal.get(0));\r
426                                                 if (options.flat) {\r
427                                                         cal.css({\r
428                                                                 position: 'relative',\r
429                                                                 display: 'block'\r
430                                                         });\r
431                                                 } else {\r
432                                                         $(this).bind(options.eventName, show);\r
433                                                 }\r
434                                         }\r
435                                 });\r
436                         },\r
437                         showPicker: function() {\r
438                                 return this.each( function () {\r
439                                         if ($(this).data('colorpickerId')) {\r
440                                                 show.apply(this);\r
441                                         }\r
442                                 });\r
443                         },\r
444                         hidePicker: function() {\r
445                                 return this.each( function () {\r
446                                         if ($(this).data('colorpickerId')) {\r
447                                                 $('#' + $(this).data('colorpickerId')).hide();\r
448                                         }\r
449                                 });\r
450                         },\r
451                         setColor: function(col) {\r
452                                 if (typeof col == 'string') {\r
453                                         col = HexToHSB(col);\r
454                                 } else if (col.r != undefined && col.g != undefined && col.b != undefined) {\r
455                                         col = RGBToHSB(col);\r
456                                 } else if (col.h != undefined && col.s != undefined && col.b != undefined) {\r
457                                         col = fixHSB(col);\r
458                                 } else {\r
459                                         return this;\r
460                                 }\r
461                                 return this.each(function(){\r
462                                         if ($(this).data('colorpickerId')) {\r
463                                                 var cal = $('#' + $(this).data('colorpickerId'));\r
464                                                 cal.data('colorpicker').color = col;\r
465                                                 cal.data('colorpicker').origColor = col;\r
466                                                 fillRGBFields(col, cal.get(0));\r
467                                                 fillHSBFields(col, cal.get(0));\r
468                                                 fillHexFields(col, cal.get(0));\r
469                                                 setHue(col, cal.get(0));\r
470                                                 setSelector(col, cal.get(0));\r
471                                                 setCurrentColor(col, cal.get(0));\r
472                                                 setNewColor(col, cal.get(0));\r
473                                         }\r
474                                 });\r
475                         }\r
476                 };\r
477         }();\r
478         $.fn.extend({\r
479                 ColorPicker: ColorPicker.init,\r
480                 ColorPickerHide: ColorPicker.hidePicker,\r
481                 ColorPickerShow: ColorPicker.showPicker,\r
482                 ColorPickerSetColor: ColorPicker.setColor\r
483         });\r
484 })(jQuery)