Convert a number from 1 to 16777215 to a color value

I am trying to convert a number from 1 to 16,777,215 to any color format (RGB / HSL / HEX) that grows with the color spectrum using Javascript / jQuery.

The number 16,777,215 is the total possible RGB combinations (255,255,255), which are 32-bit colors.

I originally thought that converting the value to a hex using toString (16) would increase across the spectrum, however as the number increases, it seems to work across different brightness values ​​and blinks. An example of this unwanted behavior is http://jsfiddle.net/2z82auka/

var colour = 16777215;
window.setInterval(function(){
    colour -= 1000;
    $('body').css({background:'#' + colour.toString(16)});
}, 50);

      

How can I convert a value from 1 to 16777215 to a color in the below color spectrum?

Wanted outcome

+3


source to share


9 replies


The code below will do exactly what you want - it will give you vibrant colors in the color spectrum just like the image below, and to prove this, the demo will output integer values ​​next to the color. The result will look like this. Please use the rainbow

function in the code setInterval

.

spectrum



var colours = 16777215;

function rainbow(numOfSteps, step) {
	var r, g, b;
	var h = 1 - (step / numOfSteps);
	var i = ~~(h * 6);
	var f = h * 6 - i;
	var q = 1 - f;
	switch(i % 6){
		case 0: r = 1, g = f, b = 0; break;
		case 1: r = q, g = 1, b = 0; break;
		case 2: r = 0, g = 1, b = f; break;
		case 3: r = 0, g = q, b = 1; break;
		case 4: r = f, g = 0, b = 1; break;
		case 5: r = 1, g = 0, b = q; break;
	}
	var c = "#" + ("00" + (~ ~(r * 235)).toString(16)).slice(-2) + ("00" + (~ ~(g * 235)).toString(16)).slice(-2) + ("00" + (~ ~(b * 235)).toString(16)).slice(-2);
	return (c);
}

function render(i) {
	var item = "<li style='background-color:" + rainbow(colours, i) + "'>" + i + "</li>";
	$("ul").append(item);
}

function repeat(fn, times) {
	for (var i = 0; i < times; i+=10000) fn(i);
}

repeat(render, colours);
      

