将1到16777215之间的数字转换为颜色值

时间:2015-04-24 15:43:45

标签: javascript

我正在尝试将1到16,777,215之间的数字转换为使用Javascript / jQuery在色谱中递增的任何颜色格式(RGB / HSL / HEX)。

数字16,777,215是RGB(255,255,255)的总可能组合,即32位颜色。

我最初认为使用toString(16)将值转换为十六进制值会在频谱中增加,但随着数字增加,它似乎通过不同的亮度值而不是闪烁。这种不受欢迎的行为的一个例子是http://jsfiddle.net/2z82auka/

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

如何将1到16777215之间的值转换为下面所示色域的颜色?

Wanted outcome

10 个答案:

答案 0 :(得分:6)

下面的代码将完全符合您的要求 - 它将为您提供与下图完全相同的鲜艳色彩,为了证明这一点,演示将打印出颜色旁边的整数值。结果将如下所示。请使用rainbow代码中的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);
&#13;
li {
  font-size:8px;
  height:10px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul></ul>
&#13;
&#13;
&#13;

(我不能因为这段代码而受到赞扬,但我可以因为不放弃和解决颜色变化而感到荣幸。参考:https://gist.github.com/ruiwen/6163115

答案 1 :(得分:2)

坚持使用RGB:始终递增1将不会在频谱中产生稳定的等级。例如,当你从#0000ff(蓝色)转到+1时,你最终会在#000100处,这基本上是黑色的。

相反,您可能希望做更多的事情,比如将三个值(R值,G值和B值)中的每一个递增一。但是,这将省略许多很多颜色。但如果平稳性是你对全面性的重视,那么这是一种简单的方法。

@nada指出,这会给你一大堆灰色。如果你想避免这种情况,你可以尝试以下变体:递增R直到它不再增加。在增加G直到达到最大值时将其保持为最大值,然后将B增加到最大值。现在反过来:将R减少到最小,然后是G,然后是B.这仍然会错过很多颜色(事实上,它会错过大多数颜色),但它应该是平滑的并且应该避免只不过是灰色的。

虽然这样可行(如果你不介意遗漏大多数颜色),我相信有更好的解决方案。我希望有人适应它。我很好奇。

答案 2 :(得分:2)

转换为范围从1开始的初始值> 16777216从0开始; 360

这里的技术:Convert a number range to another range, maintaining ratio

然后使用HSL颜色模型,并从H0 S100 L100增加&gt; H360 S100 L100

答案 3 :(得分:2)

您有色调值,因此需要使用固定亮度和饱和度将其转换为各种颜色格式。

要将色调从[1,16777215]正确缩放到[0,1]比例,您需要执行(x - 1) / 16777215。取这个数字并将其输入hsl2rgbhere's a JS implementation),其中包含高lum且相对较高的坐姿。

像这样:

&#13;
&#13;
// 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);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

我将步长从1000增加到100000,使演示更加明显。

答案 4 :(得分:1)

这对我有用...

export function intToHex(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(Math.floor( Math.floor(colorNumber / 256) / 256 ) % 256),
        g = toHex(Math.floor( colorNumber / 256 ) % 256),
        b = toHex(colorNumber % 256);
    return '#' + r + g + b; 
}

答案 5 :(得分:0)

通常,这是将整数转换为rgba

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

表示为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 + ")";
}

更新了小提琴:http://jsfiddle.net/2z82auka/2/

答案 6 :(得分:0)

那样的东西?

<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>

答案 7 :(得分:0)

与Drake's结婚this

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; 
}

答案 8 :(得分:0)

您已经展示的图片表明您真的只想通过一组连续的颜色旋转,而不是每种可能的rgb颜色(因为它们中的许多基本上看起来是白色或黑色)。我建议使用HSV作为基础而不是RGB。试图增加一个代表RGB值的数字会导致你看到的口吃(就像@Trott指出的那样,从0000ff到000100从蓝色跳到黑色)。

尝试这样的事情(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)
    };
}

(感谢this SO answer转换代码。我太懒了,不能为自己搞清楚。)

答案 9 :(得分:0)

我的实施......

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>