【问题标题】:How to generate a CSS color that is some specific percentage lighter/darker using JavaScript如何使用 JavaScript 生成比特定百分比更亮/更暗的 CSS 颜色
【发布时间】:2010-12-03 05:40:56
【问题描述】:

假设我的颜色是#404040。如何生成一个新的颜色十六进制代码,它要么亮要么暗 20%(或另一个给定百分比)?我需要这个来生成颜色以应用于悬停。

所应用的颜色会根据所选主题而变化,因此无法使用具有预定义颜色值的其他类或:hover

【问题讨论】:

  • 颜色总是十六进制颜色吗?是否可以将它们全部转换为 RGB,甚至更好地转换为 HSV?

标签: javascript html css colors


【解决方案1】:
var pad = function(num, totalChars) {
    var pad = '0';
    num = num + '';
    while (num.length < totalChars) {
        num = pad + num;
    }
    return num;
};

// Ratio is between 0 and 1
var changeColor = function(color, ratio, darker) {
    // Trim trailing/leading whitespace
    color = color.replace(/^\s*|\s*$/, '');

    // Expand three-digit hex
    color = color.replace(
        /^#?([a-f0-9])([a-f0-9])([a-f0-9])$/i,
        '#$1$1$2$2$3$3'
    );

    // Calculate ratio
    var difference = Math.round(ratio * 256) * (darker ? -1 : 1),
        // Determine if input is RGB(A)
        rgb = color.match(new RegExp('^rgba?\\(\\s*' +
            '(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])' +
            '\\s*,\\s*' +
            '(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])' +
            '\\s*,\\s*' +
            '(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])' +
            '(?:\\s*,\\s*' +
            '(0|1|0?\\.\\d+))?' +
            '\\s*\\)$'
        , 'i')),
        alpha = !!rgb && rgb[4] != null ? rgb[4] : null,

        // Convert hex to decimal
        decimal = !!rgb? [rgb[1], rgb[2], rgb[3]] : color.replace(
            /^#?([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])/i,
            function() {
                return parseInt(arguments[1], 16) + ',' +
                    parseInt(arguments[2], 16) + ',' +
                    parseInt(arguments[3], 16);
            }
        ).split(/,/),
        returnValue;

    // Return RGB(A)
    return !!rgb ?
        'rgb' + (alpha !== null ? 'a' : '') + '(' +
            Math[darker ? 'max' : 'min'](
                parseInt(decimal[0], 10) + difference, darker ? 0 : 255
            ) + ', ' +
            Math[darker ? 'max' : 'min'](
                parseInt(decimal[1], 10) + difference, darker ? 0 : 255
            ) + ', ' +
            Math[darker ? 'max' : 'min'](
                parseInt(decimal[2], 10) + difference, darker ? 0 : 255
            ) +
            (alpha !== null ? ', ' + alpha : '') +
            ')' :
        // Return hex
        [
            '#',
            pad(Math[darker ? 'max' : 'min'](
                parseInt(decimal[0], 10) + difference, darker ? 0 : 255
            ).toString(16), 2),
            pad(Math[darker ? 'max' : 'min'](
                parseInt(decimal[1], 10) + difference, darker ? 0 : 255
            ).toString(16), 2),
            pad(Math[darker ? 'max' : 'min'](
                parseInt(decimal[2], 10) + difference, darker ? 0 : 255
            ).toString(16), 2)
        ].join('');
};
var lighterColor = function(color, ratio) {
    return changeColor(color, ratio, false);
};
var darkerColor = function(color, ratio) {
    return changeColor(color, ratio, true);
};

// Use
var darker = darkerColor('rgba(80, 75, 52, .5)', .2);
var lighter = lighterColor('rgba(80, 75, 52, .5)', .2);

现在处理 RGB(A) 输入,以及十六进制(3 位或 6 位)。

【讨论】:

  • 从技术上讲,要从 RGB 值中获得 x% 更亮或更暗的颜色,您必须将其转换为 HSL,将 (L) 亮度降低或增加 x%,然后再转换回 RGB .我不确定像您在此处所做的那样减少单个 RGB 值会导致相同的颜色。不讨论人眼如何感知亮度变化,这可能会引入一个非线性比例,相当于 x% 感知亮度变化:)
  • 没错,这是一种非常幼稚的做法
【解决方案2】:

您基本上只需要从每个 R、G、B 分量中添加(对于较浅的)或减去(对于较深的)等量。

看看Domino 2.0,它是一个小型的 JavaScript 库,可以做到这一点。

【讨论】:

  • 我使用 :hover 并用我的大脑计算,但这对我有用
【解决方案3】:

您可以制作一个部分透明的白色或黑色 PNG 并在悬停时覆盖(底层?):

div.button {
  background-color: #404040;
}
body>div.button:hover {
  background-image: url('blackpixel.png');
}

无需 JS。

【讨论】:

  • 然后添加更多代码以支持 IE 6。然后添加另一个更轻的选项。然后.....
  • 大声笑,这并没有解决我列出的任何问题。它的实用性有限,但如果这就是你所需要的,那就去吧
