| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128 |
- //
- // jQuery MiniColors: A tiny color picker built on jQuery
- //
- // Developed by Cory LaViska for A Beautiful Site, LLC
- //
- // Licensed under the MIT license: http://opensource.org/licenses/MIT
- //
- (function (factory) {
- if(typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else if(typeof exports === 'object') {
- // Node/CommonJS
- module.exports = factory(require('jquery'));
- } else {
- // Browser globals
- factory(jQuery);
- }
- }(function ($) {
- 'use strict';
- // Defaults
- $.minicolors = {
- defaults: {
- animationSpeed: 50,
- animationEasing: 'swing',
- change: null,
- changeDelay: 0,
- control: 'hue',
- defaultValue: '',
- format: 'hex',
- hide: null,
- hideSpeed: 100,
- inline: false,
- keywords: '',
- letterCase: 'lowercase',
- opacity: false,
- position: 'bottom',
- show: null,
- showSpeed: 100,
- theme: 'default',
- swatches: []
- }
- };
- // Public methods
- $.extend($.fn, {
- minicolors: function(method, data) {
- switch(method) {
- // Destroy the control
- case 'destroy':
- $(this).each(function() {
- destroy($(this));
- });
- return $(this);
- // Hide the color picker
- case 'hide':
- hide();
- return $(this);
- // Get/set opacity
- case 'opacity':
- // Getter
- if(data === undefined) {
- // Getter
- return $(this).attr('data-opacity');
- } else {
- // Setter
- $(this).each(function() {
- updateFromInput($(this).attr('data-opacity', data));
- });
- }
- return $(this);
- // Get an RGB(A) object based on the current color/opacity
- case 'rgbObject':
- return rgbObject($(this), method === 'rgbaObject');
- // Get an RGB(A) string based on the current color/opacity
- case 'rgbString':
- case 'rgbaString':
- return rgbString($(this), method === 'rgbaString');
- // Get/set settings on the fly
- case 'settings':
- if(data === undefined) {
- return $(this).data('minicolors-settings');
- } else {
- // Setter
- $(this).each(function() {
- var settings = $(this).data('minicolors-settings') || {};
- destroy($(this));
- $(this).minicolors($.extend(true, settings, data));
- });
- }
- return $(this);
- // Show the color picker
- case 'show':
- show($(this).eq(0));
- return $(this);
- // Get/set the hex color value
- case 'value':
- if(data === undefined) {
- // Getter
- return $(this).val();
- } else {
- // Setter
- $(this).each(function() {
- if(typeof(data) === 'object' && data !== null) {
- if(data.opacity !== undefined) {
- $(this).attr('data-opacity', keepWithin(data.opacity, 0, 1));
- }
- if(data.color) {
- $(this).val(data.color);
- }
- } else {
- $(this).val(data);
- }
- updateFromInput($(this));
- });
- }
- return $(this);
- // Initializes the control
- default:
- if(method !== 'create') data = method;
- $(this).each(function() {
- init($(this), data);
- });
- return $(this);
- }
- }
- });
- // Initialize input elements
- function init(input, settings) {
- var minicolors = $('<div class="minicolors" />');
- var defaults = $.minicolors.defaults;
- var name;
- var size;
- var swatches;
- var swatch;
- var swatchString;
- var panel;
- var i;
- // Do nothing if already initialized
- if(input.data('minicolors-initialized')) return;
- // Handle settings
- settings = $.extend(true, {}, defaults, settings);
- // The wrapper
- minicolors
- .addClass('minicolors-theme-' + settings.theme)
- .toggleClass('minicolors-with-opacity', settings.opacity);
- // Custom positioning
- if(settings.position !== undefined) {
- $.each(settings.position.split(' '), function() {
- minicolors.addClass('minicolors-position-' + this);
- });
- }
- // Input size
- if(settings.format === 'rgb') {
- size = settings.opacity ? '25' : '20';
- } else {
- size = settings.keywords ? '11' : '7';
- }
- // The input
- input
- .addClass('minicolors-input')
- .data('minicolors-initialized', false)
- .data('minicolors-settings', settings)
- .prop('size', size)
- .wrap(minicolors)
- .after(
- '<div class="minicolors-panel minicolors-slider-' + settings.control + '">' +
- '<div class="minicolors-slider minicolors-sprite">' +
- '<div class="minicolors-picker"></div>' +
- '</div>' +
- '<div class="minicolors-opacity-slider minicolors-sprite">' +
- '<div class="minicolors-picker"></div>' +
- '</div>' +
- '<div class="minicolors-grid minicolors-sprite">' +
- '<div class="minicolors-grid-inner"></div>' +
- '<div class="minicolors-picker"><div></div></div>' +
- '</div>' +
- '</div>'
- );
- // The swatch
- if(!settings.inline) {
- input.after('<span class="minicolors-swatch minicolors-sprite minicolors-input-swatch"><span class="minicolors-swatch-color"></span></span>');
- input.next('.minicolors-input-swatch').on('click', function(event) {
- event.preventDefault();
- input.trigger('focus');
- });
- }
- // Prevent text selection in IE
- panel = input.parent().find('.minicolors-panel');
- panel.on('selectstart', function() { return false; }).end();
- // Swatches
- if(settings.swatches && settings.swatches.length !== 0) {
- panel.addClass('minicolors-with-swatches');
- swatches = $('<ul class="minicolors-swatches"></ul>')
- .appendTo(panel);
- for(i = 0; i < settings.swatches.length; ++i) {
- // allow for custom objects as swatches
- if(typeof settings.swatches[i] === 'object') {
- name = settings.swatches[i].name;
- swatch = settings.swatches[i].color;
- } else {
- name = '';
- swatch = settings.swatches[i];
- }
- swatchString = swatch;
- swatch = isRgb(swatch) ? parseRgb(swatch, true) : hex2rgb(parseHex(swatch, true));
- $('<li class="minicolors-swatch minicolors-sprite"><span class="minicolors-swatch-color"></span></li>')
- .attr("title", name)
- .appendTo(swatches)
- .data('swatch-color', swatchString)
- .find('.minicolors-swatch-color')
- .css({
- backgroundColor: ((swatchString !== 'transparent') ? rgb2hex(swatch) : 'transparent'),
- opacity: String(swatch.a)
- });
- settings.swatches[i] = swatch;
- }
- }
- // Inline controls
- if(settings.inline) input.parent().addClass('minicolors-inline');
- updateFromInput(input, false);
- input.data('minicolors-initialized', true);
- }
- // Returns the input back to its original state
- function destroy(input) {
- var minicolors = input.parent();
- // Revert the input element
- input
- .removeData('minicolors-initialized')
- .removeData('minicolors-settings')
- .removeProp('size')
- .removeClass('minicolors-input');
- // Remove the wrap and destroy whatever remains
- minicolors.before(input).remove();
- }
- // Shows the specified dropdown panel
- function show(input) {
- var minicolors = input.parent();
- var panel = minicolors.find('.minicolors-panel');
- var settings = input.data('minicolors-settings');
- // Do nothing if uninitialized, disabled, inline, or already open
- if(
- !input.data('minicolors-initialized') ||
- input.prop('disabled') ||
- minicolors.hasClass('minicolors-inline') ||
- minicolors.hasClass('minicolors-focus')
- ) return;
- hide();
- minicolors.addClass('minicolors-focus');
- if (panel.animate) {
- panel
- .stop(true, true)
- .fadeIn(settings.showSpeed, function () {
- if (settings.show) settings.show.call(input.get(0));
- });
- } else {
- panel.show();
- if (settings.show) settings.show.call(input.get(0));
- }
- }
- // Hides all dropdown panels
- function hide() {
- $('.minicolors-focus').each(function() {
- var minicolors = $(this);
- var input = minicolors.find('.minicolors-input');
- var panel = minicolors.find('.minicolors-panel');
- var settings = input.data('minicolors-settings');
- if (panel.animate) {
- panel.fadeOut(settings.hideSpeed, function () {
- if (settings.hide) settings.hide.call(input.get(0));
- minicolors.removeClass('minicolors-focus');
- });
- } else {
- panel.hide();
- if (settings.hide) settings.hide.call(input.get(0));
- minicolors.removeClass('minicolors-focus');
- }
- });
- }
- // Moves the selected picker
- function move(target, event, animate) {
- var input = target.parents('.minicolors').find('.minicolors-input');
- var settings = input.data('minicolors-settings');
- var picker = target.find('[class$=-picker]');
- var offsetX = target.offset().left;
- var offsetY = target.offset().top;
- var x = Math.round(event.pageX - offsetX);
- var y = Math.round(event.pageY - offsetY);
- var duration = animate ? settings.animationSpeed : 0;
- var wx, wy, r, phi, styles;
- // Touch support
- if(event.originalEvent.changedTouches) {
- x = event.originalEvent.changedTouches[0].pageX - offsetX;
- y = event.originalEvent.changedTouches[0].pageY - offsetY;
- }
- // Constrain picker to its container
- if(x < 0) x = 0;
- if(y < 0) y = 0;
- if(x > target.width()) x = target.width();
- if(y > target.height()) y = target.height();
- // Constrain color wheel values to the wheel
- if(target.parent().is('.minicolors-slider-wheel') && picker.parent().is('.minicolors-grid')) {
- wx = 75 - x;
- wy = 75 - y;
- r = Math.sqrt(wx * wx + wy * wy);
- phi = Math.atan2(wy, wx);
- if(phi < 0) phi += Math.PI * 2;
- if(r > 75) {
- r = 75;
- x = 75 - (75 * Math.cos(phi));
- y = 75 - (75 * Math.sin(phi));
- }
- x = Math.round(x);
- y = Math.round(y);
- }
- // Move the picker
- styles = {
- top: y + 'px'
- };
- if(target.is('.minicolors-grid')) {
- styles.left = x + 'px';
- }
- if (picker.animate) {
- picker
- .stop(true)
- .animate(styles, duration, settings.animationEasing, function() {
- updateFromControl(input, target);
- });
- } else {
- picker
- .css(styles);
- updateFromControl(input, target);
- }
- }
- // Sets the input based on the color picker values
- function updateFromControl(input, target) {
- function getCoords(picker, container) {
- var left, top;
- if(!picker.length || !container) return null;
- left = picker.offset().left;
- top = picker.offset().top;
- return {
- x: left - container.offset().left + (picker.outerWidth() / 2),
- y: top - container.offset().top + (picker.outerHeight() / 2)
- };
- }
- var hue, saturation, brightness, x, y, r, phi;
- var hex = input.val();
- var opacity = input.attr('data-opacity');
- // Helpful references
- var minicolors = input.parent();
- var settings = input.data('minicolors-settings');
- var swatch = minicolors.find('.minicolors-input-swatch');
- // Panel objects
- var grid = minicolors.find('.minicolors-grid');
- var slider = minicolors.find('.minicolors-slider');
- var opacitySlider = minicolors.find('.minicolors-opacity-slider');
- // Picker objects
- var gridPicker = grid.find('[class$=-picker]');
- var sliderPicker = slider.find('[class$=-picker]');
- var opacityPicker = opacitySlider.find('[class$=-picker]');
- // Picker positions
- var gridPos = getCoords(gridPicker, grid);
- var sliderPos = getCoords(sliderPicker, slider);
- var opacityPos = getCoords(opacityPicker, opacitySlider);
- // Handle colors
- if(target.is('.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider')) {
- // Determine HSB values
- switch(settings.control) {
- case 'wheel':
- // Calculate hue, saturation, and brightness
- x = (grid.width() / 2) - gridPos.x;
- y = (grid.height() / 2) - gridPos.y;
- r = Math.sqrt(x * x + y * y);
- phi = Math.atan2(y, x);
- if(phi < 0) phi += Math.PI * 2;
- if(r > 75) {
- r = 75;
- gridPos.x = 69 - (75 * Math.cos(phi));
- gridPos.y = 69 - (75 * Math.sin(phi));
- }
- saturation = keepWithin(r / 0.75, 0, 100);
- hue = keepWithin(phi * 180 / Math.PI, 0, 360);
- brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
- hex = hsb2hex({
- h: hue,
- s: saturation,
- b: brightness
- });
- // Update UI
- slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 }));
- break;
- case 'saturation':
- // Calculate hue, saturation, and brightness
- hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
- saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
- brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
- hex = hsb2hex({
- h: hue,
- s: saturation,
- b: brightness
- });
- // Update UI
- slider.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: brightness }));
- minicolors.find('.minicolors-grid-inner').css('opacity', saturation / 100);
- break;
- case 'brightness':
- // Calculate hue, saturation, and brightness
- hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
- saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
- brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
- hex = hsb2hex({
- h: hue,
- s: saturation,
- b: brightness
- });
- // Update UI
- slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 }));
- minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (brightness / 100));
- break;
- default:
- // Calculate hue, saturation, and brightness
- hue = keepWithin(360 - parseInt(sliderPos.y * (360 / slider.height()), 10), 0, 360);
- saturation = keepWithin(Math.floor(gridPos.x * (100 / grid.width())), 0, 100);
- brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
- hex = hsb2hex({
- h: hue,
- s: saturation,
- b: brightness
- });
- // Update UI
- grid.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: 100 }));
- break;
- }
- // Handle opacity
- if(settings.opacity) {
- opacity = parseFloat(1 - (opacityPos.y / opacitySlider.height())).toFixed(2);
- } else {
- opacity = 1;
- }
- updateInput(input, hex, opacity);
- }
- else {
- // Set swatch color
- swatch.find('span').css({
- backgroundColor: hex,
- opacity: String(opacity)
- });
- // Handle change event
- doChange(input, hex, opacity);
- }
- }
- // Sets the value of the input and does the appropriate conversions
- // to respect settings, also updates the swatch
- function updateInput(input, value, opacity) {
- var rgb;
- // Helpful references
- var minicolors = input.parent();
- var settings = input.data('minicolors-settings');
- var swatch = minicolors.find('.minicolors-input-swatch');
- if(settings.opacity) input.attr('data-opacity', opacity);
- // Set color string
- if(settings.format === 'rgb') {
- // Returns RGB(A) string
- // Checks for input format and does the conversion
- if(isRgb(value)) {
- rgb = parseRgb(value, true);
- }
- else {
- rgb = hex2rgb(parseHex(value, true));
- }
- opacity = input.attr('data-opacity') === '' ? 1 : keepWithin(parseFloat(input.attr('data-opacity')).toFixed(2), 0, 1);
- if(isNaN(opacity) || !settings.opacity) opacity = 1;
- if(input.minicolors('rgbObject').a <= 1 && rgb && settings.opacity) {
- // Set RGBA string if alpha
- value = 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat(opacity) + ')';
- } else {
- // Set RGB string (alpha = 1)
- value = 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')';
- }
- } else {
- // Returns hex color
- // Checks for input format and does the conversion
- if(isRgb(value)) {
- value = rgbString2hex(value);
- }
- value = convertCase(value, settings.letterCase);
- }
- // Update value from picker
- input.val(value);
- // Set swatch color
- swatch.find('span').css({
- backgroundColor: value,
- opacity: String(opacity)
- });
- // Handle change event
- doChange(input, value, opacity);
- }
- // Sets the color picker values from the input
- function updateFromInput(input, preserveInputValue) {
- var hex, hsb, opacity, keywords, alpha, value, x, y, r, phi;
- // Helpful references
- var minicolors = input.parent();
- var settings = input.data('minicolors-settings');
- var swatch = minicolors.find('.minicolors-input-swatch');
- // Panel objects
- var grid = minicolors.find('.minicolors-grid');
- var slider = minicolors.find('.minicolors-slider');
- var opacitySlider = minicolors.find('.minicolors-opacity-slider');
- // Picker objects
- var gridPicker = grid.find('[class$=-picker]');
- var sliderPicker = slider.find('[class$=-picker]');
- var opacityPicker = opacitySlider.find('[class$=-picker]');
- // Determine hex/HSB values
- if(isRgb(input.val())) {
- // If input value is a rgb(a) string, convert it to hex color and update opacity
- hex = rgbString2hex(input.val());
- alpha = keepWithin(parseFloat(getAlpha(input.val())).toFixed(2), 0, 1);
- if(alpha) {
- input.attr('data-opacity', alpha);
- }
- } else {
- hex = convertCase(parseHex(input.val(), true), settings.letterCase);
- }
- if(!hex){
- hex = convertCase(parseInput(settings.defaultValue, true), settings.letterCase);
- }
- hsb = hex2hsb(hex);
- // Get array of lowercase keywords
- keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function(a) {
- return a.toLowerCase().trim();
- });
- // Set color string
- if(input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1) {
- value = convertCase(input.val());
- } else {
- value = isRgb(input.val()) ? parseRgb(input.val()) : hex;
- }
- // Update input value
- if(!preserveInputValue) input.val(value);
- // Determine opacity value
- if(settings.opacity) {
- // Get from data-opacity attribute and keep within 0-1 range
- opacity = input.attr('data-opacity') === '' ? 1 : keepWithin(parseFloat(input.attr('data-opacity')).toFixed(2), 0, 1);
- if(isNaN(opacity)) opacity = 1;
- input.attr('data-opacity', opacity);
- swatch.find('span').css('opacity', String(opacity));
- // Set opacity picker position
- y = keepWithin(opacitySlider.height() - (opacitySlider.height() * opacity), 0, opacitySlider.height());
- opacityPicker.css('top', y + 'px');
- }
- // Set opacity to zero if input value is transparent
- if(input.val().toLowerCase() === 'transparent') {
- swatch.find('span').css('opacity', String(0));
- }
- // Update swatch
- swatch.find('span').css('backgroundColor', hex);
- // Determine picker locations
- switch(settings.control) {
- case 'wheel':
- // Set grid position
- r = keepWithin(Math.ceil(hsb.s * 0.75), 0, grid.height() / 2);
- phi = hsb.h * Math.PI / 180;
- x = keepWithin(75 - Math.cos(phi) * r, 0, grid.width());
- y = keepWithin(75 - Math.sin(phi) * r, 0, grid.height());
- gridPicker.css({
- top: y + 'px',
- left: x + 'px'
- });
- // Set slider position
- y = 150 - (hsb.b / (100 / grid.height()));
- if(hex === '') y = 0;
- sliderPicker.css('top', y + 'px');
-
- // Update panel color
- slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 }));
- break;
- case 'saturation':
- // Set grid position
- x = keepWithin((5 * hsb.h) / 12, 0, 150);
- y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
- gridPicker.css({
- top: y + 'px',
- left: x + 'px'
- });
- // Set slider position
- y = keepWithin(slider.height() - (hsb.s * (slider.height() / 100)), 0, slider.height());
- sliderPicker.css('top', y + 'px');
- // Update UI
- slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: hsb.b }));
- minicolors.find('.minicolors-grid-inner').css('opacity', hsb.s / 100);
- break;
- case 'brightness':
- // Set grid position
- x = keepWithin((5 * hsb.h) / 12, 0, 150);
- y = keepWithin(grid.height() - Math.ceil(hsb.s / (100 / grid.height())), 0, grid.height());
- gridPicker.css({
- top: y + 'px',
- left: x + 'px'
- });
- // Set slider position
- y = keepWithin(slider.height() - (hsb.b * (slider.height() / 100)), 0, slider.height());
- sliderPicker.css('top', y + 'px');
- // Update UI
- slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 }));
- minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (hsb.b / 100));
- break;
- default:
- // Set grid position
- x = keepWithin(Math.ceil(hsb.s / (100 / grid.width())), 0, grid.width());
- y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
- gridPicker.css({
- top: y + 'px',
- left: x + 'px'
- });
- // Set slider position
- y = keepWithin(slider.height() - (hsb.h / (360 / slider.height())), 0, slider.height());
- sliderPicker.css('top', y + 'px');
- // Update panel color
- grid.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: 100 }));
- break;
- }
- // Fire change event, but only if minicolors is fully initialized
- if(input.data('minicolors-initialized')) {
- doChange(input, value, opacity);
- }
- }
- // Runs the change and changeDelay callbacks
- function doChange(input, value, opacity) {
- var settings = input.data('minicolors-settings');
- var lastChange = input.data('minicolors-lastChange');
- var obj, sel, i;
- // Only run if it actually changed
- if(!lastChange || lastChange.value !== value || lastChange.opacity !== opacity) {
- // Remember last-changed value
- input.data('minicolors-lastChange', {
- value: value,
- opacity: opacity
- });
- // Check and select applicable swatch
- if(settings.swatches && settings.swatches.length !== 0) {
- if(!isRgb(value)) {
- obj = hex2rgb(value);
- }
- else {
- obj = parseRgb(value, true);
- }
- sel = -1;
- for(i = 0; i < settings.swatches.length; ++i) {
- if(obj.r === settings.swatches[i].r && obj.g === settings.swatches[i].g && obj.b === settings.swatches[i].b && obj.a === settings.swatches[i].a) {
- sel = i;
- break;
- }
- }
- input.parent().find('.minicolors-swatches .minicolors-swatch').removeClass('selected');
- if(sel !== -1) {
- input.parent().find('.minicolors-swatches .minicolors-swatch').eq(i).addClass('selected');
- }
- }
- // Fire change event
- if(settings.change) {
- if(settings.changeDelay) {
- // Call after a delay
- clearTimeout(input.data('minicolors-changeTimeout'));
- input.data('minicolors-changeTimeout', setTimeout(function() {
- settings.change.call(input.get(0), value, opacity);
- }, settings.changeDelay));
- } else {
- // Call immediately
- settings.change.call(input.get(0), value, opacity);
- }
- }
- input.trigger('change').trigger('input');
- }
- }
- // Generates an RGB(A) object based on the input's value
- function rgbObject(input) {
- var rgb,
- opacity = $(input).attr('data-opacity');
- if( isRgb($(input).val()) ) {
- rgb = parseRgb($(input).val(), true);
- } else {
- var hex = parseHex($(input).val(), true);
- rgb = hex2rgb(hex);
- }
- if( !rgb ) return null;
- if( opacity !== undefined ) $.extend(rgb, { a: parseFloat(opacity) });
- return rgb;
- }
- // Generates an RGB(A) string based on the input's value
- function rgbString(input, alpha) {
- var rgb,
- opacity = $(input).attr('data-opacity');
- if( isRgb($(input).val()) ) {
- rgb = parseRgb($(input).val(), true);
- } else {
- var hex = parseHex($(input).val(), true);
- rgb = hex2rgb(hex);
- }
- if( !rgb ) return null;
- if( opacity === undefined ) opacity = 1;
- if( alpha ) {
- return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat(opacity) + ')';
- } else {
- return 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')';
- }
- }
- // Converts to the letter case specified in settings
- function convertCase(string, letterCase) {
- return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase();
- }
- // Parses a string and returns a valid hex string when possible
- function parseHex(string, expand) {
- string = string.replace(/^#/g, '');
- if(!string.match(/^[A-F0-9]{3,6}/ig)) return '';
- if(string.length !== 3 && string.length !== 6) return '';
- if(string.length === 3 && expand) {
- string = string[0] + string[0] + string[1] + string[1] + string[2] + string[2];
- }
- return '#' + string;
- }
- // Parses a string and returns a valid RGB(A) string when possible
- function parseRgb(string, obj) {
- var values = string.replace(/[^\d,.]/g, '');
- var rgba = values.split(',');
- rgba[0] = keepWithin(parseInt(rgba[0], 10), 0, 255);
- rgba[1] = keepWithin(parseInt(rgba[1], 10), 0, 255);
- rgba[2] = keepWithin(parseInt(rgba[2], 10), 0, 255);
- if(rgba[3] !== undefined) {
- rgba[3] = keepWithin(parseFloat(rgba[3], 10), 0, 1);
- }
- // Return RGBA object
- if( obj ) {
- if (rgba[3] !== undefined) {
- return {
- r: rgba[0],
- g: rgba[1],
- b: rgba[2],
- a: rgba[3]
- };
- } else {
- return {
- r: rgba[0],
- g: rgba[1],
- b: rgba[2]
- };
- }
- }
- // Return RGBA string
- if(typeof(rgba[3]) !== 'undefined' && rgba[3] <= 1) {
- return 'rgba(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ', ' + rgba[3] + ')';
- } else {
- return 'rgb(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ')';
- }
- }
- // Parses a string and returns a valid color string when possible
- function parseInput(string, expand) {
- if(isRgb(string)) {
- // Returns a valid rgb(a) string
- return parseRgb(string);
- } else {
- return parseHex(string, expand);
- }
- }
- // Keeps value within min and max
- function keepWithin(value, min, max) {
- if(value < min) value = min;
- if(value > max) value = max;
- return value;
- }
- // Checks if a string is a valid RGB(A) string
- function isRgb(string) {
- var rgb = string.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
- return (rgb && rgb.length === 4) ? true : false;
- }
- // Function to get alpha from a RGB(A) string
- function getAlpha(rgba) {
- rgba = rgba.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+(\.\d{1,2})?|\.\d{1,2})[\s+]?/i);
- return (rgba && rgba.length === 6) ? rgba[4] : '1';
- }
- // Converts an HSB object to an RGB object
- function hsb2rgb(hsb) {
- var rgb = {};
- var h = Math.round(hsb.h);
- var s = Math.round(hsb.s * 255 / 100);
- var v = Math.round(hsb.b * 255 / 100);
- if(s === 0) {
- rgb.r = rgb.g = rgb.b = v;
- } else {
- var t1 = v;
- var t2 = (255 - s) * v / 255;
- var t3 = (t1 - t2) * (h % 60) / 60;
- if(h === 360) h = 0;
- if(h < 60) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
- else if(h < 120) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
- else if(h < 180) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
- else if(h < 240) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
- else if(h < 300) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
- else if(h < 360) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
- else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
- }
- return {
- r: Math.round(rgb.r),
- g: Math.round(rgb.g),
- b: Math.round(rgb.b)
- };
- }
- // Converts an RGB string to a hex string
- function rgbString2hex(rgb){
- rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
- return (rgb && rgb.length === 4) ? '#' +
- ('0' + parseInt(rgb[1],10).toString(16)).slice(-2) +
- ('0' + parseInt(rgb[2],10).toString(16)).slice(-2) +
- ('0' + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
- }
- // Converts an RGB object to a hex string
- function rgb2hex(rgb) {
- var hex = [
- rgb.r.toString(16),
- rgb.g.toString(16),
- rgb.b.toString(16)
- ];
- $.each(hex, function(nr, val) {
- if(val.length === 1) hex[nr] = '0' + val;
- });
- return '#' + hex.join('');
- }
- // Converts an HSB object to a hex string
- function hsb2hex(hsb) {
- return rgb2hex(hsb2rgb(hsb));
- }
- // Converts a hex string to an HSB object
- function hex2hsb(hex) {
- var hsb = rgb2hsb(hex2rgb(hex));
- if(hsb.s === 0) hsb.h = 360;
- return hsb;
- }
- // Converts an RGB object to an HSB object
- function rgb2hsb(rgb) {
- var hsb = { h: 0, s: 0, b: 0 };
- var min = Math.min(rgb.r, rgb.g, rgb.b);
- var max = Math.max(rgb.r, rgb.g, rgb.b);
- var delta = max - min;
- hsb.b = max;
- hsb.s = max !== 0 ? 255 * delta / max : 0;
- if(hsb.s !== 0) {
- if(rgb.r === max) {
- hsb.h = (rgb.g - rgb.b) / delta;
- } else if(rgb.g === max) {
- hsb.h = 2 + (rgb.b - rgb.r) / delta;
- } else {
- hsb.h = 4 + (rgb.r - rgb.g) / delta;
- }
- } else {
- hsb.h = -1;
- }
- hsb.h *= 60;
- if(hsb.h < 0) {
- hsb.h += 360;
- }
- hsb.s *= 100/255;
- hsb.b *= 100/255;
- return hsb;
- }
- // Converts a hex string to an RGB object
- function hex2rgb(hex) {
- hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
- return {
- r: hex >> 16,
- g: (hex & 0x00FF00) >> 8,
- b: (hex & 0x0000FF)
- };
- }
- // Handle events
- $([document])
- // Hide on clicks outside of the control
- .on('mousedown.minicolors touchstart.minicolors', function(event) {
- if(!$(event.target).parents().add(event.target).hasClass('minicolors')) {
- hide();
- }
- })
- // Start moving
- .on('mousedown.minicolors touchstart.minicolors', '.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider', function(event) {
- var target = $(this);
- event.preventDefault();
- $(event.delegateTarget).data('minicolors-target', target);
- move(target, event, true);
- })
- // Move pickers
- .on('mousemove.minicolors touchmove.minicolors', function(event) {
- var target = $(event.delegateTarget).data('minicolors-target');
- if(target) move(target, event);
- })
- // Stop moving
- .on('mouseup.minicolors touchend.minicolors', function() {
- $(this).removeData('minicolors-target');
- })
- // Selected a swatch
- .on('click.minicolors', '.minicolors-swatches li', function(event) {
- event.preventDefault();
- var target = $(this), input = target.parents('.minicolors').find('.minicolors-input'), color = target.data('swatch-color');
- updateInput(input, color, getAlpha(color));
- updateFromInput(input);
- })
- // Show panel when swatch is clicked
- .on('mousedown.minicolors touchstart.minicolors', '.minicolors-input-swatch', function(event) {
- var input = $(this).parent().find('.minicolors-input');
- event.preventDefault();
- show(input);
- })
- // Show on focus
- .on('focus.minicolors', '.minicolors-input', function() {
- var input = $(this);
- if(!input.data('minicolors-initialized')) return;
- show(input);
- })
- // Update value on blur
- .on('blur.minicolors', '.minicolors-input', function() {
- var input = $(this);
- var settings = input.data('minicolors-settings');
- var keywords;
- var hex;
- var rgba;
- var swatchOpacity;
- var value;
- if(!input.data('minicolors-initialized')) return;
- // Get array of lowercase keywords
- keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function(a) {
- return a.toLowerCase().trim();
- });
- // Set color string
- if(input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1) {
- value = input.val();
- } else {
- // Get RGBA values for easy conversion
- if(isRgb(input.val())) {
- rgba = parseRgb(input.val(), true);
- } else {
- hex = parseHex(input.val(), true);
- rgba = hex ? hex2rgb(hex) : null;
- }
- // Convert to format
- if(rgba === null) {
- value = settings.defaultValue;
- } else if(settings.format === 'rgb') {
- value = settings.opacity ?
- parseRgb('rgba(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ',' + input.attr('data-opacity') + ')') :
- parseRgb('rgb(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ')');
- } else {
- value = rgb2hex(rgba);
- }
- }
- // Update swatch opacity
- swatchOpacity = settings.opacity ? input.attr('data-opacity') : 1;
- if(value.toLowerCase() === 'transparent') swatchOpacity = 0;
- input
- .closest('.minicolors')
- .find('.minicolors-input-swatch > span')
- .css('opacity', String(swatchOpacity));
- // Set input value
- input.val(value);
- // Is it blank?
- if(input.val() === '') input.val(parseInput(settings.defaultValue, true));
- // Adjust case
- input.val(convertCase(input.val(), settings.letterCase));
- })
- // Handle keypresses
- .on('keydown.minicolors', '.minicolors-input', function(event) {
- var input = $(this);
- if(!input.data('minicolors-initialized')) return;
- switch(event.which) {
- case 9: // tab
- hide();
- break;
- case 13: // enter
- case 27: // esc
- hide();
- input.blur();
- break;
- }
- })
- // Update on keyup
- .on('keyup.minicolors', '.minicolors-input', function() {
- var input = $(this);
- if(!input.data('minicolors-initialized')) return;
- updateFromInput(input, true);
- })
- // Update on paste
- .on('paste.minicolors', '.minicolors-input', function() {
- var input = $(this);
- if(!input.data('minicolors-initialized')) return;
- setTimeout(function() {
- updateFromInput(input, true);
- }, 1);
- });
- }));
|