0

Edit: Posting Solution

I wanted to create color swatches based on the color chosen in Farbtastic. I did my calculations on the HSL value, because it's easier and produces better results.

After getting the HSL value from Farbtastic, I added brightness to create a new color. The new color is in HSL format, and I need to switch it back to RGB or Hex, in order to display it and save it for use later. Some browsers display HSL, but I have no faith that all mobile browsers etc will do so.

The problem was to convert variable 'newcolor' back to RGB or Hex, once the calculation was done.

// collect parent ids for farb
$(".farbtastic").parent().each(writeColorpanel);

function writeColorpanel (i, elem) {
    var picker = $.farbtastic(elem);  //farb object
    picker.linkTo(onColorChange); //a farb function
}  

    function onColorChange(color) {

    // retrieve hsl value, do calculations and place in hidden input.
    var hslcolor = $.farbtastic('#example_colorpicker_picker').hsl;

    // brighten by 40%
    var brightness = 1.4 * (Math.round(hslcolor[2]*10000)/10000);
    if (brightness>1) { brightness = 1 };
    if (brightness<0) { brightness = 0; }

    // create the new brighter color
    var newcolor = hslcolor;
    newcolor[2]=brightness;

    //convert to rgb (safer than trusting all mobile browsers to display HSL)
    var rgb = hsl2rgb(newcolor);

    //apply the color to swatches
    var firstSwatch = $('#section-example_colorpicker').find('.square1');
    firstSwatch.css( {'background-color': color } );
    var secondSwatch = $('#section-example_colorpicker').find('.square2');
    secondSwatch.css('background-color', 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')');

}

function hsl2rgb(hsl) {
    var h = hsl[0], s = hsl[1], l = hsl[2];
    var m1, m2, hue;
    var r, g, b
    h = (Math.round( 360*h )/1);
    if (s == 0)
        r = g = b = (l * 255);
    else {
        if (l <= 0.5)
            m2 = l * (s + 1);
        else
            m2 = l + s - l * s;
        m1 = l * 2 - m2;
        hue = h / 360;
        r = Math.round(HueToRgb(m1, m2, hue + 1/3));
        g = Math.round(HueToRgb(m1, m2, hue));
        b = Math.round(HueToRgb(m1, m2, hue - 1/3));
    }
    return {r: r, g: g, b: b};
}

function HueToRgb(m1, m2, hue) {
    var v;
    if (hue < 0)
        hue += 1;
    else if (hue > 1)
        hue -= 1;

    if (6 * hue < 1)
        v = m1 + (m2 - m1) * hue * 6;
    else if (2 * hue < 1)
        v = m2;
    else if (3 * hue < 2)
        v = m1 + (m2 - m1) * (2/3 - hue) * 6;
    else
        v = m1;

    return 255 * v;
}

Note that the script marked as answer works for whole number values. Since Farb returned fractional values, I made minor edits, posted above.

Wordpress Theme authors: If you are using Options Framework Theme for Wordpress, and want to use Farbtastic so you may use HSL values, see this Fork by Elihorn, which contains the files you need. In this set of files I needed to add "wp_enqueue_style( 'farbtastic' ); " at the line where we enqueued the script. The .JS file for farbtastic does not need to be included because WP already has it. You'll also need to enqueue Jquery, of course, probably at the top of functions.php.

For part2 of this question (an issue with duplicates), see: Return different values from function used multiple times

Community
  • 1
  • 1
Jen
  • 1,663
  • 1
  • 17
  • 34

2 Answers2

2

I decided to seperate the functions and rewrite them a little so they work properly.
Ended up with this :

