All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wings.js.yui.colorpicker.colorpicker.js Maven / Gradle / Ivy

The newest version!
/*
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.9.0
*/
/**
 * Provides color conversion and validation utils
 * @class YAHOO.util.Color
 * @namespace YAHOO.util
 */
YAHOO.util.Color = function() {

    var ZERO     = "0",
        isArray  = YAHOO.lang.isArray,
        isNumber = YAHOO.lang.isNumber;

    return {

        /**
         * Converts 0-1 to 0-255
         * @method real2dec
         * @param n {float} the number to convert
         * @return {int} a number 0-255
         */
        real2dec: function(n) {
            return Math.min(255, Math.round(n*256));
        },

        /**
         * Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]
         * @method hsv2rgb
         * @param h {int|[int, float, float]} the hue, or an
         *        array containing all three parameters
         * @param s {float} the saturation
         * @param v {float} the value/brightness
         * @return {[int, int, int]} the red, green, blue values in
         *          decimal.
         */
        hsv2rgb: function(h, s, v) { 

            if (isArray(h)) {
                return this.hsv2rgb.call(this, h[0], h[1], h[2]);
            }

            var r, g, b,
                i = Math.floor((h/60)%6),
                f = (h/60)-i,
                p = v*(1-s),
                q = v*(1-f*s),
                t = v*(1-(1-f)*s),
                fn;

            switch (i) {
                case 0: r=v; g=t; b=p; break;
                case 1: r=q; g=v; b=p; break;
                case 2: r=p; g=v; b=t; break;
                case 3: r=p; g=q; b=v; break;
                case 4: r=t; g=p; b=v; break;
                case 5: r=v; g=p; b=q; break;
            }

            fn=this.real2dec;

            return [fn(r), fn(g), fn(b)];
        },

        /**
         * Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]
         * @method rgb2hsv
         * @param r {int|[int, int, int]} the red value, or an
         *        array containing all three parameters
         * @param g {int} the green value
         * @param b {int} the blue value
         * @return {[int, float, float]} the value converted to hsv
         */
        rgb2hsv: function(r, g, b) {

            if (isArray(r)) {
                return this.rgb2hsv.apply(this, r);
            }

            r /= 255;
            g /= 255;
            b /= 255;

            var h,s,
                min = Math.min(Math.min(r,g),b),
                max = Math.max(Math.max(r,g),b),
                delta = max-min,
                hsv;

            switch (max) {
                case min: h=0; break;
                case r:   h=60*(g-b)/delta; 
                          if (g FFFFFF
         * @method rgb2hex
         * @param r {int|[int, int, int]} the red value, or an
         *        array containing all three parameters
         * @param g {int} the green value
         * @param b {int} the blue value
         * @return {string} the hex string
         */
        rgb2hex: function(r, g, b) {
            if (isArray(r)) {
                return this.rgb2hex.apply(this, r);
            }

            var f=this.dec2hex;
            return f(r) + f(g) + f(b);
        },
     
        /**
         * Converts an int 0...255 to hex pair 00...FF
         * @method dec2hex
         * @param n {int} the number to convert
         * @return {string} the hex equivalent
         */
        dec2hex: function(n) {
            n = parseInt(n,10)|0;
            n = (n > 255 || n < 0) ? 0 : n;

            return (ZERO+n.toString(16)).slice(-2).toUpperCase();
        },

        /**
         * Converts a hex pair 00...FF to an int 0...255 
         * @method hex2dec
         * @param str {string} the hex pair to convert
         * @return {int} the decimal
         */
        hex2dec: function(str) {
            return parseInt(str,16);
        },

        /**
         * Converts a hex string to rgb
         * @method hex2rgb
         * @param str {string} the hex string
         * @return {[int, int, int]} an array containing the rgb values
         */
        hex2rgb: function(s) { 
            var f = this.hex2dec;
            return [f(s.slice(0, 2)), f(s.slice(2, 4)), f(s.slice(4, 6))];
        },

        /**
         * Returns the closest websafe color to the supplied rgb value.
         * @method websafe
         * @param r {int|[int, int, int]} the red value, or an
         *        array containing all three parameters
         * @param g {int} the green value
         * @param b {int} the blue value
         * @return {[int, int, int]} an array containing the closes
         *                           websafe rgb colors.
         */
        websafe: function(r, g, b) {

            if (isArray(r)) {
                return this.websafe.apply(this, r);
            }

            // returns the closest match [0, 51, 102, 153, 204, 255]
            var f = function(v) {
                if (isNumber(v)) {
                    v = Math.min(Math.max(0, v), 255);
                    var i, next;
                    for (i=0; i<256; i=i+51) {
                        next = i+51;
                        if (v >= i && v <= next) {
                            return (v-i > 25) ? next : i;
                        }
                    }
                }

                return v;
            };

            return [f(r), f(g), f(b)];
        }
    };
}();


/**
 * The colorpicker module provides a widget for selecting colors
 * @module colorpicker
 * @requires yahoo, dom, event, element, slider
 */
(function() {

    var _pickercount = 0,
        util   = YAHOO.util,
        lang   = YAHOO.lang,
        Slider = YAHOO.widget.Slider,
        Color  = util.Color,
        Dom    = util.Dom,
        Event  = util.Event,
        sub    = lang.substitute,
        
        b = "yui-picker";
    

    /**
     * A widget to select colors
     * @namespace YAHOO.widget
     * @class YAHOO.widget.ColorPicker
     * @extends YAHOO.util.Element
     * @constructor
     * @param {HTMLElement | String | Object} el(optional) The html 
     * element that represents the colorpicker, or the attribute object to use. 
     * An element will be created if none provided.
     * @param {Object} attr (optional) A key map of the colorpicker's 
     * initial attributes.  Ignored if first arg is attributes object.
     */
    function ColorPicker(el, attr) {
        _pickercount = _pickercount + 1;
        attr = attr || {};
        if (arguments.length === 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
            attr = el; // treat first arg as attr object
            el = attr.element || null;
        }
        
        if (!el && !attr.element) { // create if we dont have one
            el = this._createHostElement(attr);
        }

        ColorPicker.superclass.constructor.call(this, el, attr); 

        this.initPicker();
    }

    YAHOO.extend(ColorPicker, YAHOO.util.Element, {
    
        /**
         * The element ids used by this control
         * @property ID
         * @final
         */
        ID : {

            /**
             * The id for the "red" form field
             * @property ID.R
             * @type String
             * @final
             * @default yui-picker-r
             */
            R: b + "-r",

            /**
             * The id for the "red" hex pair output
             * @property ID.R_HEX
             * @type String
             * @final
             * @default yui-picker-rhex
             */
            R_HEX: b + "-rhex",

            /**
             * The id for the "green" form field
             * @property ID.G
             * @type String
             * @final
             * @default yui-picker-g
             */
            G: b + "-g",

            /**
             * The id for the "green" hex pair output
             * @property ID.G_HEX
             * @type String
             * @final
             * @default yui-picker-ghex
             */
            G_HEX: b + "-ghex",


            /**
             * The id for the "blue" form field
             * @property ID.B
             * @type String
             * @final
             * @default yui-picker-b
             */
            B: b + "-b",

            /**
             * The id for the "blue" hex pair output
             * @property ID.B_HEX
             * @type String
             * @final
             * @default yui-picker-bhex
             */
            B_HEX: b + "-bhex",

            /**
             * The id for the "hue" form field
             * @property ID.H
             * @type String
             * @final
             * @default yui-picker-h
             */
            H: b + "-h",

            /**
             * The id for the "saturation" form field
             * @property ID.S
             * @type String
             * @final
             * @default yui-picker-s
             */
            S: b + "-s",

            /**
             * The id for the "value" form field
             * @property ID.V
             * @type String
             * @final
             * @default yui-picker-v
             */
            V: b + "-v",

            /**
             * The id for the picker region slider
             * @property ID.PICKER_BG
             * @type String
             * @final
             * @default yui-picker-bg
             */
            PICKER_BG:      b + "-bg",

            /**
             * The id for the picker region thumb
             * @property ID.PICKER_THUMB
             * @type String
             * @final
             * @default yui-picker-thumb
             */
            PICKER_THUMB:   b + "-thumb",

            /**
             * The id for the hue slider
             * @property ID.HUE_BG
             * @type String
             * @final
             * @default yui-picker-hue-bg
             */
            HUE_BG:         b + "-hue-bg",

            /**
             * The id for the hue thumb
             * @property ID.HUE_THUMB
             * @type String
             * @final
             * @default yui-picker-hue-thumb
             */
            HUE_THUMB:      b + "-hue-thumb",

            /**
             * The id for the hex value form field
             * @property ID.HEX
             * @type String
             * @final
             * @default yui-picker-hex
             */
            HEX:            b + "-hex",

            /**
             * The id for the color swatch
             * @property ID.SWATCH
             * @type String
             * @final
             * @default yui-picker-swatch
             */
            SWATCH:         b + "-swatch",

            /**
             * The id for the websafe color swatch
             * @property ID.WEBSAFE_SWATCH
             * @type String
             * @final
             * @default yui-picker-websafe-swatch
             */
            WEBSAFE_SWATCH: b + "-websafe-swatch",

            /**
             * The id for the control details
             * @property ID.CONTROLS
             * @final
             * @default yui-picker-controls
             */
            CONTROLS: b + "-controls",

            /**
             * The id for the rgb controls
             * @property ID.RGB_CONTROLS
             * @final
             * @default yui-picker-rgb-controls
             */
            RGB_CONTROLS: b + "-rgb-controls",

            /**
             * The id for the hsv controls
             * @property ID.HSV_CONTROLS
             * @final
             * @default yui-picker-hsv-controls
             */
            HSV_CONTROLS: b + "-hsv-controls",
            
            /**
             * The id for the hsv controls
             * @property ID.HEX_CONTROLS
             * @final
             * @default yui-picker-hex-controls
             */
            HEX_CONTROLS: b + "-hex-controls",

            /**
             * The id for the hex summary
             * @property ID.HEX_SUMMARY
             * @final
             * @default yui-picker-hex-summary
             */
            HEX_SUMMARY: b + "-hex-summary",

            /**
             * The id for the controls section header
             * @property ID.CONTROLS_LABEL
             * @final
             * @default yui-picker-controls-label
             */
            CONTROLS_LABEL: b + "-controls-label"
        },

        /**
         * Constants for any script-generated messages.  The values here
         * are the default messages.  They can be updated by providing
         * the complete list to the constructor for the "txt" attribute.
         * Note: the strings are added to the DOM as HTML.
         * @property TXT
         * @final
         */
        TXT : {
            ILLEGAL_HEX: "Illegal hex value entered",
            SHOW_CONTROLS: "Show color details",
            HIDE_CONTROLS: "Hide color details",
            CURRENT_COLOR: "Currently selected color: {rgb}",
            CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.",
            R: "R",
            G: "G",
            B: "B",
            H: "H",
            S: "S",
            V: "V",
            HEX: "#",
            DEG: "\u00B0",
            PERCENT: "%"
        },

        /**
         * Constants for the default image locations for img tags that are
         * generated by the control.  They can be modified by passing the
         * complete list to the contructor for the "images" attribute
         * @property IMAGE
         * @final
         */
        IMAGE : {
            PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png",
            HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png"
        },

        /**
         * Constants for the control's default default values
         * @property DEFAULT
         * @final
         */
        DEFAULT : {
            PICKER_SIZE: 180
        },

        /**
         * Constants for the control's configuration attributes
         * @property OPT
         * @final
         */
        OPT : {
            HUE         : "hue",
            SATURATION  : "saturation",
            VALUE       : "value",
            RED     : "red",
            GREEN   : "green",
            BLUE    : "blue",
            HSV     : "hsv",
            RGB     : "rgb",
            WEBSAFE : "websafe",
            HEX     : "hex",
            PICKER_SIZE       : "pickersize",
            SHOW_CONTROLS     : "showcontrols",
            SHOW_RGB_CONTROLS : "showrgbcontrols",
            SHOW_HSV_CONTROLS : "showhsvcontrols",
            SHOW_HEX_CONTROLS : "showhexcontrols",
            SHOW_HEX_SUMMARY  : "showhexsummary",
            SHOW_WEBSAFE      : "showwebsafe",
            CONTAINER         : "container",
            IDS      : "ids",
            ELEMENTS : "elements",
            TXT      : "txt",
            IMAGES   : "images",
            ANIMATE  : "animate"
        },

        /**
         * Flag to allow individual UI updates to forego animation if available.
         * True during construction for initial thumb placement.  Set to false
         * after that.
         *
         * @property skipAnim
         * @type Boolean
         * @default true
         */
        skipAnim : true,

        /**
         * Creates the host element if it doesn't exist
         * @method _createHostElement
         * @protected
         */
        _createHostElement : function () {
            var el = document.createElement('div');

            if (this.CSS.BASE) {
                el.className = this.CSS.BASE;
            }
            
            return el;
        },

        /**
         * Moves the hue slider into the position dictated by the current state
         * of the control
         * @method _updateHueSlider
         * @protected
         */
        _updateHueSlider : function() {
            var size = this.get(this.OPT.PICKER_SIZE),
                h = this.get(this.OPT.HUE);

            h = size - Math.round(h / 360 * size);
            
            // 0 is at the top and bottom of the hue slider.  Always go to
            // the top so we don't end up sending the thumb to the bottom
            // when the value didn't actually change (e.g., a conversion
            // produced 360 instead of 0 and the value was already 0).
            if (h === size) {
                h = 0;
            }

            this.hueSlider.setValue(h, this.skipAnim);
        },

        /**
         * Moves the picker slider into the position dictated by the current state
         * of the control
         * @method _updatePickerSlider
         * @protected
         */
        _updatePickerSlider : function() {
            var size = this.get(this.OPT.PICKER_SIZE),
                s = this.get(this.OPT.SATURATION),
                v = this.get(this.OPT.VALUE);

            s = Math.round(s * size / 100);
            v = Math.round(size - (v * size / 100));


            this.pickerSlider.setRegionValue(s, v, this.skipAnim);
        },

        /**
         * Moves the sliders into the position dictated by the current state
         * of the control
         * @method _updateSliders
         * @protected
         */
        _updateSliders : function() {
            this._updateHueSlider();
            this._updatePickerSlider();
        },

        /**
         * Sets the control to the specified rgb value and
         * moves the sliders to the proper positions
         * @method setValue
         * @param rgb {[int, int, int]} the rgb value
         * @param silent {boolean} whether or not to fire the change event
         */
        setValue : function(rgb, silent) {
            silent = (silent) || false;
            this.set(this.OPT.RGB, rgb, silent);
            this._updateSliders();
        },

        /**
         * The hue slider
         * @property hueSlider
         * @type YAHOO.widget.Slider
         */
        hueSlider : null,
        
        /**
         * The picker region
         * @property pickerSlider
         * @type YAHOO.widget.Slider
         */
        pickerSlider : null,

        /**
         * Translates the slider value into hue, int[0,359]
         * @method _getH
         * @protected
         * @return {int} the hue from 0 to 359
         */
        _getH : function() {
            var size = this.get(this.OPT.PICKER_SIZE),
                h = (size - this.hueSlider.getValue()) / size;
            h = Math.round(h*360);
            return (h === 360) ? 0 : h;
        },

        /**
         * Translates the slider value into saturation, int[0,1], left to right
         * @method _getS
         * @protected
         * @return {int} the saturation from 0 to 1
         */
        _getS : function() {
            return this.pickerSlider.getXValue() / this.get(this.OPT.PICKER_SIZE);
        },

        /**
         * Translates the slider value into value/brightness, int[0,1], top
         * to bottom
         * @method _getV
         * @protected
         * @return {int} the value from 0 to 1
         */
        _getV : function() {
            var size = this.get(this.OPT.PICKER_SIZE);
            return (size - this.pickerSlider.getYValue()) / size;
        },

        /**
         * Updates the background of the swatch with the current rbg value.
         * Also updates the websafe swatch to the closest websafe color
         * @method _updateSwatch
         * @protected
         */
        _updateSwatch : function() {
            var rgb = this.get(this.OPT.RGB),
                websafe = this.get(this.OPT.WEBSAFE),
                el = this.getElement(this.ID.SWATCH),
                color = rgb.join(","),
                txt = this.get(this.OPT.TXT);

            Dom.setStyle(el, "background-color", "rgb(" + color  + ")");
            el.title = sub(txt.CURRENT_COLOR, {
                    "rgb": "#" + this.get(this.OPT.HEX)
                });


            el = this.getElement(this.ID.WEBSAFE_SWATCH);
            color = websafe.join(",");

            Dom.setStyle(el, "background-color", "rgb(" + color + ")");
            el.title = sub(txt.CLOSEST_WEBSAFE, {
                    "rgb": "#" + Color.rgb2hex(websafe)
                });

        },

        /**
         * Reads the sliders and converts the values to RGB, updating the
         * internal state for all the individual form fields
         * @method _getValuesFromSliders
         * @protected
         */
        _getValuesFromSliders : function() {
            this.set(this.OPT.RGB, Color.hsv2rgb(this._getH(), this._getS(), this._getV()));
        },

        /**
         * Updates the form field controls with the state data contained
         * in the control.
         * @method _updateFormFields
         * @protected
         */
        _updateFormFields : function() {
            this.getElement(this.ID.H).value = this.get(this.OPT.HUE);
            this.getElement(this.ID.S).value = this.get(this.OPT.SATURATION);
            this.getElement(this.ID.V).value = this.get(this.OPT.VALUE);
            this.getElement(this.ID.R).value = this.get(this.OPT.RED);
            this.getElement(this.ID.R_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.RED));
            this.getElement(this.ID.G).value = this.get(this.OPT.GREEN);
            this.getElement(this.ID.G_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.GREEN));
            this.getElement(this.ID.B).value = this.get(this.OPT.BLUE);
            this.getElement(this.ID.B_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.BLUE));
            this.getElement(this.ID.HEX).value = this.get(this.OPT.HEX);
        },

        /**
         * Event handler for the hue slider.
         * @method _onHueSliderChange
         * @param newOffset {int} pixels from the start position
         * @protected
         */
        _onHueSliderChange : function(newOffset) {

            var h        = this._getH(),
                rgb      = Color.hsv2rgb(h, 1, 1),
                styleDef = "rgb(" + rgb.join(",") + ")";

            this.set(this.OPT.HUE, h, true);

            // set picker background to the hue
            Dom.setStyle(this.getElement(this.ID.PICKER_BG), "background-color", styleDef);

            if (this.hueSlider.valueChangeSource !== Slider.SOURCE_SET_VALUE) {
                this._getValuesFromSliders();
            }

            this._updateFormFields();
            this._updateSwatch();
        },

        /**
         * Event handler for the picker slider, which controls the
         * saturation and value/brightness.
         * @method _onPickerSliderChange
         * @param newOffset {{x: int, y: int}} x/y pixels from the start position
         * @protected
         */
        _onPickerSliderChange : function(newOffset) {

            var s=this._getS(), v=this._getV();
            this.set(this.OPT.SATURATION, Math.round(s*100), true);
            this.set(this.OPT.VALUE, Math.round(v*100), true);

            if (this.pickerSlider.valueChangeSource !== Slider.SOURCE_SET_VALUE) {
                this._getValuesFromSliders();
            }

            this._updateFormFields();
            this._updateSwatch();
        },


        /**
         * Key map to well-known commands for txt field input
         * @method _getCommand
         * @param e {Event} the keypress or keydown event
         * @return {int} a command code
         * 
    *
  • 0 = not a number, letter in range, or special key
  • *
  • 1 = number
  • *
  • 2 = a-fA-F
  • *
  • 3 = increment (up arrow)
  • *
  • 4 = decrement (down arrow)
  • *
  • 5 = special key (tab, delete, return, escape, left, right)
  • *
  • 6 = return
  • *
* @protected */ _getCommand : function(e) { var c = Event.getCharCode(e); //alert(Event.getCharCode(e) + ", " + e.keyCode + ", " + e.charCode); // special keys if (c === 38) { // up arrow return 3; } else if (c === 13) { // return return 6; } else if (c === 40) { // down array return 4; } else if (c >= 48 && c<=57) { // 0-9 return 1; } else if (c >= 97 && c<=102) { // a-f return 2; } else if (c >= 65 && c<=70) { // A-F return 2; //} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 || // (c >= 112 && c <=123)) { // including F-keys // tab, delete, return, escape, left, right or ctrl/meta sequences } else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 || e.ctrlKey || e.metaKey) { // special chars return 5; } else { // something we probably don't want return 0; } }, /** * Use the value of the text field to update the control * @method _useFieldValue * @param e {Event} an event * @param el {HTMLElement} the field * @param prop {string} the key to the linked property * @protected */ _useFieldValue : function(e, el, prop) { var val = el.value; if (prop !== this.OPT.HEX) { val = parseInt(val, 10); } if (val !== this.get(prop)) { this.set(prop, val); } }, /** * Handle keypress on one of the rgb or hsv fields. * @method _rgbFieldKeypress * @param e {Event} the keypress event * @param el {HTMLElement} the field * @param prop {string} the key to the linked property * @protected */ _rgbFieldKeypress : function(e, el, prop) { var command = this._getCommand(e), inc = (e.shiftKey) ? 10 : 1; switch (command) { case 6: // return, update the value this._useFieldValue.apply(this, arguments); break; case 3: // up arrow, increment this.set(prop, Math.min(this.get(prop)+inc, 255)); this._updateFormFields(); //Event.stopEvent(e); break; case 4: // down arrow, decrement this.set(prop, Math.max(this.get(prop)-inc, 0)); this._updateFormFields(); //Event.stopEvent(e); break; default: } }, /** * Handle keydown on the hex field * @method _hexFieldKeypress * @param e {Event} the keypress event * @param el {HTMLElement} the field * @param prop {string} the key to the linked property * @protected */ _hexFieldKeypress : function(e, el, prop) { var command = this._getCommand(e); if (command === 6) { // return, update the value this._useFieldValue.apply(this, arguments); } }, /** * Allows numbers and special chars, and by default allows a-f. * Used for the hex field keypress handler. * @method _hexOnly * @param e {Event} the event * @param numbersOnly omits a-f if set to true * @protected * @return {boolean} false if we are canceling the event */ _hexOnly : function(e, numbersOnly) { var command = this._getCommand(e); switch (command) { case 6: // return case 5: // special char case 1: // number break; case 2: // hex char (a-f) if (numbersOnly !== true) { break; } // fallthrough is intentional default: // prevent alpha and punctuation Event.stopEvent(e); return false; } }, /** * Allows numbers and special chars only. Used for the * rgb and hsv fields keypress handler. * @method _numbersOnly * @param e {Event} the event * @protected * @return {boolean} false if we are canceling the event */ _numbersOnly : function(e) { return this._hexOnly(e, true); }, /** * Returns the element reference that is saved. The id can be either * the element id, or the key for this id in the "id" config attribute. * For instance, the host element id can be obtained by passing its * id (default: "yui_picker") or by its key "YUI_PICKER". * @param id {string} the element id, or key * @return {HTMLElement} a reference to the element */ getElement : function(id) { return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[id]]; }, _createElements : function() { var el, child, img, fld, p, ids = this.get(this.OPT.IDS), txt = this.get(this.OPT.TXT), images = this.get(this.OPT.IMAGES), Elem = function(type, o) { var n = document.createElement(type); if (o) { lang.augmentObject(n, o, true); } return n; }, RGBElem = function(type, obj) { var o = lang.merge({ //type: "txt", autocomplete: "off", value: "0", size: 3, maxlength: 3 }, obj); o.name = o.id; return new Elem(type, o); }; p = this.get("element"); // Picker slider (S and V) --------------------------------------------- el = new Elem("div", { id: ids[this.ID.PICKER_BG], className: "yui-picker-bg", tabIndex: -1, hideFocus: true }); child = new Elem("div", { id: ids[this.ID.PICKER_THUMB], className: "yui-picker-thumb" }); img = new Elem("img", { src: images.PICKER_THUMB }); child.appendChild(img); el.appendChild(child); p.appendChild(el); // Hue slider --------------------------------------------- el = new Elem("div", { id: ids[this.ID.HUE_BG], className: "yui-picker-hue-bg", tabIndex: -1, hideFocus: true }); child = new Elem("div", { id: ids[this.ID.HUE_THUMB], className: "yui-picker-hue-thumb" }); img = new Elem("img", { src: images.HUE_THUMB }); child.appendChild(img); el.appendChild(child); p.appendChild(el); // controls --------------------------------------------- el = new Elem("div", { id: ids[this.ID.CONTROLS], className: "yui-picker-controls" }); p.appendChild(el); p = el; // controls header el = new Elem("div", { className: "hd" }); child = new Elem("a", { id: ids[this.ID.CONTROLS_LABEL], //className: "yui-picker-controls-label", href: "#" }); el.appendChild(child); p.appendChild(el); // bd el = new Elem("div", { className: "bd" }); p.appendChild(el); p = el; // rgb el = new Elem("ul", { id: ids[this.ID.RGB_CONTROLS], className: "yui-picker-rgb-controls" }); child = new Elem("li"); child.appendChild(document.createTextNode(txt.R + " ")); fld = new RGBElem("input", { id: ids[this.ID.R], className: "yui-picker-r" }); child.appendChild(fld); el.appendChild(child); child = new Elem("li"); child.appendChild(document.createTextNode(txt.G + " ")); fld = new RGBElem("input", { id: ids[this.ID.G], className: "yui-picker-g" }); child.appendChild(fld); el.appendChild(child); child = new Elem("li"); child.appendChild(document.createTextNode(txt.B + " ")); fld = new RGBElem("input", { id: ids[this.ID.B], className: "yui-picker-b" }); child.appendChild(fld); el.appendChild(child); p.appendChild(el); // hsv el = new Elem("ul", { id: ids[this.ID.HSV_CONTROLS], className: "yui-picker-hsv-controls" }); child = new Elem("li"); child.appendChild(document.createTextNode(txt.H + " ")); fld = new RGBElem("input", { id: ids[this.ID.H], className: "yui-picker-h" }); child.appendChild(fld); child.appendChild(document.createTextNode(" " + txt.DEG)); el.appendChild(child); child = new Elem("li"); child.appendChild(document.createTextNode(txt.S + " ")); fld = new RGBElem("input", { id: ids[this.ID.S], className: "yui-picker-s" }); child.appendChild(fld); child.appendChild(document.createTextNode(" " + txt.PERCENT)); el.appendChild(child); child = new Elem("li"); child.appendChild(document.createTextNode(txt.V + " ")); fld = new RGBElem("input", { id: ids[this.ID.V], className: "yui-picker-v" }); child.appendChild(fld); child.appendChild(document.createTextNode(" " + txt.PERCENT)); el.appendChild(child); p.appendChild(el); // hex summary el = new Elem("ul", { id: ids[this.ID.HEX_SUMMARY], className: "yui-picker-hex_summary" }); child = new Elem("li", { id: ids[this.ID.R_HEX] }); el.appendChild(child); child = new Elem("li", { id: ids[this.ID.G_HEX] }); el.appendChild(child); child = new Elem("li", { id: ids[this.ID.B_HEX] }); el.appendChild(child); p.appendChild(el); // hex field el = new Elem("div", { id: ids[this.ID.HEX_CONTROLS], className: "yui-picker-hex-controls" }); el.appendChild(document.createTextNode(txt.HEX + " ")); child = new RGBElem("input", { id: ids[this.ID.HEX], className: "yui-picker-hex", size: 6, maxlength: 6 }); el.appendChild(child); p.appendChild(el); p = this.get("element"); // swatch el = new Elem("div", { id: ids[this.ID.SWATCH], className: "yui-picker-swatch" }); p.appendChild(el); // websafe swatch el = new Elem("div", { id: ids[this.ID.WEBSAFE_SWATCH], className: "yui-picker-websafe-swatch" }); p.appendChild(el); }, _attachRGBHSV : function(id, config) { Event.on(this.getElement(id), "keydown", function(e, me) { me._rgbFieldKeypress(e, this, config); }, this); Event.on(this.getElement(id), "keypress", this._numbersOnly, this, true); Event.on(this.getElement(id), "blur", function(e, me) { me._useFieldValue(e, this, config); }, this); }, /** * Updates the rgb attribute with the current state of the r,g,b * fields. This is invoked from change listeners on these * attributes to facilitate updating these values from the * individual form fields * @method _updateRGB * @protected */ _updateRGB : function() { var rgb = [this.get(this.OPT.RED), this.get(this.OPT.GREEN), this.get(this.OPT.BLUE)]; this.set(this.OPT.RGB, rgb); this._updateSliders(); }, /** * Creates any missing DOM structure. * * @method _initElements * @protected */ _initElements : function () { // bind all of our elements var o=this.OPT, ids = this.get(o.IDS), els = this.get(o.ELEMENTS), i, el, id; // Add the default value as a key for each element for easier lookup for (i in this.ID) { if (lang.hasOwnProperty(this.ID, i)) { ids[this.ID[i]] = ids[i]; } } // Check for picker element, if not there, create all of them el = Dom.get(ids[this.ID.PICKER_BG]); if (!el) { this._createElements(); } else { } for (i in ids) { if (lang.hasOwnProperty(ids, i)) { // look for element el = Dom.get(ids[i]); // generate an id if the implementer passed in an element reference, // and the element did not have an id already id = Dom.generateId(el); // update the id in case we generated the id ids[i] = id; // key is WEBSAFE_SWATCH ids[ids[i]] = id; // key is websafe_swatch // store the dom ref els[id] = el; } } }, /** * Sets the initial state of the sliders * @method initPicker */ initPicker : function () { this._initSliders(); this._bindUI(); this.syncUI(true); }, /** * Creates the Hue and Value/Saturation Sliders. * * @method _initSliders * @protected */ _initSliders : function () { var ID = this.ID, size = this.get(this.OPT.PICKER_SIZE); this.hueSlider = Slider.getVertSlider( this.getElement(ID.HUE_BG), this.getElement(ID.HUE_THUMB), 0, size); this.pickerSlider = Slider.getSliderRegion( this.getElement(ID.PICKER_BG), this.getElement(ID.PICKER_THUMB), 0, size, 0, size); // Apply animate attribute configuration this.set(this.OPT.ANIMATE, this.get(this.OPT.ANIMATE)); }, /** * Adds event listeners to Sliders and UI elements. Wires everything * up. * * @method _bindUI * @protected */ _bindUI : function () { var ID = this.ID, O = this.OPT; this.hueSlider.subscribe("change", this._onHueSliderChange, this, true); this.pickerSlider.subscribe("change", this._onPickerSliderChange, this, true); Event.on(this.getElement(ID.WEBSAFE_SWATCH), "click", function(e) { this.setValue(this.get(O.WEBSAFE)); }, this, true); Event.on(this.getElement(ID.CONTROLS_LABEL), "click", function(e) { this.set(O.SHOW_CONTROLS, !this.get(O.SHOW_CONTROLS)); Event.preventDefault(e); }, this, true); this._attachRGBHSV(ID.R, O.RED); this._attachRGBHSV(ID.G, O.GREEN); this._attachRGBHSV(ID.B, O.BLUE); this._attachRGBHSV(ID.H, O.HUE); this._attachRGBHSV(ID.S, O.SATURATION); this._attachRGBHSV(ID.V, O.VALUE); Event.on(this.getElement(ID.HEX), "keydown", function(e, me) { me._hexFieldKeypress(e, this, O.HEX); }, this); Event.on(this.getElement(this.ID.HEX), "keypress", this._hexOnly, this,true); Event.on(this.getElement(this.ID.HEX), "blur", function(e, me) { me._useFieldValue(e, this, O.HEX); }, this); }, /** * Wrapper for _updateRGB, but allows non-animated update * * @method syncUI * @param skipAnim {Boolean} Omit Slider animation for this action */ syncUI : function (skipAnim) { this.skipAnim = skipAnim; this._updateRGB(); this.skipAnim = false; }, /** * Updates the RGB values from the current state of the HSV * values. Executed when the one of the HSV form fields are * updated * _updateRGBFromHSV * @protected */ _updateRGBFromHSV : function() { var hsv = [this.get(this.OPT.HUE), this.get(this.OPT.SATURATION)/100, this.get(this.OPT.VALUE)/100], rgb = Color.hsv2rgb(hsv); this.set(this.OPT.RGB, rgb); this._updateSliders(); }, /** * Parses the hex string to normalize shorthand values, converts * the hex value to rgb and updates the rgb attribute (which * updates the state for all of the other values) * method _updateHex * @protected */ _updateHex : function() { var hex = this.get(this.OPT.HEX), l = hex.length, c,i,rgb; // support #369 -> #336699 shorthand if (l === 3) { c = hex.split(""); for (i=0; i 1) { for (i in ids) { if (lang.hasOwnProperty(ids, i)) { ids[i] = ids[i] + _pickercount; } } } /** * A list of element ids and/or element references used by the * control. The default is the this.ID list, and can be customized * by passing a list in the contructor * @attribute ids * @type {referenceid: realid} * @writeonce */ this.setAttributeConfig(this.OPT.IDS, { value: ids, writeonce: true }); /** * A list of txt strings for internationalization. Default * is this.TXT * @attribute txt * @type {key: txt} * @writeonce */ this.setAttributeConfig(this.OPT.TXT, { value: attr.txt || this.TXT, writeonce: true }); /** * The img src default list * is this.IMAGES * @attribute images * @type {key: image} * @writeonce */ this.setAttributeConfig(this.OPT.IMAGES, { value: attr.images || this.IMAGE, writeonce: true }); /** * The element refs used by this control. Set at initialization * @attribute elements * @type {id: HTMLElement} * @readonly */ this.setAttributeConfig(this.OPT.ELEMENTS, { value: {}, readonly: true }); /** * Hide/show the entire set of controls * @attribute showcontrols * @type boolean * @default true */ this.setAttributeConfig(this.OPT.SHOW_CONTROLS, { value: lang.isBoolean(attr.showcontrols) ? attr.showcontrols : true, method: function(on) { var el = Dom.getElementsByClassName("bd", "div", this.getElement(this.ID.CONTROLS))[0]; this._hideShowEl(el, on); this.getElement(this.ID.CONTROLS_LABEL).innerHTML = (on) ? this.get(this.OPT.TXT).HIDE_CONTROLS : this.get(this.OPT.TXT).SHOW_CONTROLS; } }); /** * Hide/show the rgb controls * @attribute showrgbcontrols * @type boolean * @default true */ this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS, { value: lang.isBoolean(attr.showrgbcontrols) ? attr.showrgbcontrols : true, method: function(on) { this._hideShowEl(this.ID.RGB_CONTROLS, on); } }); /** * Hide/show the hsv controls * @attribute showhsvcontrols * @type boolean * @default false */ this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS, { value: lang.isBoolean(attr.showhsvcontrols) ? attr.showhsvcontrols : false, method: function(on) { //Dom.setStyle(this.getElement(this.ID.HSV_CONTROLS), "visibility", (on) ? "" : "hidden"); this._hideShowEl(this.ID.HSV_CONTROLS, on); // can't show both the hsv controls and the rbg hex summary if (on && this.get(this.OPT.SHOW_HEX_SUMMARY)) { this.set(this.OPT.SHOW_HEX_SUMMARY, false); } } }); /** * Hide/show the hex controls * @attribute showhexcontrols * @type boolean * @default true */ this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS, { value: lang.isBoolean(attr.showhexcontrols) ? attr.showhexcontrols : false, method: function(on) { this._hideShowEl(this.ID.HEX_CONTROLS, on); } }); /** * Hide/show the websafe swatch * @attribute showwebsafe * @type boolean * @default true */ this.setAttributeConfig(this.OPT.SHOW_WEBSAFE, { value: lang.isBoolean(attr.showwebsafe) ? attr.showwebsafe : true, method: function(on) { this._hideShowEl(this.ID.WEBSAFE_SWATCH, on); } }); /** * Hide/show the hex summary * @attribute showhexsummary * @type boolean * @default true */ this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY, { value: lang.isBoolean(attr.showhexsummary) ? attr.showhexsummary : true, method: function(on) { this._hideShowEl(this.ID.HEX_SUMMARY, on); // can't show both the hsv controls and the rbg hex summary if (on && this.get(this.OPT.SHOW_HSV_CONTROLS)) { this.set(this.OPT.SHOW_HSV_CONTROLS, false); } } }); this.setAttributeConfig(this.OPT.ANIMATE, { value: lang.isBoolean(attr.animate) ? attr.animate : true, method: function(on) { if (this.pickerSlider) { this.pickerSlider.animate = on; this.hueSlider.animate = on; } } }); this.on(this.OPT.HUE + "Change", this._updateRGBFromHSV, this, true); this.on(this.OPT.SATURATION + "Change", this._updateRGBFromHSV, this, true); this.on(this.OPT.VALUE + "Change", this._updateRGBFromHSV, this, true); this.on(this.OPT.RED + "Change", this._updateRGB, this, true); this.on(this.OPT.GREEN + "Change", this._updateRGB, this, true); this.on(this.OPT.BLUE + "Change", this._updateRGB, this, true); this.on(this.OPT.HEX + "Change", this._updateHex, this, true); this._initElements(); } }); YAHOO.widget.ColorPicker = ColorPicker; })(); YAHOO.register("colorpicker", YAHOO.widget.ColorPicker, {version: "2.9.0", build: "2800"});




© 2015 - 2024 Weber Informatics LLC | Privacy Policy