【问题标题】:Simple Color Variation简单的颜色变化
【发布时间】:2010-11-13 18:02:00
【问题描述】:

我正在创建一个用户界面,用户可以在其中更改页面的颜色值。我想要的是取分配给他们的背景颜色的值并将其变亮一定量。我只是想获得一条高光线,而不必每次都制作新图像。

示例:用户将背景颜色设置为#ECECEC。现在我想让某个元素的边框变成#F4F4F4(更接近白色的颜色)。

如果他们是使用 Javascript、PHP 甚至 jQuery 实现此目的的好方法,请告诉我。

【问题讨论】:

  • 你到底要什么?你想知道如何设置颜色吗?您想知道如何找到第二个数字(现有颜色的较浅版本)吗?
  • 我有一个表单,我将从用户那里收到一个 HEX 背景颜色值。我需要采用该颜色,将其分配给背景,然后将较浅的版本分配给标题边框颜色。全部在提交之前。

标签: php javascript jquery html colors


【解决方案1】:

顺便说一句:RGB 不是感知上的线性色彩空间。 我建议从 RGB 转换为 HSL,进行插值,然后再转换回 RGB。 我编写了以下 PHP 代码来生成任意感知正确的渐变;我建议把它变成一个服务,然后可以在需要时从 PHP 或 AJAX 调用。

你可以得到你最终的十六进制输出

$hexcol = col2string( RGBinterpolate("#ececec", "#ffffff", 0.5) ); // "#f4f4f4"

代码:

// Input:
//   $start as RGB color string,
//   $end as RGB color string,
//   $dist as float in [0.0 .. 1.0] being % distance between start and end colors
// Output:
//   array(int, int, int) being the resulting color in RGB)
function RGBinterpolate( $start, $end, $dist ) {
        $hsl_start = rgb2hsl( getCol($start) );
        $hsl_end = rgb2hsl( getCol($end) );

        // choose the shorter arc of the hue wheel!
        if ($hsl_start[0] > $hsl_end[0]) {
            if ($hsl_start[0] > $hsl_end[0] + 0.5)
                $hsl_start[0] -= 1.0;
        }
        else {
            if ($hsl_end[0] > $hsl_start[0] + 0.5)
                $hsl_end[0] -= 1.0;
        }

        // do linear interpolation in hsl color space
        $hs = interp( $hsl_start[0], $hsl_end[0], $dist );
        $ss = interp( $hsl_start[1], $hsl_end[1], $dist );
        $ls = interp( $hsl_start[2], $hsl_end[2], $dist );

        return hsl2rgb( array( $hs, $ss, $ls ) );
}


// Input: start-value, end-value, % distance as float in [0.0 .. 1.0]
// Output: result of interpolation as float
function interp($start, $end, $dist) {
        return $start + ($end - $start)*$dist;
}


// Input: string in one of the following formats:
//  #XXXXXX        (standard hex code as used in CSS)
//  0xXXXXXX       (same thing written as C longint)
//  #XXX           (equivalent to each-digit-doubled, ie #abc is #aabbcc)
//  000, 000, 000  (decimal triad, each value in 0..255)
//  colorname      (Netscape defined color names)
// Output: array(int, int, int) for legal values, else default value
function getCol($str, $default=array(0,0,0)) {
    global $namedcolors;

        // convert named color to #xxxxxx code
    if( isset($namedcolors[$str]) )
        $str = $namedcolors[$str];      // turn named color into a hex value

    $str = trim($str);  // remove leading and trailing whitespace
    $hex = "[0-9a-z]";

        // attempt to match #XXXXXX
    $pat = "/(#)($hex{2})($hex{2})($hex{2})/i";
    if ((preg_match($pat, $str, $arr)) == 1) {
            $r = hexdec($arr[2]);
            $g = hexdec($arr[3]);
            $b = hexdec($arr[4]);

            return array($r, $g, $b);
    }

        // attempt to match 0xXXXXXX
    $pat = "/(0x)($hex{2})($hex{2})($hex{2})/i";
    if ((preg_match($pat, $str, $arr)) == 1) {
            $r = hexdec($arr[2]);
            $g = hexdec($arr[3]);
            $b = hexdec($arr[4]);

            return array($r, $g, $b);
    }

        // attempt to match #XXX
    $pat = "/(#)($hex)($hex)($hex)/i";
    if ((preg_match($pat, $str, $arr)) == 1) {
            $r = hexdec($arr[2]) * 17;
            $g = hexdec($arr[3]) * 17;
            $b = hexdec($arr[4]) * 17;

            return array($r, $g, $b);
    }

    // attempt to match int, int, int
        $pat = "/(\d{1,3})\\s*,\\s*(\d{1,3})\\s*,\\s*(\d{1,3})/i";
    if ((preg_match($pat, $str, $arr)) == 1) {
            $r = 0 + $arr[2];    // implicit cast to int - make explicit?
            $g = 0 + $arr[3];
            $b = 0 + $arr[4];

            return array($r, $g, $b);
    }

        // if none of the above worked, return default value
    return $default;
}


