如何从 HTML 页面中的 3 个输入范围正确获取 RGB 值



我目前正在为我的LED开发Web界面。所以我想有 3 个滑块,从中我可以向我的控制器发送十六进制值。

这是我到目前为止所拥有的:

<div class="main">
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderRed" style="background: linear-gradient(to right, black 0%, red 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderGreen" style="background: linear-gradient(to right, black, green 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderBlue" style="background: linear-gradient(to right, black, blue 70%);">
</div>
</div>

和 JS 以获取我可以发送到控制器的十六进制值:

sliderRed.oninput = function () {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
sliderGreen.oninput = function () {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
sliderBlue.oninput = function () {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
function color(r, g, b) {
console.log(rgbToHex(r, g, b));
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

我从上面的代码中得到的结果与我想要得到的#000000#ffffff之间的值并不接近。 相反,如果我移动滑块,我会得到类似#86122240的值,即使如果我从按钮输入静态值,函数color()确实有效。

您正在尝试将 rgb 值作为字符串推送到rgbToHex()函数。只需先使用 parseInt(( 函数在color()函数中将它们转换为整数,然后将转换后的 rgb 值发送到rgbToHex()函数。

此外,所有三个输入侦听器都在做同样的事情,因此只需创建一个名为 say、assignRGB()的单独函数,并在调用这三个滑块中的任何一个输入事件时调用该函数。

还可以通过使用 querySelectorAll(( 方法来检索所有三个输入并将输入侦听器添加到每个输入,从而进一步清理代码。


检查并运行以下代码片段以获取上述方法的实际示例:

const rgbSliders = document.querySelectorAll('.slider');
function assignRGB() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
rgbSliders.forEach(function(slider){
slider.addEventListener('input', assignRGB);
});
function color(r, g, b) {
const x = parseInt(r);
const y = parseInt(g);
const z = parseInt(b);
console.log(rgbToHex(x,y,z));
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
<div class="main">
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderRed" style="background: linear-gradient(to right, black 0%, red 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderGreen" style="background: linear-gradient(to right, black, green 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderBlue" style="background: linear-gradient(to right, black, blue 70%);">
</div>
</div>

输入元素的.value属性将始终返回一个字符串。
在JavaScript中,+可以添加数字,也可以连接字符串。
这就是脚本这一部分的问题:

((1 << 24) + (r << 16) + (g << 8) + b)

rgb是字符串。 移位运算符将它们转换为实数,因此(r << 16)(g << 16)将产生正确的值。
但是还有b...

如果您尝试"添加"两个变量,其中一个是字符串,则结果也将是一个字符串。

((1 << 24) + (r << 16) + (g << 8) + b)

本质上是:

(<number> + <number> + <number> + <string>)

结尾为:

((<number> + <number> + <number>).toString() + <string>)

让我们添加一些数字(实际上是脚本中的字符串(->r = g = b = "1"

/*1*/ (("1" << 24) + ("1" << 16) + ("1" << 8) + "1")
/*2*/ (16777216  + 65536       + 256        + "1")
/*3*/ (16843008                             + "1")
/*4*/ ("16843008"                           + "1")
/*5*/ "168430081"

现在让我们用一个代码片段和你的公式来测试这个假设:

console.log((("1" << 24) + ("1" << 16) + ("1" << 8) + "1").toString(16).slice(1));

tl;dr
rgb的值转换为实际数字,然后再在公式中使用它们

console.log(((1 << 24) + (1 << 16) + (1 << 8) + 1).toString(16).slice(1));

工作示例:

sliderRed.oninput = function() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;

color(red, green, blue);
}
sliderGreen.oninput = function() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
sliderBlue.oninput = function() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
function color(r, g, b) {
r = parseInt(r, 10);
g = parseInt(g, 10);
b = parseInt(b, 10);

console.log(rgbToHex(r, g, b));
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
<div class="main">
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderRed" style="background: linear-gradient(to right, black 0%, red 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderGreen" style="background: linear-gradient(to right, black, green 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderBlue" style="background: linear-gradient(to right, black, blue 70%);">
</div>
</div>

最新更新