使用javascript计算颜色值(r,g,b)
我有x
包含速度值的数组数量。使用javascript计算颜色值(r,g,b)
这些值的单位是m/s,我不知道有多少,有多大。我需要创建一个函数来决定使用什么颜色。
我的想法是找到阵列的max
和min
值(速度),因为我知道这些值都可分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>
如果您不反对使用库,您可以查看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
...
}
我将排序此数组并在此之后将您的阵列分成3个较小的阵列。这个操作之后,你应该规范你的数组。您可以使用公式将列表中的每个元素乘以公式:
(xi - min)/(max - min)
。
你必须规范你的新阵列而不是旧阵列。对于第一个数组(最小值),您可以通过k=(max-xi)*255.0
计算红色强度。这种颜色将是(k, 0, 0)
。按公式着色速度最快的阵列:k=xi*255.0
[颜色将为(0,0,k)]。中间值的公式取决于您的选择。 (更高的速度=更多的绿色或更高的速度=更低的速度)。
对于复杂的描述,我很抱歉。祝你好运。
假设min
是最小速度和max
是最大速度,则所有的速度min
和max
之间:
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
。
你可以计算这两个区域的颜色,并使用三种颜色供产生梯度。
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> ';
});
这看起来不错。不过,我需要按照他们到达的顺序使用我的速度,所以对我进行排序并不是一个好主意。但我想我仍然可以使用你的函数,如果我能得到不同的最小值和最大值 – Zeliax
不需要对它们进行排序,只是认为它看起来更好;)。我做了一个编辑。 – DavidDomain
我同意它看起来更好,但我在地图上使用点的颜色,他们不会完全按顺序。无论如何,谢谢。这工作完美无瑕! :D – Zeliax