HTML颜色代码:从红到黄到绿

49
我想找到尽可能多的十六进制 HTML 值,以便从红色到绿色呈现平滑的颜色渐变。我希望这个过程类似于以下网站: http://www.utexas.edu/learn/html/colors.html 我对颜色选择不是很有眼光,因此我希望已经有一个标准图表,展示了如何顺利地从红色过渡到黄色再到绿色。 在该网站上,“6选1”最接近我要找的,但该示例仅限于 11 种颜色。
(1) FF0000 Red, 
(2) FF3300 Red(Orange)
(3) ff6600 
(4) ff9900 
(5) FFCC00 Gold 
(6) FFFF00 Yellow
(7) ccff00
(8) 99ff00
(9) 66ff00
(10) 33ff00
(11) 00FF00 Lime 

能够使颜色数量翻倍并同时保持平滑过渡,这将是非常棒的。

感谢任何见解和帮助。


我发现这个答案令人印象深刻,而且它链接到一个可编辑的演示:https://dev59.com/smw05IYBdhLWcg3wnjLC#17267684 - Ryan
13个回答

54

根据你想要得到的颜色数量,解决方案是通过逐步增加绿色值,当绿色最大(FF)时,再反复减少相同量的红色值。

伪代码:

int red = 255; //i.e. FF
int green = 0;
int stepSize = ?//how many colors do you want?
while(green < 255)
{
    green += stepSize;
    if(green > 255) { green = 255; }
    output(red, green, 0); //assume output is function that takes RGB
}
while(red > 0)
{
    red -= stepSize;
    if(red < 0) { red = 0; }
    output(red, green, 0); //assume output is function that takes RGB
}

手动生成,可以简单地每次增加16,就像这样:

FF0000
FF1000
FF2000
FF3000
FF4000
FF5000
FF6000
FF7000
FF8000
FF9000
FFA000
FFB000
FFC000
FFD000
FFE000
FFF000
FFFF00 //max, step by 15
F0FF00 //cheat, start with a -15 to simplify the rest
E0FF00
D0FF00
C0FF00
B0FF00
A0FF00
90FF00
80FF00
70FF00
60FF00
50FF00
40FF00
30FF00
20FF00
10FF00

29
最好的方法是理解十六进制颜色代码的实际含义。一旦你理解了这点,就会明白如何制作任意平滑度的渐变色。十六进制颜色代码是三元组,分别表示颜色的红、绿和蓝成分。例如,在颜色FF0000中,红色成分为FF,绿色成分为00,蓝色成分为00。因为将红色成分调到最大值FF,而将绿色和蓝色成分都调到最小值00,所以FF0000看起来是红色的。同样地,纯绿色是00FF00,纯蓝色是0000FF。如果你将十六进制数转换为十进制数,你将得到一个介于0255之间的值。
那么现在该怎么从红色过渡到黄色再到绿色呢?很简单,你取两个端点,决定要在它们之间分多少步,然后均匀地逐步遍历每个颜色通道,从一个颜色过渡到下一个颜色。下面是一个以11个十六进制(即十进制中的17)步长的示例。
FF0000 <-- red
FF1100
FF2200
FF3300
FF4400
FF5500
FF6600
FF7700
FF8800
FF9900
FFAA00
FFBB00
FFCC00
FFDD00
FFEE00
FFFF00 <-- yellow
EEFF00
DDFF00
CCFF00
BBFF00
AAFF00
99FF00
88FF00
77FF00
66FF00
55FF00
44FF00
33FF00
22FF00
11FF00
00FF00 <-- green

虽然在数学上是正确的,但这并不总是对于颜色感知来说最好的值。 - LarryBud

15

