Как правильно получить значения RGB из 3 входных диапазонов на странице HTML - PullRequest
3 голосов
/ 22 января 2020

В настоящее время я работаю над веб-интерфейсом для моего светодиода. Поэтому я хочу иметь 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() работает, если я вставляю значения c из моих кнопок.

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Вы пытаетесь записать sh ваши значения rgb в виде строк для вашей rgbToHex() функции. Просто преобразуйте их в целые числа сначала в вашей функции color(), используя функцию parseInt () , а затем отправьте преобразованные значения rgb в вашу функцию rgbToHex().

Кроме того, все три ваших слушатели ввода делают то же самое, поэтому просто создайте отдельную функцию, скажем, 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>
0 голосов
/ 22 января 2020

Свойство .value элемента ввода всегда будет возвращать строку.
В JavaScript + можно добавлять числа, а также объединять строки.
И это проблема в этой части вашего скрипта:

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

r, g и b являются строками. Оператор сдвига преобразует их в действительные числа, поэтому (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 :
Преобразование значений r, g и b в действительные числа перед их использованием в Ваша формула

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>
...