使用 javascript 计算颜色值 (r,g,b)
Calculating color value (r,g,b) using javascript
我有 x
个包含速度值的数组。
数值在m/s中,不知道有多少,有多大。我需要创建一个函数来决定使用什么颜色。
我的想法是找到数组的 max
和 min
值(速度),因为我知道这些值都可以被 0.25 整除,所以我想计算可能的数量"steps" 通过 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) 完全位于中间,它们可以更加强烈,然后根据它们倾向于哪一侧添加一点红色或蓝色。
我试图寻找一个可以为我做这件事的插件,但我找不到这样的插件,我也尝试用谷歌搜索来做这件事,但没有任何运气。
如果您不反对使用库,您可以查看 D3.js,特别是创建自定义比例的实用程序。这个 can be found here
的一个例子
例子
您需要使用速度数组 domain
和颜色作为输出来设置色标 range
:
let colors = d3.scale.linear().domain([0, Math.max(...speeds)])
.interpolate(d3.interpolateHcl)
.range([d3.rgb('#FF0000'), d3.rgb('#0000FF')]);
colors
现在是一个函数,给定一个索引作为输入,将输出一种颜色。设置好后,循环遍历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
将包含 speeds
中每个速度的 [r, g, b]
列表。
另一种选择是简单计算 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>
你可以计算出两个区域的颜色,然后用这三种颜色来生成渐变。
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> ';
});
我有 x
个包含速度值的数组。
数值在m/s中,不知道有多少,有多大。我需要创建一个函数来决定使用什么颜色。
我的想法是找到数组的 max
和 min
值(速度),因为我知道这些值都可以被 0.25 整除,所以我想计算可能的数量"steps" 通过 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) 完全位于中间,它们可以更加强烈,然后根据它们倾向于哪一侧添加一点红色或蓝色。
我试图寻找一个可以为我做这件事的插件,但我找不到这样的插件,我也尝试用谷歌搜索来做这件事,但没有任何运气。
如果您不反对使用库,您可以查看 D3.js,特别是创建自定义比例的实用程序。这个 can be found here
的一个例子例子
您需要使用速度数组 domain
和颜色作为输出来设置色标 range
:
let colors = d3.scale.linear().domain([0, Math.max(...speeds)])
.interpolate(d3.interpolateHcl)
.range([d3.rgb('#FF0000'), d3.rgb('#0000FF')]);
colors
现在是一个函数,给定一个索引作为输入,将输出一种颜色。设置好后,循环遍历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
将包含 speeds
中每个速度的 [r, g, b]
列表。
另一种选择是简单计算 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>
你可以计算出两个区域的颜色,然后用这三种颜色来生成渐变。
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> ';
});