【解决方案4】:

这只是对eyelidlessness'答案的修改,因为我两次看到相同的功能

var pad = function(num, totalChars) {
    var pad = '0';
    num = num + '';
    while (num.length < totalChars) {
        num = pad + num;
    }
    return num;
};

// Ratio is between 0 and 1
var changeColor = function(color, ratio, darker) {
    var difference = Math.round(ratio * 255) * (darker ? -1 : 1),
        minmax     = darker ? Math.max : Math.min,
        decimal    = color.replace(
            /^#?([a-z0-9][a-z0-9])([a-z0-9][a-z0-9])([a-z0-9][a-z0-9])/i,
            function() {
                return parseInt(arguments[1], 16) + ',' +
                    parseInt(arguments[2], 16) + ',' +
                    parseInt(arguments[3], 16);
            }
        ).split(/,/);
    return [
        '#',
        pad(minmax(parseInt(decimal[0], 10) + difference, 0).toString(16), 2),
        pad(minmax(parseInt(decimal[1], 10) + difference, 0).toString(16), 2),
        pad(minmax(parseInt(decimal[2], 10) + difference, 0).toString(16), 2)
    ].join('');
};
var lighterColor = function(color, ratio) {
    return changeColor(color, ratio, false);
};
var darkerColor = function(color, ratio) {
    return changeColor(color, ratio, true);
};

// Use
var darker = darkerColor('#404040', .2);
var lighter = lighterColor('#404040', .2);

【讨论】:

  • 然后第二个参数将是 255。嘿,另外我更新了我的以支持 RGB(A)。
  • ...还是坏了!你在minmax 调用中缺少darker ? 0 : 255 条件,所以它大部分时间都会产生黑色!
【解决方案5】:

也许jquery.colorhelpers.js 用于缩放和添加的函数会有所帮助吗? 但是,我正在尝试找到比 flot 源代码内联更好的示例。

【讨论】:

  • 那个库对 jQuery 没有依赖但仍然决定污染$ 命名空间?
【解决方案6】:

您可能错过了http://www.safalra.com/web-design/javascript/colour-handling-and-processing/。它支持 HSV 和 HSL 颜色并在它们之间以及在 RGB 值之间进行转换。

HSV 和 HSL 是更“人性化”的颜色表示,因此使用它们制作更浅的颜色、更深的颜色、或多或少的强烈颜色,或者找到具有最佳对比度的颜色非常简单。

【讨论】:

    【解决方案7】:

    来自How to Calculate Lighter or Darker Hex Colors in JavaScript Craig Buckler,2011 年 9 月 6 日:

    function ColorLuminance(hex, lum) {
      // validate hex string
      hex = String(hex).replace(/[^0-9a-f]/gi, '');
      if (hex.length < 6) {
          hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
      }
      lum = lum || 0;
      // convert to decimal and change luminosity
      var rgb = "#", c, i;
      for (i = 0; i < 3; i++) {
          c = parseInt(hex.substr(i*2,2), 16);
          c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
          rgb += ("00"+c).substr(c.length);
      }
      return rgb;
    }
    

    【讨论】:

      【解决方案8】:

      我找到了一种只使用 CSS 的方法,类似于 Wander Nauta 的解决方案,但不使用图像。如果可以更改html,只需在要更改的区域后面放置一个div,并将原始颜色设置为背景。然后,您可以将您关注的区域设置为半透明的白色或黑色背景,从而使您的元素变亮或变暗。

      我猜它有其局限性,但对我来说效果很好。

      【讨论】:

      • 另外,如果你只是想变亮,而不关心 IE
      【解决方案9】:

      这是我使用替换和拆分的方式。

      var CO='';
      
      $('#HoverMe').hover(function(){  
          CO=$(this).css('backgroundColor');
       
          var CC= $(this).css('backgroundColor').replace('rgb(','').replace(')','').split(',');
      
          var Change=0.2;
      
          var CR=Math.floor((CC[0]*Change)+parseInt(CC[0]));
      
          var CG=Math.floor((CC[1]*Change)+parseInt(CC[1]));
      
          var CB=Math.floor((CC[2]*Change)+parseInt(CC[2]));
      
          $(this).css('background','rgb('+CR+','+CG+','+CB+')');
      },
      
      function(){
          $(this).css('background',CO);
      });
      

      【讨论】:

        【解决方案10】:

        如果您指的是服务器端 JS,那么您可以使用 Stylus,它是一个 CSS 预处理器,具有使颜色更亮/更暗等内置功能。

        【讨论】:

          【解决方案11】:

          对于此解决方案,您需要两个元素,外部元素定义您的颜色,内部元素用于突出显示。就我而言,我有这样的事情:

          <div class="button"><a href="#">Hi Color</a></div>
          

          然后你在 CSS 中定义:

          .button {
             display: inline-block;
             background-color: blue;
          }
          
          .button a {
             display: inline-block;
          }
          
          .button a:hover {
             background-color: rgba(255,255,255,0.5);
          }
          

          JSFiddle

          【讨论】:

            猜你喜欢
            • 2010-12-10
            • 2019-05-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多