RGB到现实生活中的浅色Javascript转换

RGB到现实生活中的浅色Javascript转换,javascript,led,light,Javascript,Led,Light,我认为这是一个非常有趣的问题,需要一个优雅的解决方案 我有一个RGB值,例如205,50,63 我试图在网页上模拟RGB LED的颜色,就好像它是真实的灯光一样 例如,RGB颜色255,0,0将在LED和网页上显示为红色 同样,RGB颜色255255255将在LED和网页上显示为白色 但是RGB颜色0,0,0将在LED上显示为off,在网页上显示为黑色 我试图实现的是0,0,0和255255都显示为白色。就好像LED越暗,它就越白 我一直在尝试对这些值应用成比例的算法,然后将层叠在彼此的顶部,但

我认为这是一个非常有趣的问题,需要一个优雅的解决方案

我有一个RGB值,例如
205,50,63

我试图在网页上模拟RGB LED的颜色,就好像它是真实的灯光一样

例如,RGB颜色
255,0,0
将在LED和网页上显示为红色

同样,RGB颜色
255255255
将在LED和网页上显示为白色

但是RGB颜色
0,0,0
将在LED上显示为off,在网页上显示为黑色

我试图实现的是0,0,0和255255都显示为白色。就好像LED越暗,它就越白


我一直在尝试对这些值应用成比例的算法,然后将
层叠在彼此的顶部,但运气不好。有什么想法吗?

我不确定您想象的情况是什么,但从您想要的输出来看,简单地放大最大值为255有什么不对

function scaleUp(rgb) {
    let max = Math.max(rgb.r, rgb.g, rgb.b);
    if (!max) { // 0 or NaN
        return {r: 255, g: 255, b: 255};
    }
    let factor = 255 / max;
    return {
        r: factor * rgb.r,
        g: factor * rgb.g,
        b: factor * rgb.b,
    };
}
所以你会得到这样的结果

scaleUp({r: 0, g: 0, b: 0}); // {r: 255, g: 255, b: 255}
scaleUp({r: 255, g: 0, b: 0}); // {r: 255, g: 0, b: 0}
scaleUp({r: 50, g: 80, b: 66}); // {r: 159.375, g: 255, b: 210.375}

请注意,这会将所有
{x,0,0}
折叠为
{255,0,0}
,这意味着
{1,0,0}
{1,1,1}
大不相同。如果这是不理想的,你需要考虑这种情况下的特殊处理< <
更多RGB提示;如果您在op周围进行平方和根运算,则会获得更平滑的“更自然”的灯光过渡等,例如,与
x+y
相比,使用
sqrt(x*x+y*y)

这导致了对如何解决问题的不同想法;添加白色并缩小比例

function scaleDown(rgb) {
    let whiteAdded = {
        r: Math.sqrt(255 * 255 + rgb.r * rgb.r),
        g: Math.sqrt(255 * 255 + rgb.g * rgb.g),
        b: Math.sqrt(255 * 255 + rgb.b * rgb.b)
    };
    return scaleUp(whiteAdded);
}
这次

scaleDown({r: 0, g: 0, b: 0}); // {r: 255, g: 255, b: 255}
scaleDown({r: 255, g: 0, b: 0}); // {r: 255, g: 180.3122292025696, b: 180.3122292025696}
scaleDown({r: 50, g: 80, b: 66}); // {r: 247.94043129928136, g: 255, b: 251.32479296236951}
并且在边缘点周围有较少的跳跃,例如

scaleDown({r: 1, g: 0, b: 0}); // {r: 255, g: 254.99803923830171, b: 254.99803923830171}
最后,请注意,这会将rgb映射到范围
180..255
,因此如果要保留“真红色”等,可以将其转换为
0..255

所以


我不确定您所想象的情况是什么,但是从您所期望的输出来看,简单地放大使最大值变为255有什么不对

function scaleUp(rgb) {
    let max = Math.max(rgb.r, rgb.g, rgb.b);
    if (!max) { // 0 or NaN
        return {r: 255, g: 255, b: 255};
    }
    let factor = 255 / max;
    return {
        r: factor * rgb.r,
        g: factor * rgb.g,
        b: factor * rgb.b,
    };
}
所以你会得到这样的结果

scaleUp({r: 0, g: 0, b: 0}); // {r: 255, g: 255, b: 255}
scaleUp({r: 255, g: 0, b: 0}); // {r: 255, g: 0, b: 0}
scaleUp({r: 50, g: 80, b: 66}); // {r: 159.375, g: 255, b: 210.375}

