如何在Javascript中按百分比制作与另一种颜色相似的颜色

时间:2015-01-19 01:51:35

标签: javascript css

我有十六种形式的两种颜色,#000000#ffffff。我想以百分比的方式将第一种颜色逼近第二种颜色。 类似的东西:

var percent=0.50;
var color1='#000000';
var color2='#ffffff';

var newcolor=approximateColor1ToColor2ByPercent(color1,color2,percent);
//newcolor should be a gray like #808080

怎么做?

3 个答案:

答案 0 :(得分:6)

对于添加剂颜色混合:

要混合两种颜色,请执行以下操作:

function approximateColor1ToColor2ByPercent(color1, color2, percent) {
  var red1 = parseInt(color1[1] + color1[2], 16);
  var green1 = parseInt(color1[3] + color1[4], 16);
  var blue1 = parseInt(color1[5] + color1[6], 16);

  var red2 = parseInt(color2[1] + color2[2], 16);
  var green2 = parseInt(color2[3] + color2[4], 16);
  var blue2 = parseInt(color2[5] + color2[6], 16);

  var red = Math.round(mix(red1, red2, percent));
  var green = Math.round(mix(green1, green2, percent));
  var blue = Math.round(mix(blue1, blue2, percent));

  return generateHex(red, green, blue);
}

function generateHex(r, g, b) {
  r = r.toString(16);
  g = g.toString(16);
  b = b.toString(16);

  // to address problem mentioned by Alexis Wilke:
  while (r.length < 2) { r = "0" + r; }
  while (g.length < 2) { g = "0" + g; }
  while (b.length < 2) { b = "0" + b; }

  return "#" + r + g + b;
}

function mix(start, end, percent) {
    return start + ((percent) * (end - start));
}

然后是以下代码:

approximateColor1ToColor2ByPercent('#000000', '#ffffff', .50);

将返回'#808080'

答案 1 :(得分:1)

我不专业,只是分享我的努力。

自然与计算机之间的性能颜色方式不同。要获得与您想要的颜色相似的颜色,您可以使用浅蓝色(#00FFFF)代替({{1} })。

所以我尝试了两种颜色混合方式,首先是传统的添加剂混合:

#OOOOFF

对于alpha混合,color1和color2都有自己的alpha通道,表示自身的透明度。所以alpha混合算法应该是(R,G,B范围从0到255):

newColor.R = (color1.R + color2.R)/2

我已经实施了它们,你可以看到结果:

&#13;
&#13;
newAlpha = 1 - (1-color1.Alpha) * (1-color2.Alpha)
newColor.R = (color1.R/255 * color1.Alpha / newAlpha + color2.R/255 * color2.Alpha * (1-color1.Alpha) / newAlpha)*255
&#13;
//Convert hex color into rgb color
function HexToRgb(hexcolor) {
  var hexR = hexcolor.substr(0, 2);
  var hexG = hexcolor.substr(2, 2);
  var hexB = hexcolor.substr(4, 2);
  var rgbColor = [];
  rgbColor[0] = parseInt(hexR, 16);
  rgbColor[1] = parseInt(hexG, 16);
  rgbColor[2] = parseInt(hexB, 16);
  return rgbColor;
}

//Convert rgb color int hex color
function RgbtoHex(rgbcolor) {
  var hexColor = rgbcolor[0].toString(16) + rgbcolor[1].toString(16) + rgbcolor[2].toString(16);
  return hexColor;
}

//Additive mixing two colors
function additiveMixing(color1, color2) {
  var rgbColor1 = HexToRgb(arguments[0]);
  var rgbColor2 = HexToRgb(arguments[1]);

  var newColor = [];
  for (var n = 0; n < 3; n++) {
    newColor[n] = Math.round((rgbColor1[n] + rgbColor2[n]) / 2);
  }
  return RgbtoHex(newColor);
}

//Alpha blending two colors with two alphas
function alphaBlending(color1, color2, alpha1, alpha2) {
  var rgbColor1 = HexToRgb(arguments[0]);
  var rgbColor2 = HexToRgb(arguments[1]);

  var newColor = [];
  var alpha1 = arguments[2];
  var alpha2 = arguments[3];
  var alpha = 1 - (1 - alpha1) * (1 - alpha2);
  for (var n = 0; n < 3; n++) {
    newColor[n] = Math.round((rgbColor1[n] / 255.0 * alpha1 / alpha + rgbColor2[n] / 255.0 * alpha2 * (1 - alpha1) / alpha) * 255);
  }
  return RgbtoHex(newColor);
}

//Show base color change
$("#color1, #color2").change(function() {
  var color = $(this).val();
  $(this).next().css("background-color", color);
});

//Mix color
$("button").click(function() {
  var color1 = $("#color1").val().substr(1);
  var color2 = $("#color2").val().substr(1);
  var alpha1 = parseFloat($("#alpha1").val());
  var alpha2 = parseFloat($("#alpha2").val());
  var additiveColor = additiveMixing(color1, color2);
  var alphablendColor = alphaBlending(color1, color2, alpha1, alpha2);

  $("#additive span").text("#" + additiveColor);
  $("#additive span").parent().next().css("background-color", "#" + additiveColor);

  $("#alpha span").text("#" + alphablendColor);
  $("#alpha span").parent().next().css("background-color", "#" + alphablendColor);
});
&#13;
.color_block {
  width: 50px;
  height: 20px;
  margin-top: 5px;
  border: 1px solid black;
}
#result {
  position: absolute;
  top: 15px;
  left: 240px;
}
&#13;
&#13;
&#13;

<强>参考:

答案 2 :(得分:1)

ES6 实施:

实际上,我只是在 ES6 中重写了这篇文章的正确答案:

const blender = (color1, color2, percent) => {
  const generateHex = (r, g, b) => {
    let R = r.toString(16);
    let G = g.toString(16);
    let B = b.toString(16);

    while (R.length < 2) {
      R = `0${R}`;
    }
    while (G.length < 2) {
      G = `0${G}`;
    }
    while (B.length < 2) {
      B = `0${B}`;
    }

    return `#${R}${G}${B}`;
  };

  const mix = (start, end, prcnt) => start + prcnt * (end - start);

  const red1 = parseInt(color1[1] + color1[2], 16);
  const green1 = parseInt(color1[3] + color1[4], 16);
  const blue1 = parseInt(color1[5] + color1[6], 16);

  const red2 = parseInt(color2[1] + color2[2], 16);
  const green2 = parseInt(color2[3] + color2[4], 16);
  const blue2 = parseInt(color2[5] + color2[6], 16);

  const red = Math.round(mix(red1, red2, percent));
  const green = Math.round(mix(green1, green2, percent));
  const blue = Math.round(mix(blue1, blue2, percent));

  return generateHex(red, green, blue);
};

blender函数将两种给定的颜色与百分比数字合并,要进行测试,可以使用以下代码:

document.body.style.backgroundColor = blender('#ffffff', '#ff0000', .3);