js计算线性渐变的中间颜色值

要使用js计算线性渐变的中间值,记录下。

两个RGB颜色的中间颜色值

<style>
  #colors {
    margin-top: 2rem;
    display: flex;
  }
  #colors div {
    width: 100px;
    height: 100px;
  }
</style>
<div id="colors">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<script>
  // RGB转16进制色值
  function rgbToHex(red, green, blue) {
    const toHex = (colorValue) => {
      const hex = colorValue.toString(16);
      return hex.length == 1 ? "0" + hex : hex;
    };
    return "#" + toHex(red) + toHex(green) + toHex(blue);
  }

  // 16进制色值转RGB
  function hexToRgb(hex) {
    hex = hex.replace(/^\s*#|\s*$/g, "");
    let red = parseInt(hex.substr(0, 2), 16);
    let green = parseInt(hex.substr(2, 2), 16);
    let blue = parseInt(hex.substr(4, 2), 16);

    return [red, green, blue];
  }

  //计算线性渐变的中间颜色值
  function getColorBetweenTwoColors(colorA_str, colorB_str, ratio) {
    const colorA = hexToRgb(colorA_str);
    const colorB = hexToRgb(colorB_str);
    const r = Math.round((colorB[0] - colorA[0]) * ratio + colorA[0]);
    const g = Math.round((colorB[1] - colorA[1]) * ratio + colorA[1]);
    const b = Math.round((colorB[2] - colorA[2]) * ratio + colorA[2]);

    return rgbToHex(r, g, b);
  }

  const colorA = "#FF0000"; //红色
  const colorB = "#00FF00"; //绿色

  const radio_arr = [0, 0.25, 0.5, 0.75, 1];
  const elems = document.querySelectorAll(`#colors div`);
  for (let i in radio_arr) {
    elems[i].style.backgroundColor = getColorBetweenTwoColors(colorA, colorB, radio_arr[i]);
  }
</script>

 

多个HSL颜色的中间颜色值

<style>
  #colors {
    margin-top: 1rem;
    display: flex;
  }
  #colors div {
    width: 100px;
    height: 50px;
  }

  #grad {
    margin-top: 1rem;
    height: 50px;
    width: 700px;
    color: white;
    background: linear-gradient(to right, red, yellow, green, Cyan, blue, magenta, red);
  }

  #grad1 {
    margin-top: 1rem;
    height: 50px;
    width: 700px;
    color: white;
    background: linear-gradient(to right, hsl(0, 100%, 50%), hsl(60, 100%, 50%), hsl(120, 100%, 50%), hsl(180, 100%, 50%), hsl(240, 100%, 50%), hsl(300, 100%, 50%), hsl(0, 100%, 50%));
  }
</style>

<div style="display: flex; color: white">
  <div style="height: 50px; width: 100px; background-color: hsl(240, 100%, 50%)">HSL颜色模型</div>
  <div style="height: 50px; width: 100px; background-color: #0000ff">RGB颜色模型</div>
</div>

<div id="grad1">HSL颜色模型线性渐变</div>
<div id="grad">RGB颜色模型线性渐变</div>

<div id="colors">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<script>
  function getColorHueByRatio(startHue, endHue, ratio) {
    let hue = startHue + (endHue - startHue) * ratio;
    return hue > 360 ? hue - 360 : hue;
  }

  function hsvToRgb(h, s, v) {
    let r, g, b, i, f, p, q, t;
    if (h && s === 0) {
      r = g = b = v;
    } else {
      h /= 60;
      i = Math.floor(h);
      f = h - i;
      p = v * (1 - s);
      q = v * (1 - s * f);
      t = v * (1 - s * (1 - f));
      switch (i) {
        case 0:
          r = v;
          g = t;
          b = p;
          break;
        case 1:
          r = q;
          g = v;
          b = p;
          break;
        case 2:
          r = p;
          g = v;
          b = t;
          break;
        case 3:
          r = p;
          g = q;
          b = v;
          break;
        case 4:
          r = t;
          g = p;
          b = v;
          break;
        default:
          r = v;
          g = p;
          b = q;
      }
    }
    return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  }

  function hslToRgb(h, s, l) {
    let r, g, b;

    function hue2Rgb(p, q, t) {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1 / 6) return p + (q - p) * 6 * t;
      if (t < 1 / 2) return q;
      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    }

    let q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    let p = 2 * l - q;
    r = hue2Rgb(p, q, h + 1 / 3);
    g = hue2Rgb(p, q, h);
    b = hue2Rgb(p, q, h - 1 / 3);

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

  const radio_arr = [0, 0.25, 0.5, 0.75, 1];
  const elems = document.querySelectorAll(`#colors div`);
  const startHue = 0; //红色
  const endHue = 240; //蓝色
  for (let i in radio_arr) {
    const hue = getColorHueByRatio(startHue, endHue, radio_arr[i]);
    elems[i].style.backgroundColor = `hsl(${hue},100%,50%)`;
    console.log(radio_arr[i], hue, hsvToRgb(hue, 1, 1), hslToRgb(hue / 360, 1, 0.5));
  }
</script>

 

echarts中支持hsl颜色,chrome、firefox、Edge对hsl的支持良好

 

关于前端用到的颜色模型理论,看到有一篇文章,截图保存了下来,原文地址:https://blog.csdn.net/jimojianghu/article/details/121156313

posted @ 2024-03-28 16:32  carol2014  阅读(62)  评论(0编辑  收藏  举报