这里有一个从绿色到红色的漂亮渐变

    /* Green - Yellow - Red */
    .gradient_0    {background: #57bb8a;}
    .gradient_5    {background: #63b682;}
    .gradient_10   {background: #73b87e;}
    .gradient_15   {background: #84bb7b;}
    .gradient_20   {background: #94bd77;}
    .gradient_25   {background: #a4c073;}
    .gradient_30   {background: #b0be6e;}
    .gradient_35   {background: #c4c56d;}
    .gradient_40   {background: #d4c86a;}
    .gradient_45   {background: #e2c965;}
    .gradient_50   {background: #f5ce62;}
    .gradient_55   {background: #f3c563;}
    .gradient_60   {background: #e9b861;}
    .gradient_65   {background: #e6ad61;}
    .gradient_70   {background: #ecac67;}
    .gradient_75   {background: #e9a268;}
    .gradient_80   {background: #e79a69;}
    .gradient_85   {background: #e5926b;}
    .gradient_90   {background: #e2886c;}
    .gradient_95   {background: #e0816d;}
    .gradient_100  {background: #dd776e;}

    /* Red - Yellow - Green */
    .anti-gradient_100  {background: #57bb8a;}
    .anti-gradient_95   {background: #63b682;}
    .anti-gradient_90   {background: #73b87e;}
    .anti-gradient_85   {background: #84bb7b;}
    .anti-gradient_80   {background: #94bd77;}
    .anti-gradient_75   {background: #a4c073;}
    .anti-gradient_70   {background: #b0be6e;}
    .anti-gradient_65   {background: #c4c56d;}
    .anti-gradient_60   {background: #d4c86a;}
    .anti-gradient_55   {background: #e2c965;}
    .anti-gradient_50   {background: #f5ce62;}
    .anti-gradient_45   {background: #f3c563;}
    .anti-gradient_40   {background: #e9b861;}
    .anti-gradient_35   {background: #e6ad61;}
    .anti-gradient_30   {background: #ecac67;}
    .anti-gradient_25   {background: #e9a268;}
    .anti-gradient_20   {background: #e79a69;}
    .anti-gradient_15   {background: #e5926b;}
    .anti-gradient_10   {background: #e2886c;}
    .anti-gradient_5    {background: #e0816d;}
    .anti-gradient_0    {background: #dd776e;}
<div class="gradient_0">0</div>
<div class="gradient_5">5</div>
<div class="gradient_10">10</div>
<div class="gradient_15">15</div>
<div class="gradient_20">20</div>
<div class="gradient_25">25</div>
<div class="gradient_30">30</div>
<div class="gradient_35">35</div>
<div class="gradient_40">40</div>
<div class="gradient_45">45</div>
<div class="gradient_50">50</div>
<div class="gradient_55">55</div>
<div class="gradient_60">60</div>
<div class="gradient_65">65</div>
<div class="gradient_70">70</div>
<div class="gradient_75">75</div>
<div class="gradient_80">80</div>
<div class="gradient_85">85</div>
<div class="gradient_90">90</div>
<div class="gradient_95">95</div>
<div class="gradient_100">100</div>


10

我刚刚有一个项目,开始使用了与jball和Asaph类似的解决方案。也就是说,从红色(FF0000)平滑地增加到(FFFF00)再到(00FF00)。

然而,我发现在“黄色”周围看起来变化非常剧烈,而在“红色”和“绿色”周围几乎看不出变化。我发现可以通过使变化呈指数增长而不是线性增长来进行补偿,这样增量在“黄色”周围较小,在“红色”和“绿色”周围较大。 我制定的解决方案(使用 Javascript)如下所示:

    /**
     * Converts integer to a hexidecimal code, prepad's single 
     * digit hex codes with 0 to always return a two digit code. 
     * 
     * @param {Integer} i Integer to convert 
     * @returns {String} The hexidecimal code
     */
    function intToHex(i) {
        var hex = parseInt(i).toString(16);
        return (hex.length < 2) ? "0" + hex : hex;
    }   

    /**
     * Return hex color from scalar *value*.
     *
     * @param {float} value Scalar value between 0 and 1
     * @return {String} color
     */
    function makeColor(value) {
        // value must be between [0, 510]
        value = Math.min(Math.max(0,value), 1) * 510;

        var redValue;
        var greenValue;
        if (value < 255) {
            redValue = 255;
            greenValue = Math.sqrt(value) * 16;
            greenValue = Math.round(greenValue);
        } else {
            greenValue = 255;
            value = value - 255;
            redValue = 256 - (value * value / 255)
            redValue = Math.round(redValue);
        }

        return "#" + intToHex(redValue) + intToHex(greenValue) + "00";
    }

当我改变这个值时,它产生了一个更加平滑的渐变效果,而且无论起始点如何改变,改变输入值似乎对颜色产生了相同程度的影响。


2
非常酷!但有一个奇怪的问题:尝试将0.5传递到makeColor中。你会得到#100ff00!我所做的是将redValue = 256 - (value * value / 255)更改为redValue = 255 - (value * value / 255)以减轻这个问题。 - Chris Forrence

3
看任何一张图表都会让你误以为“颜色代码”是必须查找的单独值。实际上,最平滑的过渡方法就是简单地增加颜色中绿色的数量并减少红色的数量。
其实,这些神秘的十六进制代码根本不神秘。它们有六个数字,前两个数字显示颜色中红色的数量,中间两个数字显示绿色的数量,最后两个数字显示蓝色的数量。
与人类计数不同,我们从0到9时移动到下一个位置值并得到10,而在十六进制中,我们一直数到F。0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F、10
所以你的目标是从FF 00 00(仅红色,没有绿色或蓝色)到FF FF 00(混合红色和绿色,即黄色),最后到00 FF 00。
怎么做呢?只需不断地向绿色数量添加一点,直到它完全达到FF,然后开始从红色数量中减去一点,直到它降到00。
“一点点”是多少?取决于你认为需要多少才能获得平滑的过渡。你可以每次添加30个,从一个颜色跳到另一个颜色,或者每次添加1个,并使过渡进程更加平稳(但也许更慢)。尝试一下,看看哪种方法适合你。

2
我来到这篇文章是因为寻找一种简单的方法来为一组数值生成红黄绿的颜色列表。在编写需要展示“假设分析”和增强好、中、差数值的仪表板或报告时非常有用。在多个来源上发现了有趣的文章,但最终找到了这个非常简单的JavaScript函数:

function fSemaphor(minimal, maximal, value) {
  var difference = maximal - minimal;
  var medium = (minimal + difference / 2) | 0; // |0 returns INT
  var RED = 255,
    GREEN = 255;

  if (value <= medium)
    GREEN = (GREEN * (value / medium)) | 0;
  else
    RED = (RED * (1.0 - value / maximal)) | 0;

  // returns HEX color, for usage in CSS or any style
  return ("#" + (('0') + RED.toString(16)).substr(-2) + ('0' + GREEN.toString(16)).substr(-2) + '00'); // blue

}

我甚至提供了一个完整的使用示例。只需将其复制并粘贴到HTML页面中,看看它的作用。

Max value: <input value=0 id="minim" /> Min value: <input value=20 id="maxim" />
<input type=submit value="Calculate colors" onClick="fCalcul()">
<table id=tColors border=2></table>
<script>
  function fCalcul() {
    var i;
    var tblRows = "<tr><th>value</th><th>Color</th></tr>";
    var minValue = parseInt(minim.value);
    var maxValue = parseInt(maxim.value);
    var tblBody = "";
    var increment = 1;

    if ((maxValue - minValue) > 40) //  don't show more than 40 rows, for sample sake
      increment = ((maxValue - minValue) / 40) | 0;

    for (i = minValue; i <= maxValue; i += increment) {
      tblBody += "<tr><td>" + i + "</td><td style='background: " +
        fSemaphor(minValue, maxValue, i) + "'>" +
        fSemaphor(minValue, maxValue, i) + "</td></tr>";
    }

    tColors.innerHTML = tblRows + tblBody;
  }


    function fSemaphor(minimal, maximal, value) {
      var difference = maximal - minimal;
      var medium = (minimal + difference / 2) | 0; // |0 returns INT
      var RED = 255,
        GREEN = 255;

      if (value <= medium)
        GREEN = (GREEN * (value / medium)) | 0;
      else
        RED = (RED * (1.0 - value / maximal)) | 0;

      // returns HEX color, for usage in CSS or any style
      return ("#" + (('0') + RED.toString(16)).substr(-2) + ('0' + GREEN.toString(16)).substr(-2) + '00'); // blue

    }
</script>

感谢 Ovid 在 http://blogs.perl.org/users/ovid/2010/12/perl101-red-to-green-gradient.html 中的博客,他提供了一份技术解释,帮助我简化了它。


2

我搜索这个问题的原因是我试图为一个设备列表制作一个带有颜色的在线时间指示器,“签入”每小时检查一次。想法是,当在线时间为0%时,它将变成红色,50%时过渡到黄色,并在100%时变成绿色。这当然相当没用,但这是让表格看起来比实际更令人印象深刻的简单方法。给定最小值、最大值和值,它返回正确颜色的rgb 0-255值。假定输入有效。

function redYellowGreen(min, max, value)
{
 var green_max = 220;
 var red_max = 220;
 var red = 0;
 var green = 0;
 var blue = 0;

 if (value < max/2)
 {
  red = red_max;
  green = Math.round((value/(max/2))*green_max);
 }
 else
 {
  green = green_max;
  red = Math.round((1-((value-(max/2))/(max/2)))*red_max);
 }

 var to_return = new Object();
 to_return.red = red;
 to_return.green = green;
 to_return.blue = blue;

 return to_return;
}


最小值从未被使用。您应该计算范围(max-min),并将其用于计算。 - tommitytom

1

现今所有现代浏览器都支持CSS中的颜色渐变,可以在任何宽度/高度上实现完全平滑的渐变。然而,并非所有浏览器都支持官方的CSS linear-gradient,因此为了支持所有浏览器,请使用以下CSS类:

.gradient {
    background:    -moz-linear-gradient(left, red, yellow, green); /* FF3.6+ */
    background:        -webkit-gradient(linear, left top, right top, color-stop(0%, red), color-stop(50%, yellow), color-stop(100%, green)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(left, red, yellow, green); /* Chrome10+,Safari5.1+ */
    background:      -o-linear-gradient(left, red, yellow, green); /* Opera 11.10+ */
    background:     -ms-linear-gradient(left, red, yellow, green); /* IE10+ */
    background:         linear-gradient(to right, red, yellow, green); /* W3C */
}

如需进一步了解CSS渐变函数,请参阅Mozilla开发者网络中以下文章:

一个非常好的网站,可以快速生成适用于所有浏览器的完全定制化的颜色渐变,即Ultimate CSS Gradient Generator


0

在我的这边,我用了两个刷子解决了这个问题:

float sweepAngle = 45.0F; // angle you want ...
LinearGradientBrush linGrBrushUp = new LinearGradientBrush(
    new Point(0, 0), new     Point(w, 0),
    Color.FromArgb(255, 0, 255, 0),     // green
    Color.FromArgb(255, 255, 255, 0)    // yellow
);
LinearGradientBrush linGrBrushDown = new LinearGradientBrush(
    new Point(w, 0), new Point(0, 0),
Color.FromArgb(255, 255, 255, 0),   // yellow
Color.FromArgb(255, 255, 0, 0)      // red
);
g.DrawArc( new Pen(linGrBrushUp, 5), x, y, w, h, 180.0F, sweepAngle>180.0F?180.0F:sweepAngle );
g.DrawArc( new Pen(linGrBrushDown, 5), x, y, w, h, 0.0F, sweepAngle>180.0F?sweepAngle-180.0F:0 );

0

仅适用于Chrome和Safari浏览器

来自NiceWebType.com

<style type="text/css">
    h1 {
        position: relative;
        font-size: 60px;
        line-height: 60px;
        text-shadow: 0px 0px 3px #000;
    }
    h1 a {
        position: absolute;
        top: 0; z-index: 2;
        color: #F00;
        -webkit-mask-image: -webkit-gradient(linear, left center, right center, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
    }
    h1:after {
        content: "CSS Text Gradient (Webkit)";
        color: #0F0;
    }
</style>

<h1><a>CSS Text Gradient (Webkit)</a></h1>

它在Safari和Chrome中工作,因为它们都基于Webkit引擎,并且您使用了一个Webkit特定功能。Firefox基于Gecko引擎,而IE基于Microsoft的Trident引擎,所以您的代码在Firefox / IE中不起作用并不奇怪。我怀疑它永远也不会起作用。 - Asaph
WebKit 特定的功能很可能是对 CSS3 的初步支持。当 CSS3 支持准备好供主流使用时,我想他们会从 CSS 字段名称中删除 -webkit- 前缀。 - Asaph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接