source: pro-violet-viettel/docs/template/assets/js/uncompressed/bootstrap-colorpicker.js

Last change on this file was 400, checked in by dungnv, 11 years ago
  • Property svn:mime-type set to text/plain
File size: 13.1 KB
Line 
1/* =========================================================
2 * bootstrap-colorpicker.js
3 * http://www.eyecon.ro/bootstrap-colorpicker
4 * =========================================================
5 * Copyright 2012 Stefan Petre
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ========================================================= */
19 
20!function( $ ) {
21       
22        // Color object
23       
24        var Color = function(val) {
25                this.value = {
26                        h: 1,
27                        s: 1,
28                        b: 1,
29                        a: 1
30                };
31                this.setColor(val);
32        };
33       
34        Color.prototype = {
35                constructor: Color,
36               
37                //parse a string to HSB
38                setColor: function(val){
39                        val = val.toLowerCase();
40                        var that = this;
41                        $.each( CPGlobal.stringParsers, function( i, parser ) {
42                                var match = parser.re.exec( val ),
43                                        values = match && parser.parse( match ),
44                                        space = parser.space||'rgba';
45                                if ( values ) {
46                                        if (space === 'hsla') {
47                                                that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
48                                        } else {
49                                                that.value = CPGlobal.RGBtoHSB.apply(null, values);
50                                        }
51                                        return false;
52                                }
53                        });
54                },
55               
56                setHue: function(h) {
57                        this.value.h = 1- h;
58                },
59               
60                setSaturation: function(s) {
61                        this.value.s = s;
62                },
63               
64                setLightness: function(b) {
65                        this.value.b = 1- b;
66                },
67               
68                setAlpha: function(a) {
69                        this.value.a = parseInt((1 - a)*100, 10)/100;
70                },
71               
72                // HSBtoRGB from RaphaelJS
73                // https://github.com/DmitryBaranovskiy/raphael/
74                toRGB: function(h, s, b, a) {
75                        if (!h) {
76                                h = this.value.h;
77                                s = this.value.s;
78                                b = this.value.b;
79                        }
80                        h *= 360;
81                        var R, G, B, X, C;
82                        h = (h % 360) / 60;
83                        C = b * s;
84                        X = C * (1 - Math.abs(h % 2 - 1));
85                        R = G = B = b - C;
86
87                        h = ~~h;
88                        R += [C, X, 0, 0, X, C][h];
89                        G += [X, C, C, X, 0, 0][h];
90                        B += [0, 0, X, C, C, X][h];
91                        return {
92                                r: Math.round(R*255),
93                                g: Math.round(G*255),
94                                b: Math.round(B*255),
95                                a: a||this.value.a
96                        };
97                },
98               
99                toHex: function(h, s, b, a){
100                        var rgb = this.toRGB(h, s, b, a);
101                        return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
102                },
103               
104                toHSL: function(h, s, b, a){
105                        if (!h) {
106                                h = this.value.h;
107                                s = this.value.s;
108                                b = this.value.b;
109                        }
110                        var H = h,
111                                L = (2 - s) * b,
112                                S = s * b;
113                        if (L > 0 && L <= 1) {
114                                S /= L;
115                        } else {
116                                S /= 2 - L;
117                        }
118                        L /= 2;
119                        if (S > 1) {
120                                S = 1;
121                        }
122                        return {
123                                h: H,
124                                s: S,
125                                l: L,
126                                a: a||this.value.a
127                        };
128                }
129        };
130       
131        // Picker object
132       
133        var Colorpicker = function(element, options){
134                this.element = $(element);
135                var format = options.format||this.element.data('color-format')||'hex';
136                this.format = CPGlobal.translateFormats[format];
137                this.isInput = this.element.is('input');
138                this.component = this.element.is('.color') ? this.element.find('.add-on') : false;
139               
140                this.picker = $(CPGlobal.template)
141                                                        .appendTo('body')
142                                                        .on('mousedown', $.proxy(this.mousedown, this));
143               
144                if (this.isInput) {
145                        this.element.on({
146                                'focus': $.proxy(this.show, this),
147                                'keyup': $.proxy(this.update, this)
148                        });
149                } else if (this.component){
150                        this.component.on({
151                                'click': $.proxy(this.show, this)
152                        });
153                } else {
154                        this.element.on({
155                                'click': $.proxy(this.show, this)
156                        });
157                }
158                if (format === 'rgba' || format === 'hsla') {
159                        this.picker.addClass('alpha');
160                        this.alpha = this.picker.find('.colorpicker-alpha')[0].style;
161                }
162               
163                if (this.component){
164                        this.picker.find('.colorpicker-color').hide();
165                        this.preview = this.element.find('i')[0].style;
166                } else {
167                        this.preview = this.picker.find('div:last')[0].style;
168                }
169               
170                this.base = this.picker.find('div:first')[0].style;
171                this.update();
172        };
173       
174        Colorpicker.prototype = {
175                constructor: Colorpicker,
176               
177                show: function(e) {
178                        this.picker.show();
179                        this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
180                        this.place();
181                        $(window).on('resize', $.proxy(this.place, this));
182                        if (!this.isInput) {
183                                if (e) {
184                                        e.stopPropagation();
185                                        e.preventDefault();
186                                }
187                        }
188                        $(document).on({
189                                'mousedown': $.proxy(this.hide, this)
190                        });
191                        this.element.trigger({
192                                type: 'show',
193                                color: this.color
194                        });
195                },
196               
197                update: function(){
198                        this.color = new Color(this.isInput ? this.element.prop('value') : this.element.data('color'));
199                        this.picker.find('i')
200                                .eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end()
201                                .eq(1).css('top', 100 * (1 - this.color.value.h)).end()
202                                .eq(2).css('top', 100 * (1 - this.color.value.a));
203                        this.previewColor();
204                },
205               
206                setValue: function(newColor) {
207                        this.color = new Color(newColor);
208                        this.picker.find('i')
209                                .eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end()
210                                .eq(1).css('top', 100 * (1 - this.color.value.h)).end()
211                                .eq(2).css('top', 100 * (1 - this.color.value.a));
212                        this.previewColor();
213                        this.element.trigger({
214                                type: 'changeColor',
215                                color: this.color
216                        });
217                },
218               
219                hide: function(){
220                        this.picker.hide();
221                        $(window).off('resize', this.place);
222                        if (!this.isInput) {
223                                $(document).off({
224                                        'mousedown': this.hide
225                                });
226                                if (this.component){
227                                        this.element.find('input').prop('value', this.format.call(this));
228                                }
229                                this.element.data('color', this.format.call(this));
230                        } else {
231                                this.element.prop('value', this.format.call(this));
232                        }
233                        this.element.trigger({
234                                type: 'hide',
235                                color: this.color
236                        });
237                },
238               
239                place: function(){
240                        var offset = this.component ? this.component.offset() : this.element.offset();
241                        this.picker.css({
242                                top: offset.top + this.height,
243                                left: offset.left
244                        });
245                },
246               
247                //preview color change
248                previewColor: function(){
249                        try {
250                                this.preview.backgroundColor = this.format.call(this);
251                        } catch(e) {
252                                this.preview.backgroundColor = this.color.toHex();
253                        }
254                        //set the color for brightness/saturation slider
255                        this.base.backgroundColor = this.color.toHex(this.color.value.h, 1, 1, 1);
256                        //set te color for alpha slider
257                        if (this.alpha) {
258                                this.alpha.backgroundColor = this.color.toHex();
259                        }
260                },
261               
262                pointer: null,
263               
264                slider: null,
265               
266                mousedown: function(e){
267                        e.stopPropagation();
268                        e.preventDefault();
269                       
270                        var target = $(e.target);
271                       
272                        //detect the slider and set the limits and callbacks
273                        var zone = target.closest('div');
274                        if (!zone.is('.colorpicker')) {
275                                if (zone.is('.colorpicker-saturation')) {
276                                        this.slider = $.extend({}, CPGlobal.sliders.saturation);
277                                }
278                                else if (zone.is('.colorpicker-hue')) {
279                                        this.slider = $.extend({}, CPGlobal.sliders.hue);
280                                }
281                                else if (zone.is('.colorpicker-alpha')) {
282                                        this.slider = $.extend({}, CPGlobal.sliders.alpha);
283                                } else {
284                                        return false;
285                                }
286                                var offset = zone.offset();
287                                //reference to knob's style
288                                this.slider.knob = zone.find('i')[0].style;
289                                this.slider.left = e.pageX - offset.left;
290                                this.slider.top = e.pageY - offset.top;
291                                this.pointer = {
292                                        left: e.pageX,
293                                        top: e.pageY
294                                };
295                                //trigger mousemove to move the knob to the current position
296                                $(document).on({
297                                        mousemove: $.proxy(this.mousemove, this),
298                                        mouseup: $.proxy(this.mouseup, this)
299                                }).trigger('mousemove');
300                        }
301                        return false;
302                },
303               
304                mousemove: function(e){
305                        e.stopPropagation();
306                        e.preventDefault();
307                        var left = Math.max(
308                                0,
309                                Math.min(
310                                        this.slider.maxLeft,
311                                        this.slider.left + ((e.pageX||this.pointer.left) - this.pointer.left)
312                                )
313                        );
314                        var top = Math.max(
315                                0,
316                                Math.min(
317                                        this.slider.maxTop,
318                                        this.slider.top + ((e.pageY||this.pointer.top) - this.pointer.top)
319                                )
320                        );
321                        this.slider.knob.left = left + 'px';
322                        this.slider.knob.top = top + 'px';
323                        if (this.slider.callLeft) {
324                                this.color[this.slider.callLeft].call(this.color, left/100);
325                        }
326                        if (this.slider.callTop) {
327                                this.color[this.slider.callTop].call(this.color, top/100);
328                        }
329                        this.previewColor();
330                        this.element.trigger({
331                                type: 'changeColor',
332                                color: this.color
333                        });
334                        return false;
335                },
336               
337                mouseup: function(e){
338                        e.stopPropagation();
339                        e.preventDefault();
340                        $(document).off({
341                                mousemove: this.mousemove,
342                                mouseup: this.mouseup
343                        });
344                        return false;
345                }
346        }
347
348        $.fn.colorpicker = function ( option, val ) {
349                return this.each(function () {
350                        var $this = $(this),
351                                data = $this.data('colorpicker'),
352                                options = typeof option === 'object' && option;
353                        if (!data) {
354                                $this.data('colorpicker', (data = new Colorpicker(this, $.extend({}, $.fn.colorpicker.defaults,options))));
355                        }
356                        if (typeof option === 'string') data[option](val);
357                });
358        };
359
360        $.fn.colorpicker.defaults = {
361        };
362       
363        $.fn.colorpicker.Constructor = Colorpicker;
364       
365        var CPGlobal = {
366       
367                // translate a format from Color object to a string
368                translateFormats: {
369                        'rgb': function(){
370                                var rgb = this.color.toRGB();
371                                return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
372                        },
373                       
374                        'rgba': function(){
375                                var rgb = this.color.toRGB();
376                                return 'rgba('+rgb.r+','+rgb.g+','+rgb.b+','+rgb.a+')';
377                        },
378                       
379                        'hsl': function(){
380                                var hsl = this.color.toHSL();
381                                return 'hsl('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%)';
382                        },
383                       
384                        'hsla': function(){
385                                var hsl = this.color.toHSL();
386                                return 'hsla('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%,'+hsl.a+')';
387                        },
388                       
389                        'hex': function(){
390                                return  this.color.toHex();
391                        }
392                },
393               
394                sliders: {
395                        saturation: {
396                                maxLeft: 100,
397                                maxTop: 100,
398                                callLeft: 'setSaturation',
399                                callTop: 'setLightness'
400                        },
401                       
402                        hue: {
403                                maxLeft: 0,
404                                maxTop: 100,
405                                callLeft: false,
406                                callTop: 'setHue'
407                        },
408                       
409                        alpha: {
410                                maxLeft: 0,
411                                maxTop: 100,
412                                callLeft: false,
413                                callTop: 'setAlpha'
414                        }
415                },
416               
417                // HSBtoRGB from RaphaelJS
418                // https://github.com/DmitryBaranovskiy/raphael/
419                RGBtoHSB: function (r, g, b, a){
420                        r /= 255;
421                        g /= 255;
422                        b /= 255;
423
424                        var H, S, V, C;
425                        V = Math.max(r, g, b);
426                        C = V - Math.min(r, g, b);
427                        H = (C === 0 ? null :
428                                V == r ? (g - b) / C :
429                                V == g ? (b - r) / C + 2 :
430                                        (r - g) / C + 4
431                                );
432                        H = ((H + 360) % 6) * 60 / 360;
433                        S = C === 0 ? 0 : C / V;
434                        return {h: H||1, s: S, b: V, a: a||1};
435                },
436               
437                HueToRGB: function (p, q, h) {
438                        if (h < 0)
439                                h += 1;
440                        else if (h > 1)
441                                h -= 1;
442
443                        if ((h * 6) < 1)
444                                return p + (q - p) * h * 6;
445                        else if ((h * 2) < 1)
446                                return q;
447                        else if ((h * 3) < 2)
448                                return p + (q - p) * ((2 / 3) - h) * 6;
449                        else
450                                return p;
451                },
452       
453                HSLtoRGB: function (h, s, l, a)
454                {
455                        if (s < 0) {
456                                s = 0;
457                        }
458                        var q;
459                        if (l <= 0.5) {
460                                q = l * (1 + s);
461                        } else {
462                                q = l + s - (l * s);
463                        }
464                       
465                        var p = 2 * l - q;
466
467                        var tr = h + (1 / 3);
468                        var tg = h;
469                        var tb = h - (1 / 3);
470
471                        var r = Math.round(CPGlobal.HueToRGB(p, q, tr) * 255);
472                        var g = Math.round(CPGlobal.HueToRGB(p, q, tg) * 255);
473                        var b = Math.round(CPGlobal.HueToRGB(p, q, tb) * 255);
474                        return [r, g, b, a||1];
475                },
476               
477                // a set of RE's that can match strings and generate color tuples.
478                // from John Resig color plugin
479                // https://github.com/jquery/jquery-color/
480                stringParsers: [
481                        {
482                                re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
483                                parse: function( execResult ) {
484                                        return [
485                                                execResult[ 1 ],
486                                                execResult[ 2 ],
487                                                execResult[ 3 ],
488                                                execResult[ 4 ]
489                                        ];
490                                }
491                        }, {
492                                re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
493                                parse: function( execResult ) {
494                                        return [
495                                                2.55 * execResult[1],
496                                                2.55 * execResult[2],
497                                                2.55 * execResult[3],
498                                                execResult[ 4 ]
499                                        ];
500                                }
501                        }, {
502                                re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
503                                parse: function( execResult ) {
504                                        return [
505                                                parseInt( execResult[ 1 ], 16 ),
506                                                parseInt( execResult[ 2 ], 16 ),
507                                                parseInt( execResult[ 3 ], 16 )
508                                        ];
509                                }
510                        }, {
511                                re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
512                                parse: function( execResult ) {
513                                        return [
514                                                parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
515                                                parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
516                                                parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
517                                        ];
518                                }
519                        }, {
520                                re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
521                                space: 'hsla',
522                                parse: function( execResult ) {
523                                        return [
524                                                execResult[1]/360,
525                                                execResult[2] / 100,
526                                                execResult[3] / 100,
527                                                execResult[4]
528                                        ];
529                                }
530                        }
531                ],
532                template: '<div class="colorpicker dropdown-menu">'+
533                                                        '<div class="colorpicker-saturation"><i><b></b></i></div>'+
534                                                        '<div class="colorpicker-hue"><i></i></div>'+
535                                                        '<div class="colorpicker-alpha"><i></i></div>'+
536                                                        '<div class="colorpicker-color"><div /></div>'+
537                                                '</div>'
538        };
539
540}( window.jQuery )
Note: See TracBrowser for help on using the repository browser.