使用javascript计算颜色值(r,g,b)

问题描述:

我有x包含速度值的数组数量。使用javascript计算颜色值(r,g,b)

这些值的单位是m/s,我不知道有多少,有多大。我需要创建一个函数来决定使用什么颜色。

我的想法是找到阵列的maxmin值(速度),因为我知道这些值都可分0.25我想通过做var steps = (max - min)/0.25

来算的“台阶”可能量

因为我有RGB光谱,所以我想我可以计算出使用什么样的价值,但我根本无法将我的头围绕在做什么。

我希望能够做的是让速度变慢,速度变绿,速度变快为蓝色。

一个例子可能是我有一个数组:

speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00] 

现在,对于每一个我都值我要计算一个颜色,其中最大的价值将更加激烈较大,他们是(蓝色光谱 - 类似于(0,0,255)),而较小的值会更强烈(在红色光谱中 - (255,0,0)),它们越低。而对于中间值,我认为他们可以在绿色(0,255,0)更强烈,如果它绝对在中间,然后根据他们倾向的哪一侧添加一点红色或蓝色。

我试图寻找一个插件,可以为我做到这一点,但我无法找到这样的,我也尝试了一种方法来做到这一点,但没有任何运气。

另一种方法是简单计算hsl的值,因为您已经知道所处理的确切颜色。从hsl转换到rgb不应该很难,有很多图书馆很好。

这里是一个例子。

var speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00]; 
 
var fragment = document.createDocumentFragment(); 
 
var list = document.querySelector('ul'); 
 
var speedsMin = Math.min(...speeds); 
 
var speedsMax = Math.max(...speeds); 
 
var hslMin = 0; 
 
var hslMax = 240; 
 

 
var hslValues = speeds.map(function(value) { 
 
    return { 
 
    h: Math.ceil(((value - speedsMin)/(speedsMax - speedsMin)) * (hslMax - hslMin) + hslMin), 
 
    s: 100, 
 
    l: 50 
 
    } 
 
}) 
 

 
hslValues.forEach(function(value) { 
 
    var item = document.createElement('li'); 
 
    var color = 'hsl(' + value.h + ',' + value.s + '%,' + value.l + '%)'; 
 
    item.style.backgroundColor = color; 
 
    fragment.appendChild(item) 
 
}) 
 

 
list.appendChild(fragment)
ul { 
 
    list-style-type: none 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 

 
ul li { 
 
    width: 20px; 
 
    height: 20px; 
 
    border-radius: 10px; 
 
    display: inline-block; 
 
    margin: 0 4px 
 
}
<ul></ul>

+0

这看起来不错。不过,我需要按照他们到达的顺序使用我的速度,所以对我进行排序并不是一个好主意。但我想我仍然可以使用你的函数,如果我能得到不同的最小值和最大值 – Zeliax

+0

不需要对它们进行排序,只是认为它看起来更好;)。我做了一个编辑。 – DavidDomain

+0

我同意它看起来更好,但我在地图上使用点的颜色,他们不会完全按顺序。无论如何,谢谢。这工作完美无瑕! :D – Zeliax

如果您不反对使用库,您可以查看D3.js,特别是用于创建自定义比例的实用程序。

let colors = d3.scale.linear().domain([0, Math.max(...speeds)]) 
    .interpolate(d3.interpolateHcl) 
    .range([d3.rgb('#FF0000'), d3.rgb('#0000FF')]); 

colors现在是:这can be found here

您需要使用您的速度阵列作为domain设置你的色标和颜色输出range一个例子给定索引作为输入的函数将输出一种颜色。即设置完毕后,遍历数组speeds,以获取相应的颜色:

for (let i = 0; i < speeds.length; i++) { 
    // colors(i) 
} 

var min...,max...; 
var mid=(min+max)/2; 

speeds.foreach(function(x,idx){ 
    var r,g,b; 
    if(x<mid){ 
    b=0; 
    g=255*(x-min)/(mid-min); 
    r=255-g; 
    }else{ 
    r=0; 
    g=255*(max-x)/(max-mid); 
    b=255-g; 
    } 
    // do something with r-g-b here. 
}); 

的想法是这样的,但写作后,我也很难弯曲我的大脑进行验证。我认为现在是正确的红色 - >绿色 - >蓝色2段渐变。

以上2-3个渐变线段,我只是真的创建一个调色板。

var r=[];g=[];b=[]; 
// black-red 
for(var i=0;i<256;i++){ 
    r.push(i); 
    g.push(0); 
    b.push(0); 
} 
// red-green 
for(var i=1;i<256;i++){ 
    r.push(255-i); 
    g.push(i); 
    b.push(0); 
} 
// green-blue 
for(var i=1;i<256;i++){ 
    r.push(0); 
    g.push(255-i); 
    b.push(i); 
} 
// blue-white 
for(var i=1;i<256;i++){ 
    r.push(i); 
    g.push(i); 
    b.push(255); 
} 

然后你有1021元的调色板,指数为x*r.length/(max-min)|0

后者的一个更多的JavaScript肥胖型迭代:

