#

Jump to Table of Contents

# Example: HSL Color Picker

Use the HSL color picker to select a new color. Then chose the color type you like best.

Saturation:
Luminance:
Hexadecimal:
RGB:
HSL:

### Setting Up the HSL Picker UI

This example takes advantage of the `dial` and `slider` widgets. We will use the dial widget to represent and select the hue from the 360 degree color wheel.

Next we will use two sliders to select the saturation and luminance.

    <!-- HSL Color Picker -->
    <div class="picker">
        <div id="hue-dial"></div>
        <div class="sliders">
            <div id="sat-slider"><strong>Saturation: <span></span></strong></div>
            <div id="lum-slider"><strong>Luminance: <span></span></strong></div>
        </div>
        <div class="color"></div>
    </div>

    <!-- Picker Output -->
    <div class="yui3-g picker-output">
        <div class="yui3-u-1-3">
            <strong>Hexadecimal:</strong>
            <input type="text" id="hex-output">
        </div>
        <div class="yui3-u-1-3">
            <strong>RGB:</strong>
            <input type="text" id="rgb-output">
        </div>
        <div class="yui3-u-1-3">
            <strong>HSL:</strong>
            <input type="text" id="hsl-output">
        </div>
    </div>

This layout could use some CSS TLC, so let's get to that next.

    /** HSL Color Picker **/
    .picker {
        padding: 15px;
        background: #efefef;
        border: 1px solid #ddd;
    }

    #hue-dial, .sliders, .color {
        display: inline-block;
        zoom: 1; *display: inline;
        vertical-align: middle;
    }

    #hue-dial .yui3-dial-ring {
        background: url(../assets/color/colorwheel.png) -25px -25px no-repeat;
    }

    .sliders {
        margin: 0 30px;
    }

    .sliders strong {
        font-weight: 600;
        display: block;
    }
    .sliders strong span {
        font-weight: 300;
    }
    .sliders div + div {
        margin-top: 1em;
    }

    .color {
        width: 100px;
        height: 100px;
        border: 1px solid rgba(0, 0, 0, 0.5);
        -webkit-box-shadow: 1px 1px 2px 0px rgba(0, 0, 0, 0.3);
        -moz-box-shadow: 1px 1px 2px 0px rgba(0, 0, 0, 0.3);
        box-shadow: 1px 1px 2px 0px rgba(0, 0, 0, 0.3);
    }

    /** Output Styles **/
    .picker-output {
        padding: 20px 10px 10px;
        background: #efefef;
        border: 1px solid #ddd;
        border-top: none;
        -webkit-box-shadow: inset 0px 6px 10px -5px rgba(0, 0, 0, 0.3);
        -moz-box-shadow: inset 0px 6px 10px -5px rgba(0, 0, 0, 0.3);
        box-shadow: inset 0px 6px 10px -5px rgba(0, 0, 0, 0.3);
    }

    .picker-output strong {
        font-weight: bold;
        display: block;
    }

### Setting Up the YUI Instance

Now we need to create our YUI instance and tell it to load the `color`, `slider`, `dial` and `event-valuechange` modules.

    YUI().use('dial', 'slider', 'event-valuechange', 'color', function (Y) {
        // Code Here.
    });

#### Building The Color Picker

##### Initializing UI Variables

First things first, we need to make sure our picker UI has the sam skin class applied.

Next, we create a dial for the hue from 0 to 360. Then create a slider from 0 to 100 for saturation and luminance.

We also want to maintain a reference to the nodes where the saturation and luminance value can be read and the color swatch that will be updated from the UI.

    Y.one('.picker').addClass('yui3-skin-sam');

    var hue = new Y.Dial({
            min: 0,
            max: 360,
            stepsPerRevolution: 360,
            continuous: true,
            centerButtonDiameter: 0.4,
            render: '#hue-dial'
        }),
        sat = new Y.Slider({
            min: 0,
            max: 100,
            value: 100,
            render: '#sat-slider'
        }),
        lum = new Y.Slider({
            min: 0,
            max: 100,
            value: 50,
            render: '#lum-slider'
        }),
        satValue = Y.one('#sat-slider span'),
        lumValue = Y.one('#lum-slider span'),
        color = Y.one('.color');

##### Binding Events

After the UI components are initialized, we need to bind their respective change methods to update the UI. For dial, this is `valueChange`. For a slider, we use `thumbMove`.

    hue.after('valueChange', function(e) {
        updatePickerUI();
    });

    sat.after('thumbMove', function(e) {
        updatePickerUI();
    });

    lum.after('thumbMove', function(e) {
        lumValue.set('text', lum.get('value') + '%');
        updatePickerUI();
    });

##### Useful Functions

Finally, we create two methods: `setPickerUI` and `updatePickerUI`.

`setPickerUI` will allow us to send an Object with `h`, `s` and `l` values to update the UI positions.

`updatePickerUI` will process the values for hue, saturation and luminance and update the color swatch. `updatePickerUI` will also call `updateOutput` that we will define next.

    function setPickerUI(hsl) {
        if (typeof hsl.h !== 'undefined') {
            hue.set('value', +hsl.h);
        }

        if (typeof hsl.s !== 'undefined') {
            sat.set('value', +hsl.s);
        }

        if (typeof hsl.l !== 'undefined') {
            lum.set('value', +hsl.l);
        }
    }

    function updatePickerUI() {
        var h = hue.get('value'),
            s = sat.get('value'),
            l = lum.get('value'),
            hslString = Y.Color.fromArray([h, s, l], Y.Color.TYPES.HSL);

        satValue.set('text', s + '%');
        lumValue.set('text', l + '%');

        color.setStyle('backgroundColor', hslString);

        updateOutput(hslString);
    }

#### Building The Picker's Output

##### Initializing Output Variables

    var hexOutput = Y.one('#hex-output'),
        rgbOutput = Y.one('#rgb-output'),
        hslOutput = Y.one('#hsl-output'),
        focused = null;

##### Binding Output UI

    hexOutput.on('focus', setFocused);
    hexOutput.on('blur', unsetFocused);
    hexOutput.on('valueChange', updatePickerFromValue);

    rgbOutput.on('focus', setFocused);
    rgbOutput.on('blur', unsetFocused);
    rgbOutput.on('valueChange', updatePickerFromValue);

    hslOutput.on('focus', setFocused);
    hslOutput.on('blur', unsetFocused);
    hslOutput.on('valueChange', updatePickerFromValue);

##### Ouput Functions

    function updateOutput(hslString) {
        if (hexOutput !== focused) {
            hexOutput.set('value', Y.Color.toHex(hslString));
        }
        if (rgbOutput !== focused) {
            rgbOutput.set('value', Y.Color.toRGB(hslString));
        }
        if (hslOutput !== focused) {
            hslOutput.set('value', hslString);
        }
    }

    function updatePickerFromValue(e) {
        var val = e.newVal,
            hsl = [];

        if (Y.Color.toArray(val)) {
            hsl = Y.Color.toArray(Y.Color.toHSL(val));
            setPickerUI({
                h: hsl[0],
                s: hsl[1],
                l: hsl[2]
            });
        }
    }

    function setFocused(e) {
        focused = e.currentTarget;
    }

    function unsetFocused(e) {
        if (focused === e.currentTarget) {
            focused = null;
        }
    }

#### Get It Started

Our last step is to make sure we set the initial view of the UI when everything has loaded. We can do this by simply calling `updatePickerUI`.

    updatePickerUI();