// Input: array(int,int,int) being RGB color in { [0..255], [0..255], [0..255] }
// Output array(float,float,float) being HSL color in { [0.0 .. 1.0), [0.0 .. 1.0), [0.0 .. 1.0) }
function rgb2hsl($rgbtrio) {
    $r = $rgbtrio[0] / 256.0;   // Normalize {r,g,b} to [0.0 .. 1.0)
    $g = $rgbtrio[1] / 256.0;
    $b = $rgbtrio[2] / 256.0;

    $h = 0.0;
    $s = 0.0;
    $L = 0.0;

    $min = min($r, $g, $b);
    $max = max($r, $g, $b);
    $delta = $max - $min;
    $L = 0.5 * ( $max + $min );

    if ( $delta < 0.001 )   // This is a gray, no chroma...
    {
        $h = 0.0;   // ergo, hue and saturation are meaningless
        $s = 0.0;
    }
    else    // Chromatic data...
    {
        if ( $L < 0.5 ) $s = ($max - $min) / ( $max + $min );  
        else            $s = ($max - $min) / ( 2 - $max - $min );

        $dr = ( (($max - $r) / 6.0) + ($max / 2.0) ) / $max;
        $dg = ( (($max - $g) / 6.0) + ($max / 2.0) ) / $max;
        $db = ( (($max - $b) / 6.0) + ($max / 2.0) ) / $max;

        if ($r == $max)         $h = $db - $dg;
        elseif ($g == $max)     $h = (0.3333) + $dr - $db;
        elseif ($b == $max)     $h = (0.6666) + $dg - $dr;

        if ( $h < 0.0 ) $h += 1.0;
        if ( $h > 1.0 ) $h -= 1.0;
    }

    return array($h, $s, $L);
}


    function Hue_2_RGB( $v1, $v2, $vH ) {
        $v1 = 0.0+$v1;
        $v2 = 0.0+$v2;
        $vH = 0.0+$vH;

        if ( $vH < 0.0 )            $vH += 1.0;
        elseif ( $vH >= 1.0 )       $vH -= 1.0;
        // 0.0 <= vH < 1.0

        if ( $vH < 0.1667 )         return ( $v1 + 6.0*$vH*($v2 - $v1) );
        elseif ( $vH < 0.5 )        return ( $v2 );
        elseif ( $vH < 0.6667 )     return ( $v1 + (4.0-(6.0*$vH ))*($v2 - $v1) );
        else                        return ( $v1 );
    }

// Input: array(float,float,float) being HSL color in { [0.0 .. 1.0), [0.0 .. 1.0), [0.0 .. 1.0) }
// Output: array(int,int,int) being RGB color in { [0..255], [0..255], [0..255] }
function hsl2rgb($hsltrio) {
    $h = $hsltrio[0];
    $s = $hsltrio[1];
    $L = $hsltrio[2];

    if ( $s < 0.001 )                       //HSL from 0 to 1
    {
        $r = $L;
        $g = $L;
        $b = $L;
    }
    else
    {
        if ( $L < 0.5 )             $j = $L * ( 1.0 + $s );
        else                        $j = ($L + $s) - ($s * $L);

        $i = (2.0 * $L) - $j;

        $r = Hue_2_RGB( $i, $j, $h + 0.3333 );
        $g = Hue_2_RGB( $i, $j, $h );
        $b = Hue_2_RGB( $i, $j, $h - 0.3333 );
    }

    return array( floor(256.0 * $r), floor(256.0 * $g), floor(256.0 * $b) );
}


