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 // 07.04.2014: Der Colorpicker funktioniert beim Klick-Event auf den Farb-Slider nicht korrekt, nur bei Move. 156 moveHue(ev); 157 158 fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); 159 fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); 160 $(document).unbind('mouseup', upHue); 161 $(document).unbind('mousemove', moveHue); 162 return false; 163 }, 164 downSelector = function (ev) { 165 var current = { 166 cal: $(this).parent(), 167 pos: $(this).offset() 168 }; 169 current.preview = current.cal.data('colorpicker').livePreview; 170 $(document).bind('mouseup', current, upSelector); 171 $(document).bind('mousemove', current, moveSelector); 172 }, 173 moveSelector = function (ev) { 174 change.apply( 175 ev.data.cal.data('colorpicker') 176 .fields 177 .eq(6) 178 .val(parseInt(100*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.pos.top))))/150, 10)) 179 .end() 180 .eq(5) 181 .val(parseInt(100*(Math.max(0,Math.min(150,(ev.pageX - ev.data.pos.left))))/150, 10)) 182 .get(0), 183 [ev.data.preview] 184 ); 185 return false; 186 }, 187 upSelector = function (ev) { 188 // 07.04.2014: Der Colorpicker funktioniert beim Klick-Event auf die Farbe nicht korrekt, nur bei Move. 189 moveSelector(ev); 190 191 fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); 192 fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); 193 $(document).unbind('mouseup', upSelector); 194 $(document).unbind('mousemove', moveSelector); 195 return false; 196 }, 197 enterSubmit = function (ev) { 198 $(this).addClass('colorpicker_focus'); 199 }, 200 leaveSubmit = function (ev) { 201 $(this).removeClass('colorpicker_focus'); 202 }, 203 clickSubmit = function (ev) { 204 var cal = $(this).parent(); 205 var col = cal.data('colorpicker').color; 206 cal.data('colorpicker').origColor = col; 207 setCurrentColor(col, cal.get(0)); 208 cal.data('colorpicker').onSubmit(col, HSBToHex(col), HSBToRGB(col), cal.data('colorpicker').el); 209 }, 210 show = function (ev) { 211 var cal = $('#' + $(this).data('colorpickerId')); 212 cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]); 213 var pos = $(this).offset(); 214 var viewPort = getViewport(); 215 var top = pos.top + this.offsetHeight; 216 var left = pos.left; 217 if (top + 176 > viewPort.t + viewPort.h) { 218 top -= this.offsetHeight + 176; 219 } 220 if (left + 356 > viewPort.l + viewPort.w) { 221 left -= 356; 222 } 223 cal.css({left: left + 'px', top: top + 'px'}); 224 if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) != false) { 225 cal.show(); 226 } 227 $(document).bind('mousedown', {cal: cal}, hide); 228 return false; 229 }, 230 hide = function (ev) { 231 if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) { 232 if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) { 233 ev.data.cal.hide(); 234 } 235 $(document).unbind('mousedown', hide); 236 } 237 }, 238 isChildOf = function(parentEl, el, container) { 239 if (parentEl == el) { 240 return true; 241 } 242 if (parentEl.contains) { 243 return parentEl.contains(el); 244 } 245 if ( parentEl.compareDocumentPosition ) { 246 return !!(parentEl.compareDocumentPosition(el) & 16); 247 } 248 var prEl = el.parentNode; 249 while(prEl && prEl != container) { 250 if (prEl == parentEl) 251 return true; 252 prEl = prEl.parentNode; 253 } 254 return false; 255 }, 256 getViewport = function () { 257 var m = document.compatMode == 'CSS1Compat'; 258 return { 259 l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), 260 t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop), 261 w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth), 262 h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight) 263 }; 264 }, 265 fixHSB = function (hsb) { 266 return { 267 h: Math.min(360, Math.max(0, hsb.h)), 268 s: Math.min(100, Math.max(0, hsb.s)), 269 b: Math.min(100, Math.max(0, hsb.b)) 270 }; 271 }, 272 fixRGB = function (rgb) { 273 return { 274 r: Math.min(255, Math.max(0, rgb.r)), 275 g: Math.min(255, Math.max(0, rgb.g)), 276 b: Math.min(255, Math.max(0, rgb.b)) 277 }; 278 }, 279 fixHex = function (hex) { 280 var len = 6 - hex.length; 281 if (len > 0) { 282 var o = []; 283 for (var i=0; i<len; i++) { 284 o.push('0'); 285 } 286 o.push(hex); 287 hex = o.join(''); 288 } 289 return hex; 290 }, 291 HexToRGB = function (hex) { 292 var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); 293 return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)}; 294 }, 295 HexToHSB = function (hex) { 296 return RGBToHSB(HexToRGB(hex)); 297 }, 298 RGBToHSB = function (rgb) { 299 var hsb = { 300 h: 0, 301 s: 0, 302 b: 0 303 }; 304 var min = Math.min(rgb.r, rgb.g, rgb.b); 305 var max = Math.max(rgb.r, rgb.g, rgb.b); 306 var delta = max - min; 307 hsb.b = max; 308 if (max != 0) { 309 310 } 311 hsb.s = max != 0 ? 255 * delta / max : 0; 312 if (hsb.s != 0) { 313 if (rgb.r == max) { 314 hsb.h = (rgb.g - rgb.b) / delta; 315 } else if (rgb.g == max) { 316 hsb.h = 2 + (rgb.b - rgb.r) / delta; 317 } else { 318 hsb.h = 4 + (rgb.r - rgb.g) / delta; 319 } 320 } else { 321 hsb.h = -1; 322 } 323 hsb.h *= 60; 324 if (hsb.h < 0) { 325 hsb.h += 360; 326 } 327 hsb.s *= 100/255; 328 hsb.b *= 100/255; 329 return hsb; 330 }, 331 HSBToRGB = function (hsb) { 332 var rgb = {}; 333 var h = Math.round(hsb.h); 334 var s = Math.round(hsb.s*255/100); 335 var v = Math.round(hsb.b*255/100); 336 if(s == 0) { 337 rgb.r = rgb.g = rgb.b = v; 338 } else { 339 var t1 = v; 340 var t2 = (255-s)*v/255; 341 var t3 = (t1-t2)*(h%60)/60; 342 if(h==360) h = 0; 343 if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3} 344 else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3} 345 else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3} 346 else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3} 347 else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3} 348 else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3} 349 else {rgb.r=0; rgb.g=0; rgb.b=0} 350 } 351 return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)}; 352 }, 353 RGBToHex = function (rgb) { 354 var hex = [ 355 rgb.r.toString(16), 356 rgb.g.toString(16), 357 rgb.b.toString(16) 358 ]; 359 $.each(hex, function (nr, val) { 360 if (val.length == 1) {
361 hex[nr] = '0' + val; 362 } 363 }); 364 return hex.join(''); 365 }, 366 HSBToHex = function (hsb) { 367 return RGBToHex(HSBToRGB(hsb)); 368 }, 369 restoreOriginal = function () { 370 var cal = $(this).parent(); 371 var col = cal.data('colorpicker').origColor; 372 cal.data('colorpicker').color = col; 373 fillRGBFields(col, cal.get(0)); 374 fillHexFields(col, cal.get(0)); 375 fillHSBFields(col, cal.get(0)); 376 setSelector(col, cal.get(0)); 377 setHue(col, cal.get(0)); 378 setNewColor(col, cal.get(0)); 379 }; 380 return { 381 init: function (opt) { 382 opt = $.extend({}, defaults, opt||{}); 383 if (typeof opt.color == 'string') { 384 opt.color = HexToHSB(opt.color); 385 } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) { 386 opt.color = RGBToHSB(opt.color); 387 } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) { 388 opt.color = fixHSB(opt.color); 389 } else { 390 return this; 391 } 392 return this.each(function () { 393 if (!$(this).data('colorpickerId')) { 394 var options = $.extend({}, opt); 395 options.origColor = opt.color; 396 var id = 'collorpicker_' + parseInt(Math.random() * 1000); 397 $(this).data('colorpickerId', id); 398 var cal = $(tpl).attr('id', id); 399 if (options.flat) { 400 cal.appendTo(this).show(); 401 } else { 402 cal.appendTo(document.body); 403 } 404 options.fields = cal 405 .find('input') 406 .bind('keyup', keyDown) 407 .bind('change', change) 408 .bind('blur', blur) 409 .bind('focus', focus); 410 cal 411 .find('span').bind('mousedown', downIncrement).end() 412 .find('>div.colorpicker_current_color').bind('click', restoreOriginal); 413 options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector); 414 options.selectorIndic = options.selector.find('div div'); 415 options.el = this; 416 options.hue = cal.find('div.colorpicker_hue div'); 417 cal.find('div.colorpicker_hue').bind('mousedown', downHue); 418 options.newColor = cal.find('div.colorpicker_new_color'); 419 options.currentColor = cal.find('div.colorpicker_current_color'); 420 cal.data('colorpicker', options); 421 cal.find('div.colorpicker_submit') 422 .bind('mouseenter', enterSubmit) 423 .bind('mouseleave', leaveSubmit) 424 .bind('click', clickSubmit); 425 fillRGBFields(options.color, cal.get(0)); 426 fillHSBFields(options.color, cal.get(0)); 427 fillHexFields(options.color, cal.get(0)); 428 setHue(options.color, cal.get(0)); 429 setSelector(options.color, cal.get(0)); 430 setCurrentColor(options.color, cal.get(0)); 431 setNewColor(options.color, cal.get(0)); 432 if (options.flat) { 433 cal.css({ 434 position: 'relative', 435 display: 'block' 436 }); 437 } else { 438 $(this).bind(options.eventName, show); 439 } 440 } 441 }); 442 }, 443 showPicker: function() { 444 return this.each( function () { 445 if ($(this).data('colorpickerId')) { 446 show.apply(this); 447 } 448 }); 449 }, 450 hidePicker: function() { 451 return this.each( function () { 452 if ($(this).data('colorpickerId')) { 453 $('#' + $(this).data('colorpickerId')).hide(); 454 } 455 }); 456 }, 457 setColor: function(col) { 458 if (typeof col == 'string') { 459 col = HexToHSB(col); 460 } else if (col.r != undefined && col.g != undefined && col.b != undefined) { 461 col = RGBToHSB(col); 462 } else if (col.h != undefined && col.s != undefined && col.b != undefined) { 463 col = fixHSB(col); 464 } else { 465 return this; 466 } 467 return this.each(function(){ 468 if ($(this).data('colorpickerId')) { 469 var cal = $('#' + $(this).data('colorpickerId')); 470 cal.data('colorpicker').color = col; 471 cal.data('colorpicker').origColor = col; 472 fillRGBFields(col, cal.get(0)); 473 fillHSBFields(col, cal.get(0)); 474 fillHexFields(col, cal.get(0)); 475 setHue(col, cal.get(0)); 476 setSelector(col, cal.get(0)); 477 setCurrentColor(col, cal.get(0));
478 setNewColor(col, cal.get(0)); 479 } 480 }); 481 } 482 }; 483 }(); 484 $.fn.extend({ 485 ColorPicker: ColorPicker.init, 486 ColorPickerHide: ColorPicker.hidePicker, 487 ColorPickerShow: ColorPicker.showPicker, 488 ColorPickerSetColor: ColorPicker.setColor 489 }); 490})(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.