Javascript 将0-1值转换为十六进制颜色?

Javascript 将0-1值转换为十六进制颜色?,javascript,colors,hex,rgb,rgba,Javascript,Colors,Hex,Rgb,Rgba,我正在创建一个应用程序,使用NASA API可视化恒星。恒星的颜色以0:1的比例返回,0表示纯蓝色,1表示纯红色。基本上,我需要设置一种方法,将javascript中的0-1值转换为滑动十六进制(或rgb)比例,如下所示: 0: blue (9aafff) .165: blue white (cad8ff) .33: white (f7f7ff) .495: yellow white (fcffd4) .66: yellow (fff3a1) .825: orange (ffa350) 1: r

我正在创建一个应用程序,使用NASA API可视化恒星。恒星的颜色以0:1的比例返回,0表示纯蓝色,1表示纯红色。基本上,我需要设置一种方法,将javascript中的0-1值转换为滑动十六进制(或rgb)比例,如下所示:

0: blue (9aafff)
.165: blue white (cad8ff)
.33: white (f7f7ff)
.495: yellow white (fcffd4)
.66: yellow (fff3a1)
.825: orange (ffa350)
1: red (fb6252)

这可能吗?我甚至不知道如何开始处理这个问题。干杯

最好是在RGB以外的其他颜色空间中工作。比如说

例如:

var stones = [ // Your Data
  {v:0, hex:'#9aafff'},
  {v:.165, hex:'#cad8ff'},
  {v:.33, hex:'#f7f7ff'},
  {v:.495, hex:'#fcffd4'},
  {v:.66, hex:'#fff3a1'},
  {v:.825, hex:'#ffa350'},
  {v:1, hex:'#fb6252'},
]
stones.forEach(function(s){
  s.rgb = hexToRgb(s.hex);
  s.hsl = rgbToHsl.apply(0, s.rgb);
});

function valueToRgbColor(val){
  for (var i=1; i<stones.length; i++) {
    if (val<=stones[i].v) {
      var k = (val-stones[i-1].v)/(stones[i].v-stones[i-1].v),
          hsl = interpolArrays(stones[i-1].hsl, stones[i].hsl, k);
      return 'rgb('+hslToRgb.apply(0,hsl).map(function(v){ return v|0})+')';
    }
  }
  throw "bad value";
}

这是我刚才用纯Javascript编写的解决方案之一。它处理两种颜色之间的线性插值

/* 
NASA color to RGB function
by Alexis Paques

It process a linear interpolation between two colors, here is the scheme:
0: blue
.165: blue white
.33: white
.495: yellow white
.66: yellow
.825: orange
1: red
*/

var blue = [0,0,255];
var bluewhite = [127,127,255];
var white = [255,255,255];
var yellowwhite = [255,255,127];
var yellow = [255,255,0];
var orange = [255,127,0];
var red = [255,0,0];
function color01toRGB(color01){
  var RGB = [0,0,0];
  var fromRGB = [0,0,0];
  var toRGB = [0,0,0];
  if(!color01)
    return '#000000';
  if(color01 > 1 || color01 < 0)
    return '#000000';
  if(color01 >= 0 && color01 <= 0.165 ){
    fromRGB = blue;
    toRGB = bluewhite;
  }
  else if(color01 > 0.165 && color01 <= 0.33 ){
    fromRGB = bluewhite;
    toRGB = white;
  }
  else if(color01 > 0.33 && color01 <= 0.495 ){
    fromRGB = white;
    toRGB = yellowwhite;
  }
  else if(color01 > 0.495 && color01 <= 0.66 ){
    fromRGB = yellowwhite;
    toRGB = yellow;
  }
  else if(color01 > 0.66 && color01 <= 0.825 ){
    fromRGB = yellow;
    toRGB = orange;
  }
  else if(color01 > 0.825 && color01 <= 1 ){
    fromRGB = orange;
    toRGB = red;
  }

  // 0.165
  for (var i = RGB.length - 1; i >= 0; i--) {
    RGB[i] = Math.round(fromRGB[i]*color01/0.165 + toRGB[i]*(1-color01/0.165)).toString(16);
  };

  return '#' + RGB.join('');
}
/*
NASA颜色到RGB功能
亚历克西斯·帕克斯
它处理两种颜色之间的线性插值,方案如下:
0:蓝色
.165:蓝白
.33:白色
.495:黄白色
.66:黄色
.825:橙色
1:红色
*/
var blue=[0,0255];
变量bluewhite=[127127255];
var white=[255255];
var yellowwhite=[255255127];
黄色变量=[255255,0];
var orange=[255127,0];
var red=[255,0,0];
函数color01toRGB(color01){
var RGB=[0,0,0];
var fromRGB=[0,0,0];
var-toRGB=[0,0,0];
如果(!color01)
返回“#000000”;
如果(color01>1 | | color01<0)
返回“#000000”;
如果(color01>=0&&color01 0.165&&color01 0.33&&color01 0.495&&color01 0.66&&color01 0.825&&color01=0;i--){
RGB[i]=数学舍入(从RGB[i]*color01/0.165+toRGB[i]*(1-color01/0.165))。到字符串(16);
};
返回“#”+RGB.join(“”);
}