function col2string($rgbtrio) {
    global $colornames;

    $r = floor( $rgbtrio[0] );
    $g = floor( $rgbtrio[1] );
    $b = floor( $rgbtrio[2] );

    $str = sprintf("#%02x%02x%02x", $r, $g, $b);

    if( isset($colornames[$str]) )
        return $colornames[$str];
    else
        return $str;
}


// All Netscape named colors
$namedcolors = array(
  "aliceblue" => "#f0f8ff",
  "antiquewhite" => "#faebd7",
  "aqua" => "#00ffff",
  "aquamarine" => "#7fffd4",
  "azure" => "#f0ffff",
  "beige" => "#f5f5dc",
  "bisque" => "#ffe4c4",
  "black" => "#000000",
  "blanchedalmond" => "#ffebcd",
  "blue" => "#0000ff",
  "blueviolet" => "#8a2be2",
  "brown" => "#a52a2a",
  "burlywood" => "#deb887",
  "cadetblue" => "#5f9ea0",
  "chartreuse" => "#7fff00",
  "chocolate" => "#d2691e",
  "coral" => "#ff7f50",
  "cornflowerblue" => "#6495ed",
  "cornsilk" => "#fff8dc",
  "crimson" => "#dc143c",
  "cyan" => "#00ffff",
  "darkblue" => "#00008b",
  "darkcyan" => "#008b8b",
  "darkgoldenrod" => "#b8860b",
  "darkgray" => "#a9a9a9",
  "darkgreen" => "#006400",
  "darkgrey" => "#a9a9a9",
  "darkkhaki" => "#bdb76b",
  "darkmagenta" => "#8b008b",
  "darkolivegreen" => "#556b2f",
  "darkorange" => "#ff8c00",
  "darkorchid" => "#9932cc",
  "darkred" => "#8b0000",
  "darksalmon" => "#e9967a",
  "darkseagreen" => "#8fbc8f",
  "darkslateblue" => "#483d8b",
  "darkslategray" => "#2f4f4f",
  "darkslategrey" => "#2f4f4f",
  "darkturquoise" => "#00ced1",
  "darkviolet" => "#9400d3",
  "deeppink" => "#ff1493",
  "deepskyblue" => "#00bfff",
  "dimgray" => "#696969",
  "dimgrey" => "#696969",
  "dodgerblue" => "#1e90ff",
  "firebrick" => "#b22222",
  "floralwhite" => "#fffaf0",
  "forestgreen" => "#228b22",
  "fuchsia" => "#ff00ff",
  "gainsboro" => "#dcdcdc",
  "ghostwhite" => "#f8f8ff",
  "gold" => "#ffd700",
  "goldenrod" => "#daa520",
  "gray" => "#808080",
  "green" => "#008000",
  "greenyellow" => "#adff2f",
  "grey" => "#808080",
  "honeydew" => "#f0fff0",
  "hotpink" => "#ff69b4",
  "indianred" => "#cd5c5c",
  "indigo" => "#4b0082",
  "ivory" => "#fffff0",
  "khaki" => "#f0e68c",
  "lavender" => "#e6e6fa",
  "lavenderblush" => "#fff0f5",
  "lawngreen" => "#7cfc00",
  "lemonchiffon" => "#fffacd",
  "lightblue" => "#add8e6",
  "lightcoral" => "#f08080",
  "lightcyan" => "#e0ffff",
  "lightgoldenrodyellow" => "#fafad2",
  "lightgray" => "#d3d3d3",
  "lightgreen" => "#90ee90",
  "lightgrey" => "#d3d3d3",
  "lightpink" => "#ffb6c1",
  "lightsalmon" => "#ffa07a",
  "lightseagreen" => "#20b2aa",
  "lightskyblue" => "#87cefa",
  "lightslategray" => "#778899",
  "lightslategrey" => "#778899",
  "lightsteelblue" => "#b0c4de",
  "lightyellow" => "#ffffe0",
  "lime" => "#00ff00",
  "limegreen" => "#32cd32",
  "linen" => "#faf0e6",
  "magenta" => "#ff00ff",
  "maroon" => "#800000",
  "mediumaquamarine" => "#66cdaa",
  "mediumblue" => "#0000cd",
  "mediumorchid" => "#ba55d3",
  "mediumpurple" => "#9370db",
  "mediumseagreen" => "#3cb371",
  "mediumslateblue" => "#7b68ee",
  "mediumspringgreen" => "#00fa9a",
  "mediumturquoise" => "#48d1cc",
  "mediumvioletred" => "#c71585",
  "midnightblue" => "#191970",
  "mintcream" => "#f5fffa",
  "mistyrose" => "#ffe4e1",
  "moccasin" => "#ffe4b5",
  "navajowhite" => "#ffdead",
  "navy" => "#000080",
  "oldlace" => "#fdf5e6",
  "olive" => "#808000",
  "olivedrab" => "#6b8e23",
  "orange" => "#ffa500",
  "orangered" => "#ff4500",
  "orchid" => "#da70d6",
  "palegoldenrod" => "#eee8aa",
  "palegreen" => "#98fb98",
  "paleturquoise" => "#afeeee",
  "palevioletred" => "#db7093",
  "papayawhip" => "#ffefd5",
  "peachpuff" => "#ffdab9",
  "peru" => "#cd853f",
  "pink" => "#ffc0cb",
  "plum" => "#dda0dd",
  "powderblue" => "#b0e0e6",
  "purple" => "#800080",
  "red" => "#ff0000",
  "rosybrown" => "#bc8f8f",
  "royalblue" => "#4169e1",
  "saddlebrown" => "#8b4513",
  "salmon" => "#fa8072",
  "sandybrown" => "#f4a460",
  "seagreen" => "#2e8b57",
  "seashell" => "#fff5ee",
  "sienna" => "#a0522d",
  "silver" => "#c0c0c0",
  "skyblue" => "#87ceeb",
  "slateblue" => "#6a5acd",
  "slategray" => "#708090",
  "slategrey" => "#708090",
  "snow" => "#fffafa",
  "springgreen" => "#00ff7f",
  "steelblue" => "#4682b4",
  "tan" => "#d2b48c",
  "teal" => "#008080",
  "thistle" => "#d8bfd8",
  "tomato" => "#ff6347",
  "turquoise" => "#40e0d0",
  "violet" => "#ee82ee",
  "wheat" => "#f5deb3",
  "white" => "#ffffff",
  "whitesmoke" => "#f5f5f5",
  "yellow" => "#ffff00",
  "yellowgreen" => "#9acd32"
);
$colornames = array_flip($namedcolors);

