将渐变添加到颜色滑块

Add Gradient to color slider

我正在尝试创建一个颜色滑块并使滑块的背景颜色动态变化。以下是我想要的颜色格式:

我能够获得 RGB、HSL 和 HS,但不能获得 V(来自 HSV)和 LAB。如何获得正确的渐变来填充 V 和 LAB?

下面的代码片段,代码功能不全。这意味着没有所有的颜色转换器。所以不要指望它可以交互工作。我正在处理那部分。我的问题 关于渐变。所以你唯一需要看的部分是 setColor 函数。

CodePen

var rInput, gInput, bInput, hInput, sInput, lInput;

window.onload = function() {
  rInput = document.getElementById("r");
  gInput = document.getElementById("g");
  bInput = document.getElementById("b");

  hInput = document.getElementById("h");
  sInput = document.getElementById("s");
  lInput = document.getElementById("l");

  hhInput = document.getElementById("hh");
  ssInput = document.getElementById("ss");
  vInput = document.getElementById("v");

  lInput = document.getElementById("l");
  aInput = document.getElementById("a");
  bbInput = document.getElementById("bb");

  setColorFromRgb();
}

function setColor() {
  document.getElementById('preview').style.backgroundColor = "rgb(" + rInput.value + "," + gInput.value + "," + bInput.value + ")";

  setGradient(rInput, [rgb(0, gInput.value, bInput.value), rgb(255, gInput.value, bInput.value)]);
  setGradient(gInput, [rgb(rInput.value, 0, bInput.value), rgb(rInput.value, 255, bInput.value)]);
  setGradient(bInput, [rgb(rInput.value, gInput.value, 0), rgb(rInput.value, gInput.value, 255)]);

  setGradient(hInput, [hsl(0, sInput.value, lInput.value), hsl(60, sInput.value, lInput.value), hsl(120, sInput.value, lInput.value), hsl(180, sInput.value, lInput.value), hsl(300, sInput.value, lInput.value), hsl(360, sInput.value, lInput.value)]);
  setGradient(sInput, [hsl(hInput.value, 0, lInput.value), hsl(hInput.value, 100, lInput.value)]);
  setGradient(lInput, [hsl(hInput.value, sInput.value, 0), hsl(hInput.value, sInput.value, 50), hsl(hInput.value, sInput.value, 100)]);

  setGradient(hhInput, [hsv(0, ssInput.value, vInput.value), hsv(60, ssInput.value, vInput.value), hsv(120, ssInput.value, vInput.value), hsv(180, ssInput.value, vInput.value), hsl(300, ssInput.value, vInput.value), hsv(360, ssInput.value, vInput.value)]);
  setGradient(ssInput, [hsv(hhInput.value, 0, vInput.value), hsv(hhInput.value, 100, vInput.value)]);


}

function setRgbSliders(r, g, b) {
  rInput.value = r;
  gInput.value = g;
  bInput.value = b;
}

function setHslSliders(h, s, l) {
  hInput.value = h;
  sInput.value = s;
  lInput.value = l;
}

function setHsvSliders(h, s, v) {
  hhInput.value = h;
  ssInput.value = s;
  vInput.value = v;
}

function setHsvSliders(l, a, b) {
  lInput.value = l;
  aInput.value = a;
  bbInput.value = b;
}


function setColorFromRgb() {
  hslValues = rgbToHsl(rInput.value, gInput.value, bInput.value);

  setHslSliders(hslValues[0], hslValues[1], hslValues[2]);

  setColor();
}

function setColorFromHsl() {
  rgbValues = hslToRgb(hInput.value, sInput.value, lInput.value);

  setRgbSliders(rgbValues[0], rgbValues[1], rgbValues[2]);

  setColor();
}

function setColorFromHsv() {
  hsvValues = hsvToRgb(hhInput.value, ssInput.value, vInput.value);

  setRgbSliders(hsvValues[0], hsvValues[1], hsvValues[2]);

  setColor();
}

function setColorFromLab() {
  hslValues = rgbToLab(lInput.value, aInput.value, bbInput.value);

  setHslSliders(labValues[0], labValues[1], labValues[2]);

  setColor();
}

function setGradient(el, steps) {
  gradientString = "linear-gradient(to right,";

  stepSize = 100 / (steps.length - 1);

  for (var i = 0; i < steps.length; i++) {
    gradientString += (i > 0 ? "," : "") + steps[i] + (i * stepSize) + "%";
  }

  el.style.backgroundImage = gradientString + ")";
}

/**
 * Formats the given RGB values into a string that can be used in CSS
 */
function rgb(r, g, b) {
  return "rgb(" + r + "," + g + "," + b + ")";
}

function hsl(h, s, l) {
  return "hsl(" + h + "," + s + "%," + l + "%)";
}

function hsv(h, s, v) {
  return "hsl(" + h + "," + s + "%," + v + "%)";
}

function lab(l, a, b) {
  return "lab(" + l + "," + a + "%," + b + "%)";
}

/**
 * Takes HSL values (H between 0 and 360, S and L each between 0 and 100) and returns the corresponding RGB values (each between 0 and 255)
 * Based on pseudo-code in the W3 Color Model document (http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color)
 */
