diff --git a/src/main/webapp/assets/colorpicker/css/bootstrap-colorpicker.css b/src/main/webapp/assets/colorpicker/css/bootstrap-colorpicker.css new file mode 100644 index 0000000..dd09b94 --- /dev/null +++ b/src/main/webapp/assets/colorpicker/css/bootstrap-colorpicker.css @@ -0,0 +1,117 @@ +/* + Colorpicker for Bootstrap + Copyright 2012 Stefan Petre + Licensed under the Apache License v2.0 + http://www.apache.org/licenses/LICENSE-2.0 +*/ +.colorpicker-saturation { + width: 100px; + height: 100px; + background-image: url(../img/bootstrap-colorpicker/saturation.png); + cursor: crosshair; + float: left; +} +.colorpicker-saturation i { + display: block; + height: 5px; + width: 5px; + border: 1px solid #000; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + position: absolute; + top: 0; + left: 0; + margin: -4px 0 0 -4px; +} +.colorpicker-saturation i b { + display: block; + height: 5px; + width: 5px; + border: 1px solid #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.colorpicker-hue, +.colorpicker-alpha { + width: 15px; + height: 100px; + float: left; + cursor: row-resize; + margin-left: 4px; + margin-bottom: 4px; +} +.colorpicker-hue i, +.colorpicker-alpha i { + display: block; + height: 1px; + background: #000; + border-top: 1px solid #fff; + position: absolute; + top: 0; + left: 0; + width: 100%; + margin-top: -1px; +} +.colorpicker-hue { background-image: url(../img/bootstrap-colorpicker/hue.png) } +.colorpicker-alpha { + background-image: url(../img/bootstrap-colorpicker/alpha.png); + display: none; +} +.colorpicker { + *zoom: 1; + top: 0; + left: 0; + padding: 4px; + min-width: 120px; + margin-top: 1px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.colorpicker:before, +.colorpicker:after { + display: table; + content: ""; +} +.colorpicker:after { clear: both } +.colorpicker:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 6px; +} +.colorpicker:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 7px; +} +.colorpicker div { position: relative } +.colorpicker.alpha { min-width: 140px } +.colorpicker.alpha .colorpicker-alpha { display: block } +.colorpicker-color { + height: 10px; + margin-top: 5px; + clear: both; + background-image: url(../img/bootstrap-colorpicker/alpha.png); + background-position: 0 100%; +} +.colorpicker-color div { height: 10px } +.input-append.color .add-on i, +.input-prepend.color .add-on i { + display: block; + cursor: pointer; + width: 16px; + height: 16px; +} \ No newline at end of file diff --git a/src/main/webapp/assets/colorpicker/css/colorpicker.css b/src/main/webapp/assets/colorpicker/css/colorpicker.css deleted file mode 100644 index 5edaad5..0000000 --- a/src/main/webapp/assets/colorpicker/css/colorpicker.css +++ /dev/null @@ -1,127 +0,0 @@ -/*! -* Colorpicker for Bootstrap -* -* Copyright 2012 Stefan Petre -* Licensed under the Apache License v2.0 -* http://www.apache.org/licenses/LICENSE-2.0 -* -*/ -.colorpicker-saturation { - width: 100px; - height: 100px; - background-image: url(/img/saturation.png); - cursor: crosshair; - float: left; -} -.colorpicker-saturation i { - display: block; - height: 5px; - width: 5px; - border: 1px solid #000; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - position: absolute; - top: 0; - left: 0; - margin: -4px 0 0 -4px; -} -.colorpicker-saturation i b { - display: block; - height: 5px; - width: 5px; - border: 1px solid #fff; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.colorpicker-hue, .colorpicker-alpha { - width: 15px; - height: 100px; - float: left; - cursor: row-resize; - margin-left: 4px; - margin-bottom: 4px; -} -.colorpicker-hue i, .colorpicker-alpha i { - display: block; - height: 1px; - background: #000; - border-top: 1px solid #fff; - position: absolute; - top: 0; - left: 0; - width: 100%; - margin-top: -1px; -} -.colorpicker-hue { - background-image: url(/img/hue.png); -} -.colorpicker-alpha { - background-image: url(/img/alpha.png); - display: none; -} -.colorpicker { - *zoom: 1; - top: 0; - left: 0; - padding: 4px; - min-width: 120px; - margin-top: 1px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.colorpicker:before, .colorpicker:after { - display: table; - content: ""; -} -.colorpicker:after { - clear: both; -} -.colorpicker:before { - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-bottom-color: rgba(0, 0, 0, 0.2); - position: absolute; - top: -7px; - left: 6px; -} -.colorpicker:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #ffffff; - position: absolute; - top: -6px; - left: 7px; -} -.colorpicker div { - position: relative; -} -.colorpicker.alpha { - min-width: 140px; -} -.colorpicker.alpha .colorpicker-alpha { - display: block; -} -.colorpicker-color { - height: 10px; - margin-top: 5px; - clear: both; - background-image: url(/img/alpha.png); - background-position: 0 100%; -} -.colorpicker-color div { - height: 10px; -} -.input-append.color .add-on i, .input-prepend.color .add-on i { - display: block; - cursor: pointer; - width: 16px; - height: 16px; -} \ No newline at end of file diff --git a/src/main/webapp/assets/colorpicker/img/alpha.png b/src/main/webapp/assets/colorpicker/img/alpha.png deleted file mode 100644 index 38043f1..0000000 --- a/src/main/webapp/assets/colorpicker/img/alpha.png +++ /dev/null Binary files differ diff --git a/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/alpha.png b/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/alpha.png new file mode 100644 index 0000000..38043f1 --- /dev/null +++ b/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/alpha.png Binary files differ diff --git a/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/hue.png b/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/hue.png new file mode 100644 index 0000000..d89560e --- /dev/null +++ b/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/hue.png Binary files differ diff --git a/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/saturation.png b/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/saturation.png new file mode 100644 index 0000000..594ae50 --- /dev/null +++ b/src/main/webapp/assets/colorpicker/img/bootstrap-colorpicker/saturation.png Binary files differ diff --git a/src/main/webapp/assets/colorpicker/img/hue.png b/src/main/webapp/assets/colorpicker/img/hue.png deleted file mode 100644 index d89560e..0000000 --- a/src/main/webapp/assets/colorpicker/img/hue.png +++ /dev/null Binary files differ diff --git a/src/main/webapp/assets/colorpicker/img/saturation.png b/src/main/webapp/assets/colorpicker/img/saturation.png deleted file mode 100644 index 594ae50..0000000 --- a/src/main/webapp/assets/colorpicker/img/saturation.png +++ /dev/null Binary files differ diff --git a/src/main/webapp/assets/colorpicker/js/bootstrap-colorpicker.js b/src/main/webapp/assets/colorpicker/js/bootstrap-colorpicker.js index 818b3cf..a2b85a8 100644 --- a/src/main/webapp/assets/colorpicker/js/bootstrap-colorpicker.js +++ b/src/main/webapp/assets/colorpicker/js/bootstrap-colorpicker.js @@ -16,525 +16,563 @@ * See the License for the specific language governing permissions and * limitations under the License. * ========================================================= */ - -!function( $ ) { - - // Color object - - var Color = function(val) { - this.value = { - h: 1, - s: 1, - b: 1, - a: 1 - }; - this.setColor(val); - }; - - Color.prototype = { - constructor: Color, - - //parse a string to HSB - setColor: function(val){ - val = val.toLowerCase(); - var that = this; - $.each( CPGlobal.stringParsers, function( i, parser ) { - var match = parser.re.exec( val ), - values = match && parser.parse( match ), - space = parser.space||'rgba'; - if ( values ) { - if (space === 'hsla') { - that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values)); - } else { - that.value = CPGlobal.RGBtoHSB.apply(null, values); - } - return false; - } - }); - }, - - setHue: function(h) { - this.value.h = 1- h; - }, - - setSaturation: function(s) { - this.value.s = s; - }, - - setLightness: function(b) { - this.value.b = 1- b; - }, - - setAlpha: function(a) { - this.value.a = parseInt((1 - a)*100, 10)/100; - }, - - // HSBtoRGB from RaphaelJS - // https://github.com/DmitryBaranovskiy/raphael/ - toRGB: function(h, s, b, a) { - if (!h) { - h = this.value.h; - s = this.value.s; - b = this.value.b; - } - h *= 360; - var R, G, B, X, C; - h = (h % 360) / 60; - C = b * s; - X = C * (1 - Math.abs(h % 2 - 1)); - R = G = B = b - C; - h = ~~h; - R += [C, X, 0, 0, X, C][h]; - G += [X, C, C, X, 0, 0][h]; - B += [0, 0, X, C, C, X][h]; - return { - r: Math.round(R*255), - g: Math.round(G*255), - b: Math.round(B*255), - a: a||this.value.a - }; - }, - - toHex: function(h, s, b, a){ - var rgb = this.toRGB(h, s, b, a); - return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1); - }, - - toHSL: function(h, s, b, a){ - if (!h) { - h = this.value.h; - s = this.value.s; - b = this.value.b; - } - var H = h, - L = (2 - s) * b, - S = s * b; - if (L > 0 && L <= 1) { - S /= L; - } else { - S /= 2 - L; - } - L /= 2; - if (S > 1) { - S = 1; - } - return { - h: H, - s: S, - l: L, - a: a||this.value.a - }; - } - }; - - // Picker object - - var Colorpicker = function(element, options){ - this.element = $(element); - var format = options.format||this.element.data('color-format')||'hex'; - this.format = CPGlobal.translateFormats[format]; - this.isInput = this.element.is('input'); - this.component = this.element.is('.color') ? this.element.find('.add-on') : false; - - this.picker = $(CPGlobal.template) - .appendTo('body') - .on('mousedown', $.proxy(this.mousedown, this)); - - if (this.isInput) { - this.element.on({ - 'focus': $.proxy(this.show, this), - 'keyup': $.proxy(this.update, this) - }); - } else if (this.component){ - this.component.on({ - 'click': $.proxy(this.show, this) - }); - } else { - this.element.on({ - 'click': $.proxy(this.show, this) - }); - } - if (format === 'rgba' || format === 'hsla') { - this.picker.addClass('alpha'); - this.alpha = this.picker.find('.colorpicker-alpha')[0].style; - } - - if (this.component){ - this.picker.find('.colorpicker-color').hide(); - this.preview = this.element.find('i')[0].style; - } else { - this.preview = this.picker.find('div:last')[0].style; - } - - this.base = this.picker.find('div:first')[0].style; - this.update(); - }; - - Colorpicker.prototype = { - constructor: Colorpicker, - - show: function(e) { - this.picker.show(); - this.height = this.component ? this.component.outerHeight() : this.element.outerHeight(); - this.place(); - $(window).on('resize', $.proxy(this.place, this)); - if (!this.isInput) { - if (e) { - e.stopPropagation(); - e.preventDefault(); - } - } - $(document).on({ - 'mousedown': $.proxy(this.hide, this) - }); - this.element.trigger({ - type: 'show', - color: this.color - }); - }, - - update: function(){ - this.color = new Color(this.isInput ? this.element.prop('value') : this.element.data('color')); - this.picker.find('i') - .eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end() - .eq(1).css('top', 100 * (1 - this.color.value.h)).end() - .eq(2).css('top', 100 * (1 - this.color.value.a)); - this.previewColor(); - }, - - setValue: function(newColor) { - this.color = new Color(newColor); - this.picker.find('i') - .eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end() - .eq(1).css('top', 100 * (1 - this.color.value.h)).end() - .eq(2).css('top', 100 * (1 - this.color.value.a)); - this.previewColor(); - this.element.trigger({ - type: 'changeColor', - color: this.color - }); - }, - - hide: function(){ - this.picker.hide(); - $(window).off('resize', this.place); - if (!this.isInput) { - $(document).off({ - 'mousedown': this.hide - }); - if (this.component){ - this.element.find('input[type=hidden]').prop('value', this.format.call(this)); - } - this.element.data('color', this.format.call(this)); - } else { - this.element.prop('value', this.format.call(this)); - } - this.element.trigger({ - type: 'hide', - color: this.color - }); - }, - - place: function(){ - var offset = this.component ? this.component.offset() : this.element.offset(); - this.picker.css({ - top: offset.top + this.height, - left: offset.left - }); - }, - - //preview color change - previewColor: function(){ - try { - this.preview.backgroundColor = this.format.call(this); - } catch(e) { - this.preview.backgroundColor = this.color.toHex(); - } - //set the color for brightness/saturation slider - this.base.backgroundColor = this.color.toHex(this.color.value.h, 1, 1, 1); - //set te color for alpha slider - if (this.alpha) { - this.alpha.backgroundColor = this.color.toHex(); - } - }, - - pointer: null, - - slider: null, - - mousedown: function(e){ - e.stopPropagation(); - e.preventDefault(); - - var target = $(e.target); - - //detect the slider and set the limits and callbacks - var zone = target.closest('div'); - if (!zone.is('.colorpicker')) { - if (zone.is('.colorpicker-saturation')) { - this.slider = $.extend({}, CPGlobal.sliders.saturation); - } - else if (zone.is('.colorpicker-hue')) { - this.slider = $.extend({}, CPGlobal.sliders.hue); - } - else if (zone.is('.colorpicker-alpha')) { - this.slider = $.extend({}, CPGlobal.sliders.alpha); - } else { - return false; - } - var offset = zone.offset(); - //reference to knob's style - this.slider.knob = zone.find('i')[0].style; - this.slider.left = e.pageX - offset.left; - this.slider.top = e.pageY - offset.top; - this.pointer = { - left: e.pageX, - top: e.pageY - }; - //trigger mousemove to move the knob to the current position - $(document).on({ - mousemove: $.proxy(this.mousemove, this), - mouseup: $.proxy(this.mouseup, this) - }).trigger('mousemove'); - } - return false; - }, - - mousemove: function(e){ - e.stopPropagation(); - e.preventDefault(); - var left = Math.max( - 0, - Math.min( - this.slider.maxLeft, - this.slider.left + ((e.pageX||this.pointer.left) - this.pointer.left) - ) - ); - var top = Math.max( - 0, - Math.min( - this.slider.maxTop, - this.slider.top + ((e.pageY||this.pointer.top) - this.pointer.top) - ) - ); - this.slider.knob.left = left + 'px'; - this.slider.knob.top = top + 'px'; - if (this.slider.callLeft) { - this.color[this.slider.callLeft].call(this.color, left/100); - } - if (this.slider.callTop) { - this.color[this.slider.callTop].call(this.color, top/100); - } - this.previewColor(); - this.element.trigger({ - type: 'changeColor', - color: this.color - }); - return false; - }, - - mouseup: function(e){ - e.stopPropagation(); - e.preventDefault(); - $(document).off({ - mousemove: this.mousemove, - mouseup: this.mouseup - }); - return false; - } - } +!function($) { - $.fn.colorpicker = function ( option, val ) { - return this.each(function () { - var $this = $(this), - data = $this.data('colorpicker'), - options = typeof option === 'object' && option; - if (!data) { - $this.data('colorpicker', (data = new Colorpicker(this, $.extend({}, $.fn.colorpicker.defaults,options)))); - } - if (typeof option === 'string') data[option](val); - }); - }; + // Color object - $.fn.colorpicker.defaults = { - }; - - $.fn.colorpicker.Constructor = Colorpicker; - - var CPGlobal = { - - // translate a format from Color object to a string - translateFormats: { - 'rgb': function(){ - var rgb = this.color.toRGB(); - return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'; - }, - - 'rgba': function(){ - var rgb = this.color.toRGB(); - return 'rgba('+rgb.r+','+rgb.g+','+rgb.b+','+rgb.a+')'; - }, - - 'hsl': function(){ - var hsl = this.color.toHSL(); - return 'hsl('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%)'; - }, - - 'hsla': function(){ - var hsl = this.color.toHSL(); - return 'hsla('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%,'+hsl.a+')'; - }, - - 'hex': function(){ - return this.color.toHex(); - } - }, - - sliders: { - saturation: { - maxLeft: 100, - maxTop: 100, - callLeft: 'setSaturation', - callTop: 'setLightness' - }, - - hue: { - maxLeft: 0, - maxTop: 100, - callLeft: false, - callTop: 'setHue' - }, - - alpha: { - maxLeft: 0, - maxTop: 100, - callLeft: false, - callTop: 'setAlpha' - } - }, - - // HSBtoRGB from RaphaelJS - // https://github.com/DmitryBaranovskiy/raphael/ - RGBtoHSB: function (r, g, b, a){ - r /= 255; - g /= 255; - b /= 255; + var Color = function(val) { + this.value = { + h: 1, + s: 1, + b: 1, + a: 1 + }; + this.setColor(val); + }; - var H, S, V, C; - V = Math.max(r, g, b); - C = V - Math.min(r, g, b); - H = (C === 0 ? null : - V == r ? (g - b) / C : - V == g ? (b - r) / C + 2 : - (r - g) / C + 4 - ); - H = ((H + 360) % 6) * 60 / 360; - S = C === 0 ? 0 : C / V; - return {h: H||1, s: S, b: V, a: a||1}; - }, - - HueToRGB: function (p, q, h) { - if (h < 0) - h += 1; - else if (h > 1) - h -= 1; + Color.prototype = { + constructor: Color, - if ((h * 6) < 1) - return p + (q - p) * h * 6; - else if ((h * 2) < 1) - return q; - else if ((h * 3) < 2) - return p + (q - p) * ((2 / 3) - h) * 6; - else - return p; - }, - - HSLtoRGB: function (h, s, l, a) - { - if (s < 0) { - s = 0; - } - var q; - if (l <= 0.5) { - q = l * (1 + s); - } else { - q = l + s - (l * s); - } - - var p = 2 * l - q; + //parse a string to HSB + setColor: function(val) { + val = val.toLowerCase(); + var that = this; + $.each(CPGlobal.stringParsers, function(i, parser) { + var match = parser.re.exec(val), + values = match && parser.parse(match), + space = parser.space || 'rgba'; + if (values) { + if (space === 'hsla') { + that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values)); + } else { + that.value = CPGlobal.RGBtoHSB.apply(null, values); + } + return false; + } + return true; + }); + }, - var tr = h + (1 / 3); - var tg = h; - var tb = h - (1 / 3); + setHue: function(h) { + this.value.h = 1 - h; + }, - var r = Math.round(CPGlobal.HueToRGB(p, q, tr) * 255); - var g = Math.round(CPGlobal.HueToRGB(p, q, tg) * 255); - var b = Math.round(CPGlobal.HueToRGB(p, q, tb) * 255); - return [r, g, b, a||1]; - }, - - // a set of RE's that can match strings and generate color tuples. - // from John Resig color plugin - // https://github.com/jquery/jquery-color/ - stringParsers: [ - { - re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ], - execResult[ 3 ], - execResult[ 4 ] - ]; - } - }, { - re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - 2.55 * execResult[1], - 2.55 * execResult[2], - 2.55 * execResult[3], - execResult[ 4 ] - ]; - } - }, { - re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ], 16 ) - ]; - } - }, { - re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) - ]; - } - }, { - re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, - space: 'hsla', - parse: function( execResult ) { - return [ - execResult[1]/360, - execResult[2] / 100, - execResult[3] / 100, - execResult[4] - ]; - } - } - ], - template: '
' - }; + setSaturation: function(s) { + this.value.s = s; + }, -}( window.jQuery ) \ No newline at end of file + setLightness: function(b) { + this.value.b = 1 - b; + }, + + setAlpha: function(a) { + this.value.a = parseInt((1 - a) * 100, 10) / 100; + }, + + // HSBtoRGB from RaphaelJS + // https://github.com/DmitryBaranovskiy/raphael/ + toRGB: function(h, s, b, a) { + if (!h) { + h = this.value.h; + s = this.value.s; + b = this.value.b; + } + h *= 360; + var R, G, B, X, C; + h = (h % 360) / 60; + C = b * s; + X = C * (1 - Math.abs(h % 2 - 1)); + R = G = B = b - C; + + h = ~~h; + R += [C, X, 0, 0, X, C][h]; + G += [X, C, C, X, 0, 0][h]; + B += [0, 0, X, C, C, X][h]; + return { + r: Math.round(R * 255), + g: Math.round(G * 255), + b: Math.round(B * 255), + a: a || this.value.a + }; + }, + + toHex: function(h, s, b, a) { + var rgb = this.toRGB(h, s, b, a); + return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1); + }, + + toHSL: function(h, s, b, a) { + if (!h) { + h = this.value.h; + s = this.value.s; + b = this.value.b; + } + var H = h, + L = (2 - s) * b, + S = s * b; + if (L > 0 && L <= 1) { + S /= L; + } else { + S /= 2 - L; + } + L /= 2; + if (S > 1) { + S = 1; + } + return { + h: H, + s: S, + l: L, + a: a || this.value.a + }; + } + }; + + var _guid = 0; + + // Picker object + + var Colorpicker = function(element, options) { + _guid++; + this.element = $(element).attr('data-colorpicker-guid', _guid); + var format = options.format || this.element.data('color-format') || 'hex'; + this.format = CPGlobal.translateFormats[format]; + this.isInput = this.element.is('input'); + this.component = this.element.is('.color') ? this.element.find('.add-on') : false; + + this.picker = $(CPGlobal.template).attr('data-colorpicker-guid', _guid) + .appendTo('body') + .on('mousedown.colorpicker', $.proxy(this.mousedown, this)); + + if (this.isInput) { + this.element.on({ + 'focus.colorpicker': $.proxy(this.show, this), + 'keyup.colorpicker': $.proxy(this.update, this) + }); + } else if (this.component) { + this.component.on({ + 'click.colorpicker': $.proxy(this.show, this) + }); + } else { + this.element.on({ + 'click.colorpicker': $.proxy(this.show, this) + }); + } + if (format === 'rgba' || format === 'hsla') { + this.picker.addClass('alpha'); + this.alpha = this.picker.find('.colorpicker-alpha')[0].style; + } + + if (this.component) { + this.picker.find('.colorpicker-color').hide(); + this.preview = this.element.find('i')[0].style; + } else { + this.preview = this.picker.find('div:last')[0].style; + } + + this.base = this.picker.find('div:first')[0].style; + this.update(); + + $($.proxy(function(){ + this.element.trigger('create', [this]); + }, this)); + }; + + Colorpicker.prototype = { + constructor: Colorpicker, + + show: function(e) { + this.picker.show(); + this.height = this.component ? this.component.outerHeight() : this.element.outerHeight(); + this.place(); + $(window).on('resize.colorpicker', $.proxy(this.place, this)); + if (!this.isInput) { + if (e) { + e.stopPropagation(); + e.preventDefault(); + } + } + $(document).on({ + 'mousedown.colorpicker': $.proxy(this.hide, this) + }); + this.element.trigger({ + type: 'showPicker', + color: this.color + }); + }, + + update: function() { + var color = this.isInput ? this.element.prop('value') : this.element.data('color'); + if (typeof color === "undefined" || color === null) { + color = '#ffffff'; + } + this.color = new Color(color); + this.picker.find('i') + .eq(0).css({left: this.color.value.s * 100, top: 100 - this.color.value.b * 100}).end() + .eq(1).css('top', 100 * (1 - this.color.value.h)).end() + .eq(2).css('top', 100 * (1 - this.color.value.a)); + this.previewColor(); + }, + + hide: function() { + this.picker.hide(); + $(window).off('resize', this.place); + if (!this.isInput) { + $(document).off({ + 'mousedown': this.hide + }); + if (this.component) { + //if the input value is empty, do not set any color + if (this.element.find('input').val() !== '') { + this.element.find('input').prop('value', this.format.call(this)).trigger('change'); + } + } + this.element.data('color', this.format.call(this)); + } else { + //if the input value is empty, do not set any color + if (this.element.val() !== '') { + this.element.prop('value', this.format.call(this)).trigger('change'); + } + } + this.element.trigger({ + type: 'hidePicker', + color: this.color + }); + }, + + place: function() { + var offset = this.component ? this.component.offset() : this.element.offset(); + this.picker.css({ + top: offset.top + this.height, + left: offset.left + }); + }, + + destroy: function(){ + $('.colorpicker[data-colorpicker-guid='+this.element.attr('data-colorpicker-guid')+']').remove(); + this.element.removeData('colorpicker').removeAttr('data-colorpicker-guid').off('.colorpicker'); + if(this.component !== false){ + this.component.off('.colorpicker'); + } + this.element.trigger("destroy", [this]); + }, + + //preview color change + previewColor: function() { + try { + this.preview.backgroundColor = this.format.call(this); + } catch (e) { + this.preview.backgroundColor = this.color.toHex(); + } + //set the color for brightness/saturation slider + this.base.backgroundColor = this.color.toHex(this.color.value.h, 1, 1, 1); + //set te color for alpha slider + if (this.alpha) { + this.alpha.backgroundColor = this.color.toHex(); + } + }, + + pointer: null, + + slider: null, + + mousedown: function(e) { + e.stopPropagation(); + e.preventDefault(); + + var target = $(e.target); + + //detect the slider and set the limits and callbacks + var zone = target.closest('div'); + if (!zone.is('.colorpicker')) { + if (zone.is('.colorpicker-saturation')) { + this.slider = $.extend({}, CPGlobal.sliders.saturation); + } + else if (zone.is('.colorpicker-hue')) { + this.slider = $.extend({}, CPGlobal.sliders.hue); + } + else if (zone.is('.colorpicker-alpha')) { + this.slider = $.extend({}, CPGlobal.sliders.alpha); + } else { + return false; + } + var offset = zone.offset(); + //reference to knob's style + this.slider.knob = zone.find('i')[0].style; + this.slider.left = e.pageX - offset.left; + this.slider.top = e.pageY - offset.top; + this.pointer = { + left: e.pageX, + top: e.pageY + }; + //trigger mousemove to move the knob to the current position + $(document).on({ + 'mousemove.colorpicker': $.proxy(this.mousemove, this), + 'mouseup.colorpicker': $.proxy(this.mouseup, this) + }).trigger('mousemove'); + } + return false; + }, + + mousemove: function(e) { + e.stopPropagation(); + e.preventDefault(); + var left = Math.max( + 0, + Math.min( + this.slider.maxLeft, + this.slider.left + ((e.pageX || this.pointer.left) - this.pointer.left) + ) + ); + var top = Math.max( + 0, + Math.min( + this.slider.maxTop, + this.slider.top + ((e.pageY || this.pointer.top) - this.pointer.top) + ) + ); + this.slider.knob.left = left + 'px'; + this.slider.knob.top = top + 'px'; + if (this.slider.callLeft) { + this.color[this.slider.callLeft].call(this.color, left / 100); + } + if (this.slider.callTop) { + this.color[this.slider.callTop].call(this.color, top / 100); + } + this.previewColor(); + + // Set input value on mousemove + if (!this.isInput) { + try { + this.element.find('input').val(this.format.call(this)).trigger('change'); + } catch (e) { + this.element.find('input').val(this.color.toHex()).trigger('change'); + } + }else{ + try { + this.element.val(this.format.call(this)).trigger('change'); + } catch (e) { + this.element.val(this.color.toHex()).trigger('change'); + } + } + + this.element.trigger({ + type: 'changeColor', + color: this.color + }); + return false; + }, + + mouseup: function(e) { + e.stopPropagation(); + e.preventDefault(); + $(document).off({ + mousemove: this.mousemove, + mouseup: this.mouseup + }); + return false; + } + }; + + $.fn.colorpicker = function(option, value) { + return this.each(function() { + var $this = $(this), + data = $this.data('colorpicker'), + options = typeof option === 'object' && option; + if (!data) { + if(option !== "destroy"){ + $this.data('colorpicker', (data = new Colorpicker(this, $.extend({}, $.fn.colorpicker.defaults, options)))); + } + }else{ + if (typeof option === 'string'){ + data[option](value); + } + } + }); + }; + + $.fn.colorpicker.defaults = { + }; + + $.fn.colorpicker.Constructor = Colorpicker; + + var CPGlobal = { + + // translate a format from Color object to a string + translateFormats: { + 'rgb': function() { + var rgb = this.color.toRGB(); + return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')'; + }, + + 'rgba': function() { + var rgb = this.color.toRGB(); + return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')'; + }, + + 'hsl': function() { + var hsl = this.color.toHSL(); + return 'hsl(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%)'; + }, + + 'hsla': function() { + var hsl = this.color.toHSL(); + return 'hsla(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%,' + hsl.a + ')'; + }, + + 'hex': function() { + return this.color.toHex(); + } + }, + + sliders: { + saturation: { + maxLeft: 100, + maxTop: 100, + callLeft: 'setSaturation', + callTop: 'setLightness' + }, + + hue: { + maxLeft: 0, + maxTop: 100, + callLeft: false, + callTop: 'setHue' + }, + + alpha: { + maxLeft: 0, + maxTop: 100, + callLeft: false, + callTop: 'setAlpha' + } + }, + + // HSBtoRGB from RaphaelJS + // https://github.com/DmitryBaranovskiy/raphael/ + RGBtoHSB: function(r, g, b, a) { + r /= 255; + g /= 255; + b /= 255; + + var H, S, V, C; + V = Math.max(r, g, b); + C = V - Math.min(r, g, b); + H = (C === 0 ? null : + V === r ? (g - b) / C : + V === g ? (b - r) / C + 2 : + (r - g) / C + 4 + ); + H = ((H + 360) % 6) * 60 / 360; + S = C === 0 ? 0 : C / V; + return {h: H || 1, s: S, b: V, a: a || 1}; + }, + + HueToRGB: function(p, q, h) { + if (h < 0) + h += 1; + else if (h > 1) + h -= 1; + + if ((h * 6) < 1) + return p + (q - p) * h * 6; + else if ((h * 2) < 1) + return q; + else if ((h * 3) < 2) + return p + (q - p) * ((2 / 3) - h) * 6; + else + return p; + }, + + HSLtoRGB: function(h, s, l, a) { + if (s < 0) { + s = 0; + } + var q; + if (l <= 0.5) { + q = l * (1 + s); + } else { + q = l + s - (l * s); + } + + var p = 2 * l - q; + + var tr = h + (1 / 3); + var tg = h; + var tb = h - (1 / 3); + + var r = Math.round(CPGlobal.HueToRGB(p, q, tr) * 255); + var g = Math.round(CPGlobal.HueToRGB(p, q, tg) * 255); + var b = Math.round(CPGlobal.HueToRGB(p, q, tb) * 255); + return [r, g, b, a || 1]; + }, + + // a set of RE's that can match strings and generate color tuples. + // from John Resig color plugin + // https://github.com/jquery/jquery-color/ + stringParsers: [ + { + re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, + parse: function(execResult) { + return [ + execResult[1], + execResult[2], + execResult[3], + execResult[4] + ]; + } + }, + { + re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, + parse: function(execResult) { + return [ + 2.55 * execResult[1], + 2.55 * execResult[2], + 2.55 * execResult[3], + execResult[4] + ]; + } + }, + { + re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, + parse: function(execResult) { + return [ + parseInt(execResult[1], 16), + parseInt(execResult[2], 16), + parseInt(execResult[3], 16) + ]; + } + }, + { + re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, + parse: function(execResult) { + return [ + parseInt(execResult[1] + execResult[1], 16), + parseInt(execResult[2] + execResult[2], 16), + parseInt(execResult[3] + execResult[3], 16) + ]; + } + }, + { + re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, + space: 'hsla', + parse: function(execResult) { + return [ + execResult[1] / 360, + execResult[2] / 100, + execResult[3] / 100, + execResult[4] + ]; + } + } + ], + template: ' ' + }; + +}(window.jQuery); \ No newline at end of file