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();