如何使用javascript从渐变百分比中获取颜色值?

时间:2015-05-09 17:36:51

标签: javascript jquery css colors linear-gradients

我有一个固定的宽度div,使用css应用渐变。我想基于此渐变构建基于滑块的颜色选择器。

当我拖动滑块时,我计算百分比位置,我想根据此值获取十六进制或rgb颜色代码。

我的想法是创建一个定义了开始/停止位置和颜色的数组,然后根据滑块位置从这个数组中找到两个值,然后以某种方式找到它之间的颜色:这是我无法前进的地方。

演示:http://jsfiddle.net/pdu8rpfv/

var gradient = [
    [
        0,
        'ff0000'
    ],
    [
        28,
        '008000'
    ],
    [
        72,
        '0000ff'
    ],
    [
        100,
        'ff0000'
    ]
];
$( "#slider" ).slider({
    min: 1,
    slide: function( event, ui ) {

        var colorRange = []
        $.each(gradient, function( index, value ) {
            if(ui.value<=value[0]) {
                colorRange = [index-1,index]
                return false;
            }
        });

        $('#result').css("background-color", 'red');

    }
});

6 个答案:

答案 0 :(得分:34)

我能够使用此函数解决此问题,该函数基于less.js函数:http://lesscss.org/functions/#color-operations-mix

function pickHex(color1, color2, weight) {
    var w1 = weight;
    var w2 = 1 - w1;
    var rgb = [Math.round(color1[0] * w1 + color2[0] * w2),
        Math.round(color1[1] * w1 + color2[1] * w2),
        Math.round(color1[2] * w1 + color2[2] * w2)];
    return rgb;
}

我只需要传递渐变阵列中两个最接近的颜色代码以及滑块手柄所处的比例(可以借助滑块宽度轻松计算)。这是现场的例子:

http://jsfiddle.net/vksn3yLL/

答案 1 :(得分:2)

使用与 Felipe Ribeiro 的最佳答案类似的逻辑,

我已经创建了一个 Javascript color-scales 来处理它。您还可以输入多个色标以及设置透明度级别。

现场演示在这里:https://codepen.io/dalisc/pen/yLVXoeR

包的链接在这里:https://www.npmjs.com/package/color-scales

示例用法:

const ColorScale = require("color-scales");
let colorScale = new ColorScale(0, 100, ["#ffffff", "#000000"], 0.5);
let rgbaStr = colorScale.getColor(50).toRGBAString(); // returns "rgba(127,127,127, 0.5)"

该包能够根据您的需要输出十六进制、rgb 或 rgba 字符串。它还可以输出自定义颜色对象 ({r,g,b,a}),以防您需要挑选单个颜色组件。

我在尝试在基于 Javascript 的应用程序上模仿 Tableau 仪表板时遇到了类似的问题。我意识到这是 Tableau 和 Microsoft Excel 等数据可视化工具的常见功能,因此我创建了一个 npm 包来在 Javascript 应用程序上处理它。如果你想减少你的代码,你可以使用这个包。

答案 2 :(得分:0)

可能不是主题,但我发现它可以帮助那些来到这里的人,因为他们想要jquery .css()中颜色和百分比之间的关系

此示例使百分比数字显示为红色至绿色,具体取决于它最接近零或100

$('#elm').css({color: 'rgb(' + ((100 - percent) *2.56) +',' + (percent *2.56) +',0)'})

请参见下面的演示

