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