请注意,这会将所有
{x,0,0}
折叠为
{255,0,0}
,这意味着
{1,0,0}
{1,1,1}
大不相同。如果这是不理想的,你需要考虑这种情况下的特殊处理< <
更多RGB提示;如果您在op周围进行平方和根运算,则会获得更平滑的“更自然”的灯光过渡等,例如,与
x+y
相比,使用
sqrt(x*x+y*y)

这导致了对如何解决问题的不同想法;添加白色并缩小比例

function scaleDown(rgb) {
    let whiteAdded = {
        r: Math.sqrt(255 * 255 + rgb.r * rgb.r),
        g: Math.sqrt(255 * 255 + rgb.g * rgb.g),
        b: Math.sqrt(255 * 255 + rgb.b * rgb.b)
    };
    return scaleUp(whiteAdded);
}
这次

scaleDown({r: 0, g: 0, b: 0}); // {r: 255, g: 255, b: 255}
scaleDown({r: 255, g: 0, b: 0}); // {r: 255, g: 180.3122292025696, b: 180.3122292025696}
scaleDown({r: 50, g: 80, b: 66}); // {r: 247.94043129928136, g: 255, b: 251.32479296236951}
并且在边缘点周围有较少的跳跃,例如

scaleDown({r: 1, g: 0, b: 0}); // {r: 255, g: 254.99803923830171, b: 254.99803923830171}
最后,请注意,这会将rgb映射到范围
180..255
,因此如果要保留“真红色”等,可以将其转换为
0..255

所以


我认为你应该考虑这个问题。假设将色调设置为红色(示例中为354°),则可以操纵
饱和度
,以获得所需的结果。 这样做的目的是降低饱和度和亮度值,这样在调暗灯光时,饱和度就会降低。在边缘情况下,当饱和度达到0%时,该值也设置为100%产生白光

看看下面的图片。请注意H、S、V值

从基本情况开始:

然后你变暗了:

最后得到去饱和的颜色:

就代码而言,它将是

dim is in range 0.0 to 1.0
hsv(dim) -> {
    saturation = baseSaturation * (1 - dim)
    value = baseValue + (1 - baseValue) * dim
}
hue is constant

我认为你应该考虑这个问题。假设将色调设置为红色(示例中为354°),则可以操纵
饱和度
,以获得所需的结果。 这样做的目的是降低饱和度和亮度值,这样在调暗灯光时,饱和度就会降低。在边缘情况下,当饱和度达到0%时,该值也设置为100%产生白光

看看下面的图片。请注意H、S、V值

从基本情况开始:

然后你变暗了:

最后得到去饱和的颜色:

就代码而言,它将是

dim is in range 0.0 to 1.0
hsv(dim) -> {
    saturation = baseSaturation * (1 - dim)
    value = baseValue + (1 - baseValue) * dim
}
hue is constant

既然已经有了答案,我就不多说了

演示模拟了多色透明LED

颜色是通过使用复合操作为RGB重叠3+个图像创建的。
“变亮”
。这是一个附加过程。还有一个白色通道,为整个LED添加白光。RGB通道增加了额外的增益,以平衡效果,当蓝色为高时,红色被压低

当没有灯光时,只显示LED的图像。在4个彩色通道RGB和白色之前和之后还有一个对比度图像绘制

使用一些更好的源图像(每个通道只使用一个,应该有2-3个)可以创建非常逼真的FX。请注意,周围环境也会影响外观

//加载媒体(led的一组图像)
var mediagready=false;
变量LED=新图像();
leds.src=”https://i.stack.imgur.com/tT1YV.png";
LED.onload=功能(){
mediaReady=true;
}
var canLed=document.createElement(“画布”);
canLed.width=31;
canLed.height=47;
var ctxLed=canLed.getContext(“2d”)
//显示画布
var canvas=document.createElement(“canvas”);
画布宽度=31*20;
身高=47;
var ctx=canvas.getContext(“2d”);
var div=document.createElement(“div”);
div.style.background=“#999”;
div.style.position=“绝对”;
div.style.top=div.style.left=“0px”;
div.style.width=div.style.height=“100%”;
var div1=document.createElement(“div”);
div1.style.fontfamine=“Arial”;
div1.style.fontSize=“28px”;
div1.textContent=“使用分层RGB和白色图像的简单LED。”;
儿童分部(第1分部);
子类(画布);
文件.正文.附件(div);
常数cPow=[1/7,1/1,1/3,1/5];//g、b、r、w的输出增益(w为白色)
可变电流={
R