$('button').click( e => {
  const percent = Math.floor(Math.random()*100);
  const newElm = $(`<b>${percent}</b><br>`)
  .css({color: `rgb(${(100 - percent) *2.56},${percent *2.56},0)`})
  $('body').append(newElm);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click to make new percentage</button><br>

答案 3 :(得分:0)

三色渐变

只要有人想要3种颜色渐变,下面是使用红色,黄色和绿色的示例:

enter image description here

here提供了colorGradient函数的github JS代码。

function colorGradient(fadeFraction, rgbColor1, rgbColor2, rgbColor3) {
    var color1 = rgbColor1;
    var color2 = rgbColor2;
    var fade = fadeFraction;

    // Do we have 3 colors for the gradient? Need to adjust the params.
    if (rgbColor3) {
      fade = fade * 2;

      // Find which interval to use and adjust the fade percentage
      if (fade >= 1) {
        fade -= 1;
        color1 = rgbColor2;
        color2 = rgbColor3;
      }
    }

    var diffRed = color2.red - color1.red;
    var diffGreen = color2.green - color1.green;
    var diffBlue = color2.blue - color1.blue;

    var gradient = {
      red: parseInt(Math.floor(color1.red + (diffRed * fade)), 10),
      green: parseInt(Math.floor(color1.green + (diffGreen * fade)), 10),
      blue: parseInt(Math.floor(color1.blue + (diffBlue * fade)), 10),
    };

    return 'rgb(' + gradient.red + ',' + gradient.green + ',' + gradient.blue + ')';
}

演示:

// Gradient Function
function colorGradient(fadeFraction, rgbColor1, rgbColor2, rgbColor3) {
    var color1 = rgbColor1;
    var color2 = rgbColor2;
    var fade = fadeFraction;

    // Do we have 3 colors for the gradient? Need to adjust the params.
    if (rgbColor3) {
      fade = fade * 2;

      // Find which interval to use and adjust the fade percentage
      if (fade >= 1) {
        fade -= 1;
        color1 = rgbColor2;
        color2 = rgbColor3;
      }
    }

    var diffRed = color2.red - color1.red;
    var diffGreen = color2.green - color1.green;
    var diffBlue = color2.blue - color1.blue;

    var gradient = {
      red: parseInt(Math.floor(color1.red + (diffRed * fade)), 10),
      green: parseInt(Math.floor(color1.green + (diffGreen * fade)), 10),
      blue: parseInt(Math.floor(color1.blue + (diffBlue * fade)), 10),
    };

    return 'rgb(' + gradient.red + ',' + gradient.green + ',' + gradient.blue + ')';
}
  
// Implementation sample
var spans = $('.gradient-test');
var count = spans.length, color;
var color1 = {
  red: 19, green: 233, blue: 19
};
var color2 = {
  red: 255, green: 0, blue: 0
};
var color3 = {
  red: 255, green: 255, blue: 0
};
$('.gradient-test').each(function(i, span) {
  var g = Math.round(((i+1) * 100) / count);
  if (g < 10){
    g = '0' + g;
  }
  g = +('0.' + g)
  color = colorGradient(g, color1, color2, color3);
  $(span).css('background-color', color);
});
.gradient-test {
  width: 1rem;
  height: 1rem;
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>

答案 4 :(得分:0)

有一个不错的库,可以处理各种颜色操作chroma.js

yarn add chroma-js

然后

import chroma from 'chroma-js';

const f = chroma.scale(['yellow', 'red', 'black']);

console.log( f(0.25).toString() );                    // #ff8000
console.log( f(0.5).css('rgba') );                    // rgba(255,0,0,1)
console.log( f(0.75).css() );                         // rgb(128,0,0)
console.log( f(1).css() );                            // rgb(0,0,0)

答案 5 :(得分:0)

无限数量的颜色渐变(两个或更多)

如果有2、3、4或20种颜色,则可以使用此解决方案。生成一个HTML元素,并使用CSS渐变背景设置样式。然后查看单个像素的颜色值。

  1. 创建一个<canvas>元素。宽度为101像素(0到100%),高度为1像素(我们不在乎高度)。然后将背景色设置为渐变。参见方法initCanvas(colorsArray)

  2. 查看画布的单个像素,然后返回其颜色。参见方法getColor(percent)

  3. 最后,您可以找到由5种颜色(红色,橙色,绿色,石灰,蓝色)制成的渐变示例。

const WIDTH = 101; // 0 to 100
const HEIGHT = 1;
  
let context;

function initCanvas(gradientColors) // gradientColors [colorA, colorB, ..]
{
  // Canvas
  const canvasElement = document.createElement("CANVAS");
  canvasElement.width = WIDTH;
  canvasElement.height = HEIGHT;

  context = canvasElement.getContext("2d");
  
  // Gradient
  const gradient = context.createLinearGradient(0, 0, WIDTH, 0); // x0, y0, x1, y1
  
  const step = 1 / (gradientColors.length - 1); // need to validate at least two colors in gradientColors
  let val = 0;
  gradientColors.forEach(color => {
    gradient.addColorStop(val, color);
    val += step;
  });

  // Fill with gradient
  context.fillStyle = gradient;
  context.fillRect(0, 0, WIDTH, HEIGHT); // x, y, width, height
}

function getColor(percent) // percent [0..100]
{
  const color = context.getImageData(percent, 0, 1, 1); // x, y, width, height
  const rgba = color.data;
  
  return `rgb(${ rgba[0] }, ${ rgba[1] }, ${ rgba[2] })`;
}

// Test:
initCanvas(['red', 'orange', 'green', 'lime', 'blue']);

document.getElementById("color0"  ).style.backgroundColor = getColor(0);
document.getElementById("color10" ).style.backgroundColor = getColor(10);
document.getElementById("color20" ).style.backgroundColor = getColor(20);
document.getElementById("color30" ).style.backgroundColor = getColor(30);
document.getElementById("color40" ).style.backgroundColor = getColor(40);
document.getElementById("color50" ).style.backgroundColor = getColor(50);
document.getElementById("color60" ).style.backgroundColor = getColor(60);
document.getElementById("color70" ).style.backgroundColor = getColor(70);
document.getElementById("color80" ).style.backgroundColor = getColor(80);
document.getElementById("color90" ).style.backgroundColor = getColor(90);
document.getElementById("color100").style.backgroundColor = getColor(100);
.example {
  width: 100px;
  height: 25px;
}
<h3>Gradient colors: red, orange, green, lime, blue</h3>
<div id="color0"   class="example">0%  </div>
<div id="color10"  class="example">10% </div>
<div id="color20"  class="example">20% </div>
<div id="color30"  class="example">30% </div>
<div id="color40"  class="example">40% </div>
<div id="color50"  class="example">50% </div>
<div id="color60"  class="example">60% </div>
<div id="color70"  class="example">70% </div>
<div id="color80"  class="example">80% </div>
<div id="color90"  class="example">90% </div>
<div id="color100" class="example">100%</div>

P.S-我使用两种方法initCanvs()getColors()进行编码,因此您不会为每种颜色选择生成新的画布。但是,如果每次都有新的渐变,则可以合并它们。