Using dat.gui Color Controller with colorMode(HSB)

Hi, I am trying to implement a color-controller GUI in a p5.js sketch. I am using this: [https://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers] It works just fine when I use colorMode(RGB). In RGB-mode, I can use the command hue() on the color object and it returns a value in the range 0-360. The way the hue() value changes when I select different colours seems to make sense (so do saturation() and brightness() ). My challenge: The code I am integrating the GUI-element into uses colorMode(HSB), so ideally I'd like to keep this as it is. But if I do, the color-controller in dat.gui no longer makes sense. If I now test varying selected colours, their respective hue() values the value moves about in unexpected ways. I realize I am probably doing something wrong. I suspect it is related to the way my colour variable is defined: this.col = [0, 0, 255]; Before sharing code-examples, I just wondered if anyone out there has experience of using dat.gui color-picker with the HSB colorMode. thanks, Richard

Answers

  • I think a code example that demonstrates your problem would be useful. From the dat.gui page it looks like you can get HSV (aka HSB) output directly:

    dat.GUI will modify colors in the format defined by their initial value.

    i.e. set initial colours in HSB and you'll presumably get HSB out...

  • Thanks for replying. OK, I'll try to share something which demonstrates the issue on Codepen. Here is an example which works, where colorMode is RGB. codepen.io/Grand-Wazoo/pen/eZLraK

  • Now I've tried to make a couple of simpler examples. This one is RGB: codepen.io/Grand-Wazoo/pen/aNaabV

  • And this one is HSB: codepen.io/Grand-Wazoo/pen/PNddZM The only difference is in the colorMode: (RGB, 255, 255, 255) is swapped with (HSB, 255, 255, 255).

  • OK so I was hoping for a simplified code example that demonstrates the problem :P

    Your description is also a little unclear: are you trying to get HSB colours out of dat.gui or RGB?

    The fact that dat.gui expects and returns HSV colours as an object and RGB as an array looks like a likely cause for confusion; but I don't get the impression that is your problem.

    I'm sure I've seen some reported issues about the p5js Color object - possibly by @GoToLoop - and I just tried doing stuff in HSB mode and saw some odd behaviour; so perhaps that's it...

    Whatever, it looks fairly straightforward to convert between colour modes; even if you have to do so 'manually':

    var gui = new dat.GUI();
    var vars = {};
    var bg;
    
    vars.colourHSV = { h: 50, s: 0.9, v: 0.3 };
    vars.colourRGB = [255, 166, 0];
    
    var p5 = new p5(function (p) {    
    
        p.setup = function () {
            p.createCanvas(600, 400);
    
            var hsv = gui.addColor(vars, 'colourHSV');
            var rgb = gui.addColor(vars, 'colourRGB');
    
            hsv.onChange(function(value) {        
                bg = HSVtoRGB(value);
            });
    
            rgb.onChange(function(value) {
                bg = value;
            });
    
            // set starting background colour
            bg = HSVtoRGB(vars.colourHSV);
        };
    
        p.draw = function() {
            p.background(bg);
        }
    
    });
    
    //adapted from: http://stackoverflow.com/questions/17242144/javascript-convert-hsb-hsv-color-to-rgb-accurately
    /* accepts parameters
     * h  Object = {h:x, s:y, v:z}
     * OR 
     * h, s, v
    */
    function HSVtoRGB(h, s, v) {
        var r, g, b, i, f, p, q, t;
        if (arguments.length === 1) {
            s = h.s, v = h.v, h = h.h;
        }
        // adjust to match p5 format
        h = h/360;
        i = Math.floor(h * 6);
        f = h * 6 - i;
        p = v * (1 - s);
        q = v * (1 - f * s);
        t = v * (1 - (1 - f) * s);
        switch (i % 6) {
            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;
        }
        // return an array for use in p5js
        return [
            Math.round(r * 255),
            Math.round(g * 255),
            Math.round(b * 255)];
    }
    
  • Thanks a lot, blindfish. I'll try to work through your reply. I am pretty new to both Processing & p5.js, so my knowledge is limited. I don't have any experience of js beyond what I have picked up through working with p5. My goal is to get HSB colours from dat.gui, yes. I intend to modulate colours by controlling hue, saturation & brightness/lightness/value seperately. (I expect there are other ways to achieve the same goal, but I am just trying to add some GUI to existing code and would like to avoid too many changes). I want to run in colorMode(HSB) and pick colours via dat.gui where the colour indicated in the color-selecter matches the colour-object (or HSB colour values) coming out. Does that make sense?

  • edited April 2016 Answer ✓

    My goal is to get HSB colours from dat.gui

    Then you have to set the initial colour variable in the HSV format dat.gui recognises:

    vars.colourHSV = { h: [0-360], s: [0-1], v: [0-1] };

    Where [0-360] etc is the range of values expected.

    That's awkward because the ranges of values/format that p5js uses for HSB is different ([0-360], [0-100], [0-100]) which most likely explains your issues.

    Since p5js also doesn't expect an object you'll have to convert the colour variable to a format p5js understands whenever you use it. Assuming colorMode(HSB), the following should work for you in your dat.gui event callback:

      hsv.onChange(function(value) {
                bg = [value.h, value.s*100, value.v*100];
            });
    

    But depending on what you're doing in your code you may want to abstract that into a conversion function so you don't have to work with two separate colour variables...

  • Ah, this is starting to make sense now. I just needed a simple conversion from the HSV format which dat.gui requires to the HSB color object that p5js uses. I couldn't see that before. Thankyou so much for taking the time to help me out!

Sign In or Register to comment.