由于您有一个值列表,所有值都非常饱和且明亮,因此您可能可以在当前(RGB)空间中对此进行插值。它不会像你转换成HSL那样漂亮,但是对于你拥有的颜色来说效果很好

由于数据中没有任何权重或曲线,使用简单的线性插值应该可以很好地工作。比如:

var停止=[
[0, 154, 175, 255],
[0.165, 202, 216, 255],
[0.33, 247, 247, 255],
[0.495, 252, 255, 212],
[0.66, 255, 243, 161],
[0.825, 255, 163, 80],
[1, 251, 98, 82]
];
函数转换颜色(颜色){
var c=Math.min(Math.max(color,0),1);//钳制在0和1之间
//在c下找到第一站
var startIndex=0;
对于(;stops[startIndex][0]=stops.length){
stopIndex=stops.length-1;
}
var stop=停止[停止指数];
log('usingstop',stopIndex,'asstop');
//找到从开始到c和开始到停止的距离
var范围=停止[0]-启动[0];
var diff=c-开始[0];
//从开始到停止将差异转换为比率
如果(范围>0){
diff/=范围;
}
log('interpoling',c',between',stop[0],'and',start[0],'by',diff);
//从RGB转换为HSL
var a=rgbToHsl(开始[1],开始[2],开始[3]);
var b=rgbToHsl(停止[1],停止[2],停止[3]);
控制台日志(“hsl停止”,a、b);
//在两种颜色之间插值(开始*diff+(停止*(1-diff)))
var out=[0,0,0];
out[0]=a[0]*diff+(b[0]*(1-diff));
out[1]=a[1]*diff+(b[1]*(1-diff));
out[2]=a[2]*diff+(b[2]*(1-diff));
console.log('插入',输出);
//从HSL转换回RGB
var r=hslToRgb(输出[0],输出[1],输出[2]);
r=r.map(功能(rv){
//对输出的每个组成部分进行四舍五入
返回数学圆(rv);
});
返回r;
}
//设置分区
var divs=document.queryselectoral('.star');
Array.prototype.forEach.call(divs,function(star){
var color=convertColor(star.dataset.color);
var colorStr='rgb('+color[0]+'、'+color[1]+'、'+color[2]+');
console.log('setting',star',to',colorStr);
star.style.backgroundColor=colorStr;
});
//从HSL到RGB的转换http://stackoverflow.com/a/30758827/129032
函数rgbToHsl(r、g、b){
r/=255,g/=255,b/=255;
var max=数学最大值(r,g,b),
min=数学min(r,g,b);
变量h,s,l=(最大+最小)/2;
如果(最大=最小){
h=s=0;//消色差
}否则{
var d=最大-最小值;
s=l>0.5?d/(2-最大-最小):d/(最大+最小);
开关(最大值){
案例r:
h=(g-b)/d+(g1)t-=1;
如果(t<1/6)返回p+(q-p)*6*t;
如果(t<1/2)返回q;
如果(t<2/3)返回p+(q-p)*(2/3-t)*6;
返回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);
}
返回[r*255,g*255,b*255];
}
.star{
宽度:24px;
高度:24px;
显示:内联块;
盒子阴影:0px 0px 16px-2px rgba(0,0,0,0.66);
}


确保这是可能的。但是值[01]和颜色之间的关系是什么?这是一个介于0&0.165=>蓝、蓝、白之间的插值吗?@AlexisPaques,是的,这是一个插值。就像我说的,滑动比例。值可以在0到1之间的任何位置(尽管我认为它们在某个点上是四舍五入的,如果我更方便的话,我可以随时使用js对它们进行四舍五入)。您可以添加并发送等效的RGB值“蓝白”、“黄白”、“黄”、“橙”吗?对于蓝白,是#7777FF吗?@AlexisPaques,当然,我在原始帖子中添加了特定的十六进制代码。这显示了颜色插值的一般理论,但不是从渐变停止列表中提取的(有点重要)方面。这是故意的吗?@这可能是个想法