PageSourceSearch

https://ameliab.com/_jsapps/inspector/jquery.mini.colors.js

js ameliab.com collected 2026-10-05 05:51:25 UTC 17,208 bytes, 674 lines download raw bytes

1/*
2 * jQuery miniColors: A small color selector
3 * 	http://www.abeautifulsite.net/blog/2011/02/jquery-minicolors-a-color-selector-for-input-controls/
4 * 	http://labs.abeautifulsite.net/jquery-miniColors/
5 *
6 * Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/)
7 *
8 * Dual licensed under the MIT or GPL Version 2 licenses
9 *
10 *
11 * Usage:
12 *
13 *	1. Link to jQuery: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
14 *
15 *  2. Link to miniColors: <script type="text/javascript" src="jquery.miniColors.js"></script>
16 *
17 *  3. Include miniColors stylesheet: <link type="text/css" rel="stylesheet" href="jquery.miniColors.css" />
18 *
19 *	4. Apply $([selector]).miniColors() to one or more INPUT elements
20 *
21 *
22 * Options:
23 *
24 *	disabled		[true|false]
25 *	readonly		[true|false]
26 *
27 *
28 *  Specify options on creation:
29 *
30 *		$([selector]).miniColors({
31 *
32 *			optionName: value,
33 *			optionName: value,
34 *			...
35 *
36 *		});
37 *
38 *
39 * Methods:
40 *
41 *	Call a method using: $([selector]).miniColors('methodName', [value]);
42 *
43 *	disabled		[true|false]
44 *	readonly		[true|false]
45 *	value			[hex value]
46 *	destroy
47 *
48 *
49 * Events:
50 *
51 *	Attach events on creation:
52 *
53 *		$([selector]).miniColors({
54 *
55 *			change: function(hex, rgb) { ... }
56 *
57 *		});
58 *
59 *	change(hex, rgb)	called when the color value changes; 'this' will refer to the original input element;
60 *                      hex is the string hex value of the selected color; rgb is an object with the RGB values
61 *
62 *
63 * Change log:
64 *
65 *	- v0.1 (2011-02-24) - Initial release
66 *
67 *
68 * Attribution:
69 *
70 *	- The color picker icon is based on an icon from the amazing Fugue icon set: 
71 *    http://p.yusukekamiyamane.com/
72 *
73 *	- The gradient image, the hue image, and the math functions are courtesy of 
74 *    the eyecon.co jQuery color picker: http://www.eyecon.ro/colorpicker/
75 *
76 *
77*/
78if(jQuery) (function($) {
79	
80	$.extend($.fn, {
81		
82		miniColors: function(o, data) {
83			
84			var create = function(input, o, data) {
85				//
86				// Creates a new instance of the miniColors selector
87				//
88				
89				// Determine initial color (defaults to white)
90				var color = cleanHex(input.val());
91				if( !color ) color = 'FFFFFF';
92				var hsb = hex2hsb(color);
93				
94				// Create trigger
95				var trigger = $('<a class="miniColors-trigger" style="background-color: #' + color + '" href="#"></a>');
96				trigger.insertAfter(input);
97				
98				// Add necessary attributes
99				input.addClass('miniColors').attr('maxlength', 7).attr('autocomplete', 'off');
100				
101				// Set input data
102				input.data('trigger', trigger);
103				input.data('hsb', hsb);
104				if( o.change ) input.data('change', o.change);
105				
106				// Handle options
107				if( o.readonly ) input.attr('readonly', true);
108				if( o.disabled ) disable(input);
109				
110				// Show selector when trigger is clicked
111				trigger.bind('click.miniColors', function(event) {
112					show(input);
113					event.preventDefault();
114				});
115				
116				// Show selector when input receives focus
117				input.bind('focus.miniColors', function(event) {
118					show(input);
119				});
120				
121				// Hide on blur
122				input.bind('blur.miniColors', function(event) {
123					var hex = cleanHex(input.val());
124					input.val( hex ? '#' + hex : '' );
125				});
126				
127				// Hide when tabbing out of the input
128				input.bind('keydown.miniColors', function(event) {
129					if( event.keyCode === 9 ) hide(input);
130				});
131				
132				// Update when color is typed in
133				input.bind('keyup.miniColors', function(event) {
134					// Remove non-hex characters
135					var filteredHex = input.val().replace(/[^A-F0-9#]/ig, '');
136					input.val(filteredHex);
137					if( !setColorFromInput(input) ) {
138						// Reset trigger color when color is invalid
139						input.data('trigger').css('backgroundColor', '#FFF');
140					}
141				});
142				
143				// Handle pasting
144				input.bind('paste.miniColors', function(event) {
145					// Short pause to wait for paste to complete
146					setTimeout( function() {
147						input.trigger('keyup');
148					}, 5);
149				});
150				
151			};
152			
153			
154			var destroy = function(input) {
155				
156				//
157				// Destroys an active instance of the miniColors selector
158				//
159				
160				hide();
161				
162				input = $(input);
163				input.data('trigger').remove();
164				input.removeAttr('autocomplete');
165				input.removeData('trigger');
166				input.removeData('selector');
167				input.removeData('hsb');
168				input.removeData('huePicker');
169				input.removeData('colorPicker');
170				input.removeData('colorPosition');
171				input.removeData('mousebutton');
172				input.removeData('moving');
173				input.unbind('click.miniColors');
174				input.unbind('focus.miniColors');
175				input.unbind('blur.miniColors');
176				input.unbind('keyup.miniColors');
177				input.unbind('keydown.miniColors');
178				input.unbind('paste.miniColors');
179				$(document).unbind('mousedown.miniColors');
180				$(document).unbind('mousemove.miniColors');
181				
182				
183			};
184			
185			
186			var enable = function(input) {
187				
188				//
189				// Disables the input control and the selector
190				//
191				
192				input.attr('disabled', false);
193				input.data('trigger').css('opacity', 1);
194				
195			};			
196			
197			var disable = function(input) {
198				//
199				// Disables the input control and the selector
200				//
201				
202				hide(input);
203				input.attr('disabled', true);
204				input.data('trigger').css('opacity', .5);
205				
206			};
207			
208			
209			var show = function(input) {
210				//
211				// Shows the miniColors selector
212				//
213				
214				if( input.attr('disabled') ) return false;
215				
216				// Hide all other instances 
217				hide();			
218				
219				// Generate the selector
220				/*
221				var selector = $('<div class="miniColors-selector"></div>');
222				selector.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"></div></div>');
223				selector.append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>');
224				selector.css({
225					top: input.is(':visible') ? input.offset().top + input.outerHeight() : input.data('trigger').offset().top + input.data('trigger').outerHeight(),
226					left: input.is(':visible') ? input.offset().left : input.data('trigger').offset().left,
227					display: 'none'
228				}).addClass( input.attr('class') );
229				*/
230				
231				var selector = $(".miniColors-selector");
232				selector.addClass( input.attr('class') );
233				
234				// Set the starting color
235				var hsb = input.data('hsb');
236				var hex = hsb2hex({ h: hsb.h, s: 100, b: 100 });
237				
238				// Set background for colors
239				selector.find('.miniColors-colors').css('backgroundColor', '#' + hex);
240				
241				// Set colorPicker position
242				//var colorPosition = input.data('colorPosition');
243				//if( !colorPosition ) 
244				colorPosition = getColorPositionFromHSB(hsb);
245				selector.find('.miniColors-colorPicker').css('top', colorPosition.y + 'px').css('left', colorPosition.x + 'px');
246				
247				// Set huePicker position
248				var huePosition = input.data('huePosition');
249				if( !huePosition ) huePosition = getHuePositionFromHSB(hsb);
250				selector.find('.miniColors-huePicker').css('top', huePosition.y + 'px');
251				
252				// Fire the show event and pass the hex value
253				$(document).trigger("colorPickerShow", [hex]);
254				
255				
256				// Set input data
257				input.data('selector', selector);
258				input.data('huePicker', selector.find('.miniColors-huePicker'));
259				input.data('colorPicker', selector.find('.miniColors-colorPicker'));
260				input.data('mousebutton', 0);
261				
262				//$('BODY').append(selector);
263				selector.show();
264				
265				// Prevent text selection in IE
266				selector.bind('selectstart', function() { return false; });
267				
268				$(document).bind('mousedown.miniColors', function(event) {
269					input.data('mousebutton', 1);
270					
271					if( $(event.target).parents().andSelf().hasClass('miniColors-colors') ) {
272						event.preventDefault();
273						input.data('moving', 'colors');
274						moveColor(input, event);
275					}
276					
277					if( $(event.target).parents().andSelf().hasClass('miniColors-hues') ) {
278						event.preventDefault();
279						input.data('moving', 'hues');
280						moveHue(input, event);
281					}
282					
283					if( $(event.target).parents().andSelf().hasClass('miniColors-selector') ) {
284						event.preventDefault();
285						return;
286					}
287					
288					if( $(event.target).parents().andSelf().hasClass('miniColors') ) return;
289					
290					hide(input);
291				});
292				
293				$(document).bind('mouseup.miniColors', function(event) {
294					input.data('mousebutton', 0);
295					input.removeData('moving');
296				});
297				
298				$(document).bind('mousemove.miniColors', function(event) {
299					if( input.data('mousebutton') === 1 ) {
300						if( input.data('moving') === 'colors' ) moveColor(input, event);
301						if( input.data('moving') === 'hues' ) moveHue(input, event);
302					}
303				});
304				
305			};
306			
307			
308			var hide = function(input) {
309				// Fire the destroy event
310				$(document).trigger("colorPickerHide");
311				
312				//
313				// Hides one or more miniColors selectors
314				//
315				
316				// Hide all other instances if input isn't specified
317				if( !input ) input = '.miniColors';
318				
319				/* This removes the element from stage
320				$(input).each( function() {
321					var selector = $(this).data('selector');
322					$(this).removeData('selector');
323					$(selector).fadeOut(0, function() {
324						$(this).remove();
325					});
326					
327				});
328				*/
329				
330				// Just hide the element instead of deleting it
331				$(".miniColors-selector").hide();
332								
333				$(document).unbind('mousedown.miniColors');
334				$(document).unbind('mousemove.miniColors');
335				
336			};
337			
338			
339			var moveColor = function(input, event) {
340				
341				var colorPicker = input.data('colorPicker');
342				
343				colorPicker.hide();
344				
345				var position = {
346					x: event.clientX - input.data('selector').find('.miniColors-colors').offset().left + $(document).scrollLeft() - 5,
347					y: event.clientY - input.data('selector').find('.miniColors-colors').offset().top + $(document).scrollTop() - 5
348				};
349				
350				if( position.x <= -5 ) position.x = -5;
351				if( position.x >= 144 ) position.x = 144;
352				if( position.y <= -5 ) position.y = -5;
353				if( position.y >= 144 ) position.y = 144;
354				input.data('colorPosition', position);
355				colorPicker.css('left', position.x).css('top', position.y).show();
356				
357				// Calculate saturation
358				var s = Math.round((position.x + 5) * .67);
359				if( s < 0 ) s = 0;
360				if( s > 100 ) s = 100;
361				
362				// Calculate brightness
363				var b = 100 - Math.round((position.y + 5) * .67);
364				if( b < 0 ) b = 0;
365				if( b > 100 ) b = 100;
366				
367				// Update HSB values
368				var hsb = input.data('hsb');
369				hsb.s = s;
370				hsb.b = b;
371				
372				// Set color
373				setColor(input, hsb, true);
374				
375			};
376			
377			
378			var moveHue = function(input, event) {
379				
380				var huePicker = input.data('huePicker');
381				
382				huePicker.hide();
383				
384				var position = {
385					y: event.clientY - input.data('selector').find('.miniColors-colors').offset().top + $(document).scrollTop() - 1
386				};
387				
388				if( position.y <= -1 ) position.y = -1;
389				if( position.y >= 149 ) position.y = 149;
390				input.data('huePosition', position);
391				huePicker.css('top', position.y).show();
392				
393				// Calculate hue
394				var h = Math.round((150 - position.y - 1) * 2.4);
395				if( h < 0 ) h = 0;
396				if( h > 360 ) h = 360;
397				
398				// Update HSB values
399				var hsb = input.data('hsb');
400				hsb.h = h;
401				
402				// Set color
403				setColor(input, hsb, true);
404				
405			};
406			
407			
408			var setColor = function(input, hsb, updateInputValue) {
409				input.data('hsb', hsb);
410				var hex = hsb2hex(hsb);	
411				if( updateInputValue ) input.val('#' + hex);
412				input.data('trigger').css('backgroundColor', '#' + hex);
413				if( input.data('selector') ) input.data('selector').find('.miniColors-colors').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
414				
415				if( input.data('change') ) {
416					input.data('change').call(input, '#' + hex, hsb2rgb(hsb));
417				}
418				
419			};
420			
421			
422			var setColorFromInput = function(input) {
423				
424				// Don't update if the hex color is invalid
425				var hex = cleanHex(input.val());
426				if( !hex ) return false;
427				
428				// Get HSB equivalent
429				var hsb = hex2hsb(hex);
430				
431				// If color is the same, no change required
432				var currentHSB = input.data('hsb');
433				if( hsb.h === currentHSB.h && hsb.s === currentHSB.s && hsb.b === currentHSB.b ) return true;
434				
435				// Set colorPicker position
436				var colorPosition = getColorPositionFromHSB(hsb);
437				var colorPicker = $(input.data('colorPicker'));
438				colorPicker.css('top', colorPosition.y + 'px').css('left', colorPosition.x + 'px');
439				
440				// Set huePosition position
441				var huePosition = getHuePositionFromHSB(hsb);
442				var huePicker = $(input.data('huePicker'));
443				huePicker.css('top', huePosition.y + 'px');
444				
445				setColor(input, hsb, false);
446				
447				return true;
448				
449			};
450			
451			
452			var getColorPositionFromHSB = function(hsb) {
453				
454				var x = Math.ceil(hsb.s / .67);
455				if( x < 0 ) x = 0;
456				if( x > 150 ) x = 150;
457				
458				var y = 150 - Math.ceil(hsb.b / .67);
459				if( y < 0 ) y = 0;
460				if( y > 150 ) y = 150;
461				
462				return { x: x - 5, y: y - 5 };
463				
464			}
465			
466			
467			var getHuePositionFromHSB = function(hsb) {
468				
469				var y = 150 - (hsb.h / 2.4);
470				if( y < 0 ) h = 0;
471				if( y > 150 ) h = 150;				
472				
473				return { y: y - 1 };
474				
475			}
476			
477			
478			var cleanHex = function(hex) {
479				
480				//
481				// Turns a dirty hex string into clean, 6-character hex color
482				//
483				
484				hex = hex.replace(/[^A-Fa-f0-9]/, '');
485				
486				if( hex.length == 3 ) {
487					hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
488				}
489				
490				return hex.length === 6 ? hex : null;
491				
492			};			
493			
494			
495			var hsb2rgb = function(hsb) {
496				var rgb = {};
497				var h = Math.round(hsb.h);
498				var s = Math.round(hsb.s*255/100);
499				var v = Math.round(hsb.b*255/100);
500				if(s == 0) {
501					rgb.r = rgb.g = rgb.b = v;
502				} else {
503					var t1 = v;
504					var t2 = (255 - s) * v / 255;
505					var t3 = (t1 - t2) * (h % 60) / 60;
506					if( h == 360 ) h = 0;
507					if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
508					else if( h<120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
509					else if( h<180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
510					else if( h<240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
511					else if( h<300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
512					else if( h<360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
513					else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
514				}
515				return {
516					r: Math.round(rgb.r),
517					g: Math.round(rgb.g),
518					b: Math.round(rgb.b)
519				};
520			};
521			
522			
523			var rgb2hex = function(rgb) {
524				
525				var hex = [
526					rgb.r.toString(16),
527					rgb.g.toString(16),
528					rgb.b.toString(16)
529				];
530				$.each(hex, function(nr, val) {
531					if (val.length == 1) hex[nr] = '0' + val;
532				});
533				
534				return hex.join('');
535			};
536			
537			
538			var hex2rgb = function(hex) {
539				var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
540				
541				return {
542					r: hex >> 16,
543					g: (hex & 0x00FF00) >> 8,
544					b: (hex & 0x0000FF)
545				};
546			};
547			
548			
549			var rgb2hsb = function(rgb) {
550				var hsb = { h: 0, s: 0, b: 0 };
551				var min = Math.min(rgb.r, rgb.g, rgb.b);
552				var max = Math.max(rgb.r, rgb.g, rgb.b);
553				var delta = max - min;
554				hsb.b = max;
555				hsb.s = max != 0 ? 255 * delta / max : 0;
556				if( hsb.s != 0 ) {
557					if( rgb.r == max ) {
558						hsb.h = (rgb.g - rgb.b) / delta;
559					} else if( rgb.g == max ) {
560						hsb.h = 2 + (rgb.b - rgb.r) / delta;
561					} else {
562						hsb.h = 4 + (rgb.r - rgb.g) / delta;
563					}
564				} else {
565					hsb.h = -1;
566				}
567				hsb.h *= 60;
568				if( hsb.h < 0 ) {
569					hsb.h += 360;
570				}
571				hsb.s *= 100/255;
572				hsb.b *= 100/255;
573				return hsb;
574			};			
575			
576			
577			var hex2hsb = function(hex) {
578				var hsb = rgb2hsb(hex2rgb(hex));
579				// Zero out hue marker for black, white, and grays (saturation === 0)
580				if( hsb.s === 0 ) hsb.h = 360;
581				return hsb;
582			};
583			
584			
585			var hsb2hex = function(hsb) {
586				return rgb2hex(hsb2rgb(hsb));
587			};
588
589			
590			//
591			// Handle calls to $([selector]).miniColors()
592			//
593			switch(o) {
594
595
596				case 'readonly':
597					
598					$(this).each( function() {
599						$(this).attr('readonly', data);
600					});
601					
602					return $(this);
603					
604					break;
605				
606				case 'disabled':
607					
608					$(this).each( function() {
609						if( data ) {
610							disable($(this));
611						} else {
612							enable($(this));
613						}
614					});
615										
616					return $(this);
617			
618				case 'value':
619					
620					$(this).each( function() {
621						$(this).val(data).trigger('keyup');
622					});
623					
624					return $(this);
625					
626					break;
627					
628				case 'destroy':
629					
630					$(this).each( function() {
631						destroy($(this));
632					});
633										
634					return $(this);
635				
636				case 'hide':
637					
638					$(this).each( function() {
639						hide($(this));
640					});
641										
642					return $(this);
643				
644				default:
645					
646					if( !o ) o = {};
647					
648					$(this).each( function() {
649						
650						// Force an input element
651						//if( $(this)[0].tagName.toLowerCase() !== 'input' ) return;
652						
653						// If a trigger is present, the control was already created
654						if( $(this).data('trigger') ) return;
655						
656						// Create the control
657						create($(this), o, data);
658						
659					});
660										
661					return $(this);
662					
663			}
664			
665			
666		}
667
668			
669	});
670	
671})(jQuery);
672
673
674

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.