如何计算三个百分比之间的比例颜色?

问题描述:

我具有由用户引入三个十六进制的颜色,例如:如何计算三个百分比之间的比例颜色?

#39bf26 
#c7c228 
#C7282E 

然后,他们必须选择一个percentaje 1和100

  • 如果percentaje为100之间,颜色会返回插入第一个颜色为 :#39bf26。
  • 如果percentaje为50,则返回的颜色将为 插入的第二种颜色:#c7c228。
  • 如果percentaje为1,则返回的颜色将为 插入的第三种颜色:#C7282E。
  • 最后,如果比例是之前任何一个值之间, 然后返回的颜色将是两个第一 颜色时percentaje < 50比例混合,并在最后两个颜色的,如果 percentaje混合> 50.

我发现了一个类似的算法在这里: http://www.awcore.com/js/snippets/161/from-red-to-green-color-map-depend-on-percentage_en

但我怕我没有色彩算法的经验,所以我希望你能建议或引导我一点点。

如果你需要更多的信息让我知道,我会编辑帖子。

+1

你只需要知道#39bf26是(0x39,0xbf,0x26),每个通道都是十六进制的;你只是按频道做加权平均频道。问题是哪个? – leonbloy 2013-04-27 13:21:41

+0

是的,我没有意识到......我在下面的回复中提出了我的解决方案。 – harrison4 2013-04-27 13:39:50

不必要的矫枉过正 - 引入Colour对象分析,.scale.add十六进制颜色

var Colour = (function() { 
    function limit(x) { 
     if (x > 255) return 255; 
     if (x < 0) return 0; 
     return Math.floor(x); 
    } 
    function toHex(r, g, b) { 
     if (r > 15) r = r.toString(16); 
     else r = '0' + r.toString(16); 
     if (g > 15) g = g.toString(16); 
     else g = '0' + g.toString(16); 
     if (b > 15) b = b.toString(16); 
     else b = '0' + b.toString(16); 
     return '#' + (r + g + b).toUpperCase(); 
    } 
    function Colour(hex) { 
     if (hex.length === 7 || hex.length === 4) hex = hex.slice(1); 
     if (hex.length === 3) 
      hex = hex.charAt(0) + hex.charAt(0) 
       + hex.charAt(1) + hex.charAt(1) 
       + hex.charAt(2) + hex.charAt(2); 
     this.hex = '#' + hex.toUpperCase(); 
     this.r = parseInt(hex.slice(0, 2), 16); 
     this.g = parseInt(hex.slice(2, 4), 16); 
     this.b = parseInt(hex.slice(4, 6), 16); 
    } 
    Colour.prototype.scale = function (x) { 
     this.r = limit(this.r * x); 
     this.g = limit(this.g * x); 
     this.b = limit(this.b * x); 
     this.hex = toHex(this.r, this.g, this.b); 
     return this; 
    }; 
    Colour.prototype.add = function (c) { 
     return new Colour(
      toHex(
       limit(this.r + c.r), 
       limit(this.g + c.g), 
       limit(this.b + c.b) 
      ) 
     ); 
    }; 
    Colour.prototype.toString = function() { 
     return this.hex; 
    }; 
    Colour.prototype.valueOf = Colour.prototype.toString; 
    return Colour; 
}()); 

然后把你的颜色;

var myColours = [ 
    new Colour('#39bf26'), // Colour {hex: "#39BF26", r: 57, g: 191, b: 38, …} 
    new Colour('#c7c228'), // Colour {hex: "#C7C228", r: 199, g: 194, b: 40, …} 
    new Colour('#C7282E') // Colour {hex: "#C7282E", r: 199, g: 40, b: 46, …} 
]; 

现在写%的逻辑功能

function percent(x, col) { 
    var factor; 
    if (x < 50) { 
     factor = (50 - x)/50; 
     return col[0].scale(factor).add(col[1].scale(1-factor)); 
    } else { 
     factor = (100 - x)/50; 
     return col[2].scale(factor).add(col[1].scale(1-factor)); 
    } 
} 

而且使用它

percent(25, myColours); // Colour {hex: "#7FC027", r: 127, g: 192, b: 39, …} 
percent(75, myColours); // Colour {hex: "#C6752B", r: 198, g: 117, b: 43, …} 

不幸的是(除非你想引入新的属性),这将从小舍入误差受到影响,在75%的结果中看到(C6不是C7红色,因为C7 = 199,199/2 = 99.5 => 99 ,那么99 + 99 = 198 => C6)。

+0

哇,谢谢你的好评!完美的作品! :) – harrison4 2013-04-27 15:32:24

+1

第19行赋值语句无效:“hex = hex.charAt(0)+ hex = hex.charAt(0)” – actimel 2014-08-20 09:21:49

+0

@actimel感到惊讶的是, – 2014-08-20 11:37:06

好,这里是解决方案:

function getColorForPercentage(pct) { 
    pct /= 100; 

    var percentColors = [ 
      { pct: 0.01, color: { r: 0xdd, g: 0x51, b: 0x4c } }, 
      { pct: 0.5, color: { r: 0xfa, g: 0xa7, b: 0x32 } }, 
      { pct: 1.0, color: { r: 0x5e, g: 0xb9, b: 0x5e }} ]; 

    for (var i = 0; i < percentColors.length; i++) { 
     if (pct <= percentColors[i].pct) { 
      var lower = percentColors[i - 1] || { pct: 0.1, color: { r: 0x0, g: 0x00, b: 0 } }; 
      var upper = percentColors[i]; 
      var range = upper.pct - lower.pct; 
      var rangePct = (pct - lower.pct)/range; 
      var pctLower = 1 - rangePct; 
      var pctUpper = rangePct; 
      var color = { 
       r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper), 
       g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper), 
       b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper) 
      }; 
      return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'; 
     } 
    } 
} 
+0

我喜欢'return'rgb('+ [color.r,color.g,color.b] .join(',')+')';' – 2014-01-07 11:13:49