function hsl2rgb(h, s, l) {
    var m1, m2, hue;
    var r, g, b
    s /=100;
    l /= 100;
    if (s == 0)
        r = g = b = (l * 255);
    else {
        if (l <= 0.5)
            m2 = l * (s + 1);
        else
            m2 = l + s - l * s;
        m1 = l * 2 - m2;
        hue = h / 360;
        r = Math.round(HueToRgb(m1, m2, hue + 1/3));
        g = Math.round(HueToRgb(m1, m2, hue));
        b = Math.round(HueToRgb(m1, m2, hue - 1/3));
    }
    return {r: r, g: g, b: b};
}

function HueToRgb(m1, m2, hue) {
    var v;
    if (hue < 0)
        hue += 1;
    else if (hue > 1)
        hue -= 1;

    if (6 * hue < 1)
        v = m1 + (m2 - m1) * hue * 6;
    else if (2 * hue < 1)
        v = m2;
    else if (3 * hue < 2)
        v = m1 + (m2 - m1) * (2/3 - hue) * 6;
    else
        v = m1;

    return 255 * v;
}

It's called by doing:

//the HSL values to use
var h = 30;
var s = 20;
var l = 70;

//call the function into a variable, returns an object rgb = {r:163, g:174, b:196}
var rgb = hsl2rgb(h, s, l);

//can now be accessed with rgb.r etc, and remember that the last two are percentages

Here's a DEMONSTRATION

If your variable newcolor is a string, you will have to do:

var colorArray = newcolor.split(','),
    h = colorArray[0],  //  0.10434092941291336
    s = colorArray[1],  //  1
    l = colorArray[2];  //  0.756

to get the HSL values into the right variables.

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Thanks Adeneo, I will give this a try! The thing might be a string. Two days on this so far, eep. – Jen Aug 03 '12 at 23:30
  • Can it work with numbers like: var h = 0.09888999543019379, s = 0.8260000610351563, l = 0.8119999999999999 ? What to change to get hue right? – Jen Aug 04 '12 at 00:12
  • It should work with those values, but that would give you something very close to black I think ? – adeneo Aug 04 '12 at 00:32
  • Yes, but what I meant to say is that Farbtastic returns its percents as fractional values. So .5 luminosity equals your 50. I hung up a bit on the hue. I think I could solve it when I'm less tired ... maybe. You've given me the tools I need to finish it, I think. :) – Jen Aug 04 '12 at 01:46
  • Minor edits done and posted solution. Great job fixing this Adeneo, thanks so much. – Jen Aug 04 '12 at 15:57
0

Michael Jackson has this conversion, along with other colour conversions, in JavaScript, on his site.

function hslToRgb(h, s, l) {
    var r, g, b;

    if (s == 0) {
        r = g = b = l; // achromatic
    } else {
        function hue2rgb(p, q, t) {
            if (t < 0) t += 1;
            if (t > 1) t -= 1;
            if (t < 1 / 6) return p + (q - p) * 6 * t;
            if (t < 1 / 2) return q;
            if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
            return p;
        }

        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = hue2rgb(p, q, h + 1 / 3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1 / 3);
    }

    return [r * 255, g * 255, b * 255];
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
dommer
  • 19,610
  • 14
  • 75
  • 137
  • I also tried that, but I don't know what to write in the first function to call it. I thought there would be a built-in function in Farbtastic. – Jen Aug 03 '12 at 22:35
  • I believe Michael Jackson is dead, so I don't really think he "has" much of anything anymore, and joking about his color after his death is not OK. Anyways, I added the code to your answer, as we don't really know how long that site will be up now that he's gone. Pun intended (of course), I know it's not the same dude, +1 for finding a function that should work. – adeneo Aug 03 '12 at 22:35
  • newcolor = hslToRgb(newcolor) Just returns NaN. The output textfield shows newcolor just fine, so that shouldn't be the issue. Similar function is in Farbtastic, but I can't figure out how to call that either. – Jen Aug 03 '12 at 22:50
  • The textfield to display newcolor shows "0.10434092941291336,1,0.756". If I paste that number in, then the function hslToRgb works, but when I enter the variable newcolor, it ceases to work. – Jen Aug 03 '12 at 23:13