function hslToRgb(h, s, l) {
  var m1, m2, m3, r, g, b;

  h = h / 360;
  s = s / 100;
  l = l / 100;

  m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;

  m1 = l * 2 - m2;

  r = hueToRgb(m1, m2, h + 1 / 3);
  g = hueToRgb(m1, m2, h);
  b = hueToRgb(m1, m2, h - 1 / 3);

  return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]
}

function hueToRgb(m1, m2, h) {
  if (h < 0) {
    h = h + 1;
  } else if (h > 1) {
    h = h - 1;
  }

  if (h * 6 < 1) {
    return m1 + (m2 - m1) * h * 6;
  } else if (h * 2 < 1) {
    return m2;
  } else if (h * 3 < 2) {
    return m1 + (m2 - m1) * (2 / 3 - h) * 6
  }

  return m1;
}

/**
 * Takes RGB values (each between 0 and 255) and returns the corresponding HSL values (H between 0 and 360, S and L each between 0 and 100).
 * Based on 
 */
function rgbToHsl(r, g, b) {
  var max, min, h, s, l;

  r = r / 255;
  g = g / 255;
  b = b / 255;

  max = Math.max(r, g, b);
  min = Math.min(r, g, b);

  l = (min + max) / 2;

  diff = max - min;

  if (diff == 0) {
    s = 0;
    h = 0;
  } else {
    if (l > 0.5) {
      s = (diff) / (2 - min - max)
    } else {
      s = diff / (max + min)
    }

    switch (max) {
      case r:
        h = (g - b) / diff + (g < b ? 6 : 0);
        break;
      case g:
        h = (b - r) / diff + 2;
        break;
      case b:
        h = (r - g) / diff + 4;
        break;
    }
  }

  return [Math.round(h * 60), Math.round(s * 100), Math.round(l * 100)];
}
body {
  background: #222;
  color: #ddd;
  font-family: sans-serif;
  font-size: 12px;
  width: 400px;
}
#preview {
  display: inline-block;
  float: left;
  width: 100%;
  height: 100px;
  margin-bottom: 5px;
}
input[type=range] {
  float: left;
  width: 100%;
  -webkit-appearance: none;
}
input[type=range],
#preview {
  border-radius: 3px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3) inset, 0 1px 0 rgba(255, 255, 255, 0.3);
}
.colourSlider {
  width: 400px;
}
.column {
  display: inline-block;
  width: 190px;
  margin-right: 20px;
  float: left;
}
.column:nth-child(2n) {
  margin-right: 0;
}
.colourSlider input[type=range] {
  float: left;
  width: 100%;
  -webkit-appearance: none;
  height: 20px;
}
.colourSlider input[type=range],
.colourSlider #preview {
  margin: 0;
  border-radius: 3px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3) inset, 0 1px 0 rgba(255, 255, 255, 0.3);
}
.colourSlider input[type="range"]::-moz-range-track {
  border: inherit;
  background: transparent;
  color: transparent;
}
.colourSlider input[type="range"]::-ms-track {
  border: inherit;
  background: transparent;
  color: transparent;
}
<div id="preview"></div>

<div class="row colourSlider">
  <div class="column">
    R:
    <input type="range" id="r" min="0" max="255" oninput="setColorFromRgb()">

    <br>G:
    <input type="range" id="g" min="0" max="255" oninput="setColorFromRgb()">

    <br>B:
    <input type="range" id="b" min="0" max="255" oninput="setColorFromRgb()">
  </div>

  <div class="column">
    H:
    <input type="range" id="h" min="0" max="360" oninput="setColorFromHsl()">
    <br>S:
    <input type="range" id="s" min="0" max="100" oninput="setColorFromHsl()">
    <br>L:
    <input type="range" id="l" min="0" max="100" oninput="setColorFromHsl()">
  </div>

  <div class="column">
    H:
    <input type="range" id="hh" min="0" max="360" oninput="setColorFromHsv()">
    <br>S:
    <input type="range" id="ss" min="0" max="100" oninput="setColorFromHsv()">
    <br>V:
    <input type="range" id="v" min="0" max="100" oninput="setColorFromHsv()">
  </div>

  <div class="column">
    L:
    <input type="range" id="ll" min="0" max="360" oninput="setColorFromLab()">
    <br>A:
    <input type="range" id="a" min="0" max="100" oninput="setColorFromLab()">
    <br>B:
    <input type="range" id="bb" min="0" max="100" oninput="setColorFromLab()">
  </div>
</div>

对不起,如果我没听懂你的意思。

首先你有两个变量lInput。我认为第二个(对于 LAB)必须是 llInput(考虑到您的命名技术)。

然后你必须添加setGradient()功能。对于 HSV 中的 V,例如应该是 setGradient(vInput, [hsv(hhInput.value, ssInput.value, 0), hsv(hhInput.value, ssInput.value, 100)]);。显然你在这里只有两个函数调用(检查你自己这个块),它们用于 'H' 和 'S'.

此外,您这里也有错别字,请将 setGradient() 中的 hsl(300, ssInput.value, vInput.value) 更改为 hsv(300, ssInput.value, vInput.value) for HSV。

对于实验室来说,它是完全相同的过程,如果我们只谈论梯度,但是你必须为此更改 setGradient() 算法,因为 css 不支持 LAB。

希望这个回答对您有所帮助:)