【讨论】:

    【解决方案2】:

    最近在为 Lablz webapp 平台添加配色方案时,我们需要解决同样的问题。 Hugh Bothwell 提供的解决方案指出了正确的方向,但存在问题。 Hugh 说从 RGB 转换为 HSL 后,您需要插入色相、饱和度和亮度。但是要创建相同颜色的阴影,您只需要操纵 Luminosity(亮度),否则您最终会得到不同的颜色。我们在服务器端(在 Java 中)使用这种方法来创建由http://colorschemedesigner.com 生成的各种颜色。我们还使用 Luminosity 来确定和调整颜色之间的对比度,这样我们就不会在彩色背景上看到无法阅读的彩色文本。

    在采用这种方法之前,我们尝试按照此处许多其他答案中提到的那样操作 RGB 颜色空间,并将 RGB 转换为 HSB 并更改亮度。 HSL 给出了最好的结果,因为它一直到最接近白色的最轻微的阴影,而在 HSB 中操纵亮度只会让你得到类似芥末色的效果,例如,当亮度从棕色增加到最大值时。

    如果你愿意,我可以把我们开发的java代码贴出来。

    【讨论】:

      【解决方案3】:

      Hugh Bothwell 的代码似乎有时会给出奇怪的答案。当转换即。 RGB #eb69ff 到 HSL 它给出 0.751567320261 1.67763157895 0.703125

      在函数 rgb2hsl($rgbtrio)
      if ( $L < 0.5 ) $s = $max / ( $max + $min );
      else $s = $max / ( 2 - $max - $min );

      该代码应该是

      if ( $L < 0.5 ) $s = ($max - $min) / ( $max + $min );
      else $s = ($max - $min) / ( 2 - $max - $min );

      至少在那之后我可以在使用 RGBinterpolate( $start, $end, $dist ) 时获得合理的 RGB 值

      【讨论】:

        【解决方案4】:

        您可以使用这样的函数来淡化颜色:

        function lighten(color, factor) {
            factor = factor || 0.4;
            var lighter = '#';
            for(var i = 1; i < 6; i += 2) {
                var part = parseInt(color.substr(i, 2), 16);
                part += Math.round((255 - part) * 0.4);
                lighter += (part < 16 ? '0' : '') + part.toString(16);
            }
            return lighter;
        }
        lighten('#ececec'); // returns '#f4f4f4'
        

        这会使颜色均匀地变亮一个百分比而不是一个固定的量。

        【讨论】:

        • 我将如何实现到表单中?我是 JS 的初学者,我将有一个具有十六进制背景颜色输入的表单。我也可以让它实时预览更改吗?页面将具有背景颜色,并且标题元素将具有变亮的边框颜色。
        【解决方案5】:

        更简单的解决方案是在 CSS 中使用 rgba() 颜色构造函数:

        border: 1px solid rgba(255,255,255,0.7)
        

        这将创建一个不透明度为 70% 的白色边框。不幸的是,Firefox 2、Opera 9 或任何版本的 IE 都不支持此功能。为这些浏览器创建替代版本并不难。 jQuery 示例:

        $('body').append('<div id="rgbatest" style="color:rgba(0,0,0,0);position:absolute;visibility:hidden">&nbsp;</div>"');
        if(!$('#rgbatest').css('color').match(/^rgba/)){
             $('body').addClass('no-rgba');
        }
        $('#rgbatest').remove();
        

        从这里,您可以使用 .no-rgba 类来覆盖 rgba 颜色。

        #thisDiv{border: 1px solid rgba(255,255,255,0.7)}
        .no-rgba #thisDiv{border: 1px solid #FFF}
        

        【讨论】:

        • 我建议反对 rgba,因为一半的浏览器(包括 IE)不支持它。这是兼容性列表:css-tricks.com/rgba-browser-support
        • 是的,检查我所做的更新;它包括基于 JavaScript 的 rgba 支持检查。
        【解决方案6】:
        var colorString=$(selector).css("background-color");
        var colorInt=parseInt(colorString.replace('#',''),16);
        colorInt+=parseInt("080808",16);
        var newColor = "#" + colorInt.toString(16);
        
        $(selector).css("border-color", newColor);
        

        【讨论】:

          【解决方案7】:

          您需要检查十六进制以查看它是 3(444) 还是 6 didgts(444444),然后将每个 RGB 拆分为十六进制的整数。

          然后,选择一个与你想要的值接近多少的阈值(假设它是分裂的差异)。

          66 十六进制 = 102 十进制。

          地板((255-102)/2) = 76。

          颜色正确 102 + 76 = 178

          178dec = B2hex。

          B2 将是你的新值(而不是 66)

          您需要为所有 3 个十六进制对执行此操作。

          【讨论】:

          【解决方案8】:

          我会实现像this one 这样的颜色选择器。这是对用户最友好的操作,实施起来并不困难。使用 onSubmit() 方法。

          $(".picker").ColorPicker({
              onSubmit: function(hsb, hex, rgb, el){
                  $(el).css({
                      'background-color': '#' + hex
                  });
                  $(el).ColorPickerHide();
              }
          });
          

          在我的例子中,'el' 是一个我想改变颜色的 div。

          【讨论】:

            【解决方案9】:

            使用 jQuery:

            $(selector).css('border-color', '#f4f4f4')
            

            selector 替换为将匹配您要修改的元素的选择器。没有 HTML 代码很难为您编写。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-04-23
              • 1970-01-01
              • 1970-01-01
              • 2013-08-15
              • 2016-08-14
              • 1970-01-01
              • 1970-01-01
              • 2013-11-26
              相关资源
              最近更新 更多