li {
  font-size:8px;
  height:10px;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul></ul>
      

Run codeHide result


(I can't take credit for this code, but I can take credit for not giving up and fixing abrupt color changes. Ref: https://gist.github.com/ruiwen/6163115 )

+6


source


Pasting to RGB: Constant increase of one will not result in a stable spectrum estimate. For example, when you go from # 0000ff (which is blue) to that +1, you end up at # 000100, which is essentially black.

Instead, you probably want to do something more like incrementing each of the three values ​​(R value, G value, and B value) by one. However, it will omit many, many colors. But if smoothness is what you value in its entirety, it's an easy way to get there.



@nada points out that this will give you a lot of gray. If you want to avoid this, you can try options such as: increment R until it is incremented anymore. Leave this at its maximum value while you increase G until it reaches its maximum, then increase B to max. Now change it: Reduce R to the minimum, then G, then B. This will still skip a ton of colors (in fact, it will skip most colors), but it should be smooth and it should avoid anything other than gray.

While this will work (if you don't miss most of the colors), I'm sure there is a better solution. Hopefully someone weighs this in. I'm very curious.

+2


source


Convert to starting value range from 1> 16777216 from 0> 360

The technique is here: Convert a range of numbers to a different range while maintaining a factor

Then use the HSL color model and increment from H0 S100 L100> H360 S100 L100

+2


source


You have a hue value, so you need to convert it to different color formats using fixed brightness and saturation.

To properly scale the hue from [1, 16777215] to the scale [0, 1], you need to do (x - 1) / 16777215

. Take that number and feed it to hsl2rgb

( here's a JS implementation ) with a high light level and a relatively high resolution.

Something like that:

// From this answer: https://stackoverflow.com/a/9493060/129032
function hslToRgb(h, s, l) {
  var r, g, b;

  if (s == 0) {
    r = g = b = l; // achromatic
  } else {
    var hue2rgb = 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 [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}

function scaleHue(hue) {
  return ((hue - 1) / 16777215);
}

var colour = 0;
window.setInterval(function() {
  colour = (colour + 100000) % 16777215;
  var hue = scaleHue(colour);
  var current = hslToRgb(hue, 0.8, 0.8);
  $('body').css({
    background: '#' + current[0].toString(16) + current[1].toString(16) + current[2].toString(16)
  });
}, 50);
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      

Run codeHide result


I increased the step from 1000 to 100000 to make the demo more obvious.

+2


source


Typically this is the formula to convert an integer to rgba

r = (val)&0xFF;
g = (val>>8)&0xFF;
b = (val>>16)&0xFF;
a = (val>>24)&0xFF;

      

Expressed as javascript

function ToRGBA(val){
   var r = (val)&0xFF;
   var g = (val>>8)&0xFF;
   var b = (val>>16)&0xFF;
   var a = (val>>24)&0xFF;   
   return "rgb(" + r + "," + g + "," + b + ")";
}

      

Updated script: http://jsfiddle.net/2z82auka/2/

0


source


Something like that?

<script>
function intToHex(colorNumber) {
    var R = (colorNumber - (colorNumber%65536)) / 65536;
    var G = ((colorNumber - R*65536) - ((colorNumber - R*65536)%256)) / 256;
    var B = colorNumber - R*65536 - G*256;
    var RGB = R.toString(16) + G.toString(16) + B.toString(16);
    return RGB;
}
</script>

      

0


source


Married this answer with Drake's help:

function colorNumberToHex(colorNumber) {
    function toHex(n) {
      n = n.toString(16) + '';
      return n.length >= 2 ? n : new Array(2 - n.length + 1).join('0') + n;
    }

    var r = toHex(colorNumber % 256),
        g = toHex(Math.floor( colorNumber / 256 ) % 256),
        b = toHex(Math.floor( Math.floor(colorNumber / 256) / 256 ) % 256);
    return '#' + r + g + b; 
}

      

0


source


The photo you submitted shows that you really just want to rotate through a set of continuous colors, not just any rgb color (as many of them essentially look white or black). I would suggest using HSV as a base instead of RGB. Attempting to increase the number representing the RGB value will result in the stutter you see (for example @Trott pointed out, 0000ff to 000100 jumps from blue to black).

Try something like this ( Fiddle ):

$(document).ready(function(){

    var h = 0;
    window.setInterval(function(){
        h += .01;
        if (h >= 1) h-=1;

        var rgbColor = HSVtoRGB(h, 1, 1);
        var colorString = '#' + convertComponentToHex(rgbColor.r)
                                + convertComponentToHex(rgbColor.g) 
                                + convertComponentToHex(rgbColor.b);
        $('body').css({background:colorString});
    }, 50);
});
function convertComponentToHex(v) {
    return ("00" + v.toString(16)).substr(-2);
}
function HSVtoRGB(h, s, v) {
    var r, g, b, i, f, p, q, t;
    if (h && s === undefined && v === undefined) {
        s = h.s, v = h.v, h = h.h;
    }
    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 {
        r: Math.floor(r * 255),
        g: Math.floor(g * 255),
        b: Math.floor(b * 255)
    };
}

      

(Thanks to this SO answer for the conversion code. I was too lazy to figure it out myself.)

0


source


My implementation ....

var r = 255;
var g = 0;
var b = 0;
var stage = 1;
var step = 5;

var int = setInterval(function () {
    if (stage == 1) {
        g += step;
        if (g >= 255) {
            g = 255;
            stage = 2;
        }
    } else if (stage == 2) {
        r -= step;
        if (r <= 0) {
            r = 0;
            stage = 3;
        }
    } else if (stage == 3) {
        b += step;
        if (b >= 255) {
            b = 255;
            stage = 4;
        }
    } else if (stage == 4) {
        g -= step;
        if (g <= 0) {
            g = 0
            stage = 5;
        }
    } else if (stage == 5) {
        r += step;
        if (r >= 255) {
            r = 255;
            stage = 6;
        }
    } else if (stage == 6) {
        b -= step;
        if (b <= 0) {
            b = 0;
            clearInterval(int);
        }
    }

    //console.log(r,g,b);
    $('body').css('background-color', 'RGB('+r+','+g+','+b+')');
}, 10);
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      

Run codeHide result


0


source







All Articles