var colors=[]; 
// black-red 
for(var i=0;i<256;i++)colors.push({r:i,g:0,b:0}); // black-red 
for(var i=1;i<256;i++)colors.push({r:255-i,g:i,b:0}); // red-green 
for(var i=1;i<256;i++)colors.push({r:0,g:255-i,b:i}); // green-blue 
for(var i=1;i<256;i++)colors.push({r:i,g:i,b:255}); // blue-white 

speeds.foreacy(function(x,idx){ 
    var color=colors[x*colors.length/(max-min)|0]; // r-g-b fields with values 0-255 
    ... 
} 
+0

你的第二方案的思考,又怎么会得到输出为4.25的速度所需要的价值? “x”应该是4.25吗? – Zeliax

+0

@Zeliax是的,'x'是实际速度值 – tevemadar

+0

好吧。据我了解,我会为每个“颜色部分”(黑 - 红,红 - 绿等)设置一个调色板,但是您建议的索引只使用红色数组?我该怎么做才能获得真正的颜色? 'var color = x * r.lenght /(max-min)| 0'? – Zeliax

我将排序此数组并在此之后将您的阵列分成3个较小的阵列。这个操作之后,你应该规范你的数组。您可以使用公式将列表中的每个元素乘以公式:

(xi - min)/(max - min)

你必须规范你的新阵列而不是旧阵列。对于第一个数组(最小值),您可以通过k=(max-xi)*255.0计算红色强度。这种颜色将是(k, 0, 0)。按公式着色速度最快的阵列:k=xi*255.0 [颜色将为(0,0,k)]。中间值的公式取决于您的选择。 (更高的速度=更多的绿色或更高的速度=更低的速度)。

对于复杂的描述,我很抱歉。祝你好运。

+0

对不起。我不能使用这个程序,因为我需要按照它们来的顺序进行调整。感谢您的分享 – Zeliax

+0

您可以将它们复制到其他数组并记住它们的索引。但我发现了另一个问题。您应该将255.0更改为128.0并将128.0添加到公式中(例如:(max-xi)* 128.0 + 128.0),因为如果数组中的值最小,则结果在所有数组中都将为黑色。 – gryxon

假设min是最小速度和max是最大速度,则所有的速度minmax之间:

min |---------------------------| max 
       speeds 

你必须这个间隔划分成两个较小的间隔,这样的:

|-------------|--------------| 
min   mid   max 

您可以分配到分钟全红,到中期全面绿化,并充分最大蓝:

R    G    B 
|-------------|--------------| 
min   mid   max 

现在您必须为每个速度值计算其颜色。假设s是你的速度之一的值:鉴于你的速度阵列

r = g = b = 0; 

if (s <= mid) { 
    r = 255 - (s - min)/(mid - min) * 255; // r is 255 when s = min and 0 when s = mid 
    g = 255 - (mid - s)/(mid - min) * 255; // g is 255 when s = mid and 0 when s = min 

} else { 
    b = 255 - (s - mid)/(max - mid) * 255; 
    g = 255 - (max - s)/(max - mid) * 255; 
} 

,你可以做到以下几点:

var speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00] 
var max = Math.max(...speeds); 
var min = Math.min(...speeds); 
var mid = (max - min)/2; 

var colors = speeds.map((s) => { 
    var r, g, b; 
    r = g = b = 0; 

    if (s <= mid) { 
     r = 255 - (s - min)/(mid - min) * 255; 
     g = 255 - (mid - s)/(mid - min) * 255; 

    } else { 
     b = 255 - (s - mid)/(max - mid) * 255; 
     g = 255 - (max - s)/(max - mid) * 255; 
    } 

    return [r, g, b]; 
}); 

console.log(colors); 

数组colors将包含一个[r, g, b]列表中的每个速度speeds

+0

这是一个非常整齐的例子。我会尝试并实施它。谢谢! :D – Zeliax

+0

@Zeliax,欢迎您!我在帖子末尾添加了更多信息以提供更多帮助。 – ninjin

你可以计算这两个区域的颜色,并使用三种颜色*生梯度。

function getColor(v, min, max) { 
 

 
    function getC(f, l, r) { 
 
     return { 
 
      r: Math.floor((1 - f) * l.r + f * r.r), 
 
      g: Math.floor((1 - f) * l.g + f * r.g), 
 
      b: Math.floor((1 - f) * l.b + f * r.b), 
 
     }; 
 
    } 
 

 
    var left = { r: 255, g: 0, b: 0 }, 
 
     middle = { r: 0, g: 255, b: 0 }, 
 
     right = { r: 0, g: 0, b: 255 }, 
 
     mid = (max - min)/2; 
 

 
    return v < min + mid ? 
 
     getC((v - min)/mid, left, middle) : 
 
     getC((v - min - mid)/mid, middle, right); 
 
} 
 

 
var speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00], 
 
    min = Math.min(...speeds), 
 
    max = Math.max(...speeds); 
 

 
speeds.forEach(function (a) { 
 
    var color = getColor(a, min, max); 
 
    document.body.innerHTML += '<span style="color: #fff; background-color: rgb(' + color.r + ',' + color.g + ',' + color.b + ');">' + a + '</span> '; 
 
});