如何创建仅包含绿色,蓝色,橙色和金色值的颜色?

时间:2015-04-29 17:59:48

标签: html css colors rgb hsl

如果知道红色,绿色和蓝色的“重量”,可以使用像

这样的类来创建颜色
.blaRGB {
    color: rgb(128, 128, 128)
}
.blaHSL {
    color: hsl(33%, 34%, 33%)
}

并在HTML中使用它:

<p class="blaRGB">BLA RGB</p>
<p class="blaHSL">BLA HSL</p>

使用上面显示的值,blaRGB为灰色且blaHSL为白色。

但如果想要代表其他颜色的组合,例如绿色,蓝色,橙色和金色,该怎么办?

有没有办法用以下符号来定义这些颜色?

.CyndiLauper {
    color: truecolors(24, 13, 11, 12) 
}

或者color: gbog(24, 13, 11, 12) gbog中的字母分别代表绿色,蓝色,橙色和金色?

目的是使用上面的CSS定义,HTML

<p class="CyndiLauper">These are your True Colors, shining through!</p>

会以这四种颜色的加权组合显示文字。

我相信这可以使用绿色,蓝色,橙色和金色的RGB值进行一些复杂的数学运算,但我不知道如何继续进行。

更新

我意识到这个问题的一个关键组成部分,我最初省略的,是“绿色,蓝色,橙色和金色到底是什么意思”?

要回答这个问题,根据官方"True Colors" website和使用ColorZilla浏览器插件,这些颜色的RGB值是:

green = 15, 167, 73
blue = 0, 152, 215
orange = 243, 123, 38
gold = 255, 230, 101

(实际上它们看起来更像森林绿,道奇蓝,红橙和黄色。)

2 个答案:

答案 0 :(得分:2)

不,你不能。以下是W3 Css Colors定义的链接,其中指出只能使用蓝色,红色和绿色。

编辑:好的,让我澄清一下。从我的理解来看,这本身是不可能的。但是,使用Less和Sass可能会有一些事情可以达到您想要的效果。 Here是关于Less Color函数的一些教程。最有趣的是关于混色的部分:

.box.mix {
    background-color: mix(@blue, @yellow, 50%);
}

然而,你需要探索这个,因为我没有经验。

答案 1 :(得分:2)

根据您使用的颜色模型,有很多种方法可以混合颜色:

以下代码段演示了两种混合方法。最左边的列显示四种原始颜色。下一列显示相同颜色,0.25不透明度,产生半透明颜色。第三列将半透明颜色叠加在一起,相当于alpha合成。

第四栏显示了另一种混合方法。在这里,我们看到了对四种原始颜色中每一种的R,G和B分量进行单独平均的结果。

&#13;
&#13;
var Colors = {
  names: ['green', 'blue', 'orange', 'gold'],
  values: {
    green: { r: 15, g: 167, b: 73 },
    blue: { r: 0, g: 152, b: 215 },
    orange: { r: 243, g: 123, b: 38 },
    gold: { r: 255, g: 230, b: 101 }
  }
};

Colors.toHex2 = function (decimal) {
  var hex = decimal.toString(16);
  return (hex.length == 1 ? '0'+hex : hex);
};

Colors.toColorString = function (value) {
  var g = Colors,
      toHex2 = g.toHex2;
  var parts = [ '#', toHex2(value.r), toHex2(value.g), toHex2(value.b) ];
  return parts.join('');
};

Colors.load = function () {
  var g = Colors,
      names = g.names,
      values = g.values,
      containers = {
        original: document.getElementById('original'),
        translucent: document.getElementById('translucent'),
        layered: document.getElementById('layered'),
        averaged: document.getElementById('averaged')
      },
      averaged = { r: 0, g: 0, b: 0 };
  document.body.style.paddingTop = 10*(1+names.length) + 'px';
  for (var i = 0; i < names.length; ++i) {
    var name = names[i],
        value = values[name],
        color = g.toColorString(value),
        swatch = document.createElement('div'),
        proportion = 1 / names.length;
    swatch.className = 'swatch';
    swatch.style.backgroundColor = color;
    containers.original.appendChild(swatch);

    swatch = swatch.cloneNode();
    swatch.style.opacity = proportion;
    containers.translucent.appendChild(swatch);

    swatch = swatch.cloneNode();
    swatch.style.height = 60 + 10*(names.length-1) + 'px';
    swatch.style.top = 10*(1+i-names.length) + 'px';
    containers.layered.appendChild(swatch);

    averaged.r += proportion * value.r;
    averaged.g += proportion * value.g;
    averaged.b += proportion * value.b;
  }

  swatch = document.createElement('div');
  swatch.className = 'swatch';
  averaged.r = Math.round(averaged.r);
  averaged.g = Math.round(averaged.g);
  averaged.b = Math.round(averaged.b);
  swatch.style.backgroundColor = g.toColorString(averaged);
  containers.averaged.appendChild(swatch);
};

window.onload = Colors.load;
&#13;
body {
  font-family: sans-serif;
  font-size: 24px;
  margin: 0;
  padding-left: 20px;
}
.display {
  width: 120px;
  float: left;
}
.swatch {
  width: 100px;
  height: 60px;
  margin-bottom: 10px;
}
.layered {
  position: relative;
  height: 60px;
}
.layered .swatch {
  position: absolute;
}
&#13;
<div id="original" class="display"></div>

<div id="translucent" class="display"></div>

<div id="layered" class="display layered"></div>

<div id="averaged" class="display"></div>
&#13;
&#13;
&#13;

在上面的演示中,我们让网络浏览器为我们进行alpha合成。我们也可以直接进行alpha合成。图层不透明度等同于Alpha通道,因此我们将每种颜色的Alpha通道设置为颜色的重量。换句话说,如果颜色的权重是25%,我们将其alpha通道设置为0.25。

请注意,alpha通道的范围是0到1.但是,我们的RGB组件范围为0到255.

假设我们混合了这两种颜色:

  • 带有Alpha通道background
  • 的RGB值alpha.background
  • 带有Alpha通道foreground
  • 的RGB值alpha.foreground

我们计算得到的颜色的alpha通道alpha.mix,如下所示:

alpha.mix = 1 - (1-alpha.background)*(1-alpha.foreground);

要计算RGB值mix的R分量,我们这样做:

mix.r = 255 * (foreground.r/255.0 * alpha.foreground/alpha.mix +
        mix.r/255.0 * alpha.background*(1-alpha.foreground)/alpha.mix);

同样对于G组件mix.g和B组件mix.b

下面的代码片段是一个交互式演示,它将alpha合成与并行平均RGB组件的简单方法进行比较。运行代码并使用滑块来查看这两种方法之间的区别。

&#13;
&#13;
var Mixer = {
  color: {
    names: ['green', 'blue', 'orange', 'gold'],
    rgb: {
      green: { r: 15, g: 167, b: 73 },
      blue: { r: 0, g: 152, b: 215 },
      orange: { r: 243, g: 123, b: 38 },
      gold: { r: 255, g: 230, b: 101 }
    }
  },
  style: {
    swatch: { width: 150, height: 90, margin: { right: 15 } },
    slider: { height: 20 },
    handle: { width: 20, height: 34 }
  }
};

Mixer.toHex2 = function (decimal) {
  var hex = decimal.toString(16);
  return (hex.length == 1 ? '0'+hex : hex);
};

Mixer.toCSS = function (rgb) {
  var g = Mixer,
      toHex2 = g.toHex2;
  var parts = [ '#', toHex2(rgb.r), toHex2(rgb.g), toHex2(rgb.b) ];
  return parts.join('');
};

Mixer.toString = function (rgb) {
  return 'rgb(' + [rgb.r, rgb.g, rgb.b].join(', ') + ')';
};

Mixer.makeUnselectable = function (element) {
  element.className += ' unselectable';
  element.ondragstart = element.onselectstart = function (event) {
    event.preventDefault();
  };
};

Mixer.makeElement = function (tag, className, innerHTML, unselectable) {
  var g = Mixer,
      element = document.createElement(tag);
  element.className = (className ? className : '');
  element.innerHTML = (innerHTML ? innerHTML : '');
  if (unselectable) {
    g.makeUnselectable(element);
  }
  return element;
};

Mixer.handleDown = function (event) {
  event = event || window.event;
  var g = Mixer;
  g.mouseX = { depart: event.screenX };
  g.activeHandle = this;
  window.onmousemove = Mixer.handleMove;
  window.onmouseup = Mixer.handleUp;
};
Mixer.handleMove = function (event) {
  event = event || window.event;
  var g = Mixer,
      handle = g.activeHandle,
      pos = handle.pos,
      handles = g.handles,
      num = g.num,
      slider = g.slider,
      proportion = g.proportion,
      segments = g.segments,
      handleWidth = g.style.handle.width,
      swatches = g.swatches,
      canvas = g.canvas,
      context = g.context,
      mixingFunctions = g.mixingFunctions,
      limit = {
        min: (pos == 0 ? 0 : handles[pos-1].right),
        max: (pos == num-2 ? slider.length.total : handles[pos+1].left) -
            handleWidth
      },
      mouseX = g.mouseX;
  mouseX.current = event.screenX;
  var left = handle.left + mouseX.current - mouseX.depart;
  if (left < limit.min) {
    left = limit.min;
  }
  if (left > limit.max) {
    left = limit.max;
  }
  handle.newLeft = left;
  segments[pos] = left - limit.min;
  context.fillStyle = swatches[pos].css;
  context.fillRect(limit.min, 0, segments[pos], canvas.height);
  segments[pos+1] = limit.max - left;
  context.fillStyle = swatches[pos+1].css;
  context.fillRect(left + handleWidth, 0, segments[pos+1], canvas.height);
  handle.style.left = left + 'px';
  var segmentSpan = segments[pos] + segments[pos+1],
      proportionSpan = proportion[pos] + proportion[pos+1];
  if (segmentSpan != 0) {
    proportion[pos] = Math.round(segments[pos]/segmentSpan * proportionSpan);
    proportion[pos+1] = proportionSpan - proportion[pos];
    swatches[pos].percent.innerHTML = proportion[pos] + '%';
    swatches[pos+1].percent.innerHTML = proportion[pos+1] + '%';
  }
  g.mixColors();
};
Mixer.handleUp = function (event) {
  var g = Mixer,
      handle = g.activeHandle;
  window.onmousemove = null;
  window.onmouseup = null;
  handle.left = handle.newLeft;
  handle.right = handle.left + g.style.handle.width;
};

Mixer.makeFunctionName = function (title) {
  var parts = ['mix'],
      tokens = title.split(' ');
  for (var i = 0; i < tokens.length; ++i) {
    var token = tokens[i];
    parts.push(token[0].toUpperCase() + token.substring(1));
  }
  return parts.join('');
};

Mixer.mixAlphaCompositing = function (swatch, label) {
  return function () {
    var g = Mixer,
        swatches = g.swatches,
        proportion = g.proportion,
        num = g.num,
        mix = {},
        subs = ['r', 'g', 'b'];
    for (var i = 0; i < subs.length; ++i) {
      var x = subs[i];
      mix[x] = swatches[0].rgb[x];
    }
    var alpha = { back: proportion[0]/100 };
    for (var pos = 1; pos < num; ++pos) {
      var fore = swatches[pos].rgb;
      alpha.fore = proportion[pos]/100,
      alpha.mix = 1 - (1-alpha.back)*(1-alpha.fore);
      if (alpha.mix >= 1.0e-6) {
        for (var i = 0; i < subs.length; ++i) {
          var x = subs[i];
          mix[x] = 255 * (fore[x]/255 * alpha.fore/alpha.mix +
              mix[x]/255 * alpha.back*(1-alpha.fore)/alpha.mix);
        }
      }
      alpha.back = alpha.mix;
    }
    for (var i = 0; i < subs.length; ++i) {
      var x = subs[i];
      mix[x] = Math.round(mix[x]);
    }
    var css = g.toCSS(mix);
    label.rgb.innerHTML = g.toString(mix);
    label.css.innerHTML = css;
    swatch.style.backgroundColor = css;
    swatch.style.opacity = alpha.mix;
  };
};

Mixer.mixWeightedAverage = function (swatch, label) {
  return function () {
    var g = Mixer,
        swatches = g.swatches,
        proportion = g.proportion,
        num = g.num,
        mix = { r: 0, g: 0, b: 0 },
        subs = ['r', 'g', 'b'];
    for (var pos = 0; pos < num; ++pos) {
      for (var i = 0; i < subs.length; ++i) {
        var x = subs[i];
        mix[x] += proportion[pos]/100 * swatches[pos].rgb[x];
      }
    }
    for (var i = 0; i < subs.length; ++i) {
      var x = subs[i];
      mix[x] = Math.round(mix[x]);
    }
    var css = g.toCSS(mix);
    label.rgb.innerHTML = g.toString(mix);
    label.css.innerHTML = css;
    swatch.style.backgroundColor = css;
  };
};

Mixer.mixColors = function () {
  var g = Mixer,
      mixingFunctions = g.mixingFunctions;
  for (var i = 0; i < mixingFunctions.length; ++i) {
    mixingFunctions[i]();
  }
};

Mixer.load = function () {
  var g = Mixer,
      style = g.style;

  // Make color swatches.
  var palette = g.palette = document.getElementById('palette'),
      names = g.color.names,
      swatches = g.swatches = [],
      num = g.num = names.length;
  for (var i = 0; i < num; ++i) {
    var name = names[i],
        rgb = g.color.rgb[name],
        css = g.toCSS(rgb),
        container = g.makeElement('div', 'swatchContainer', '', true),
        percent = g.makeElement('div', 'title', '', true),
        swatch = g.makeElement('div', 'swatch', '', true);
    swatches[i] = { rgb: rgb, css: css, percent: percent };
    container.appendChild(percent);
    swatch.style.backgroundColor = css;
    swatch.style.width = style.swatch.width + 'px';
    swatch.style.height = style.swatch.height + 'px';
    swatch.style.marginRight = style.swatch.margin.right + 'px';
    container.appendChild(swatch);
    container.appendChild(g.makeElement('div', 'label', g.toString(rgb), true));
    container.appendChild(g.makeElement('div', 'label', css, true));
    palette.appendChild(container);
  }
  var totalWidth = num*style.swatch.width + (num-1)*style.swatch.margin.right;

  // Initialize proportions.
  var proportion = g.proportion = new Array(num),
      each = Math.floor(100/num);
  for (var i = 0; i < num-1; ++i) {
    proportion[i] = each;
  }
  proportion[num-1] = 100 - (num-1)*each;
  for (var i = 0; i < num; ++i) {
    swatches[i].percent.innerHTML = proportion[i] + '%';
  }

  // Prepare the blended swatches.
  var blend = g.blend = { container: document.getElementById('blend') },
      mixers = ['alpha compositing', 'weighted average'],
      between = (totalWidth - mixers.length*style.swatch.width) /
          (mixers.length + 1);
  g.makeUnselectable(blend);
  blend.container.style.width = totalWidth + 'px';
  blend.container.style.height = style.swatch.height + 'px';
  g.mixingFunctions = [];
  for (var i = 0; i < mixers.length; ++i) {
    var mixer = mixers[i],
        container = g.makeElement('div', 'swatchContainer', '', true),
        title = g.makeElement('div', 'title', mixer, true),
        swatch = g.makeElement('div', 'swatch', '', true),
        label = {
          rgb: g.makeElement('div', 'label', '', true),
          css: g.makeElement('div', 'label', '', true)
        };
    swatch.style.width = style.swatch.width + 'px';
    swatch.style.height = style.swatch.height + 'px';
    container.style.left = i*style.swatch.width + (i+1)*between + 'px';
    container.appendChild(title);
    container.appendChild(swatch);
    container.appendChild(label.rgb);
    container.appendChild(label.css);
    blend.container.appendChild(container);
    var functionName = g.makeFunctionName(mixer),
        mixingFunction = g[functionName](swatch, label);
    g.mixingFunctions.push(mixingFunction);
  }

  // Assemble the slider widget.
  var slider = g.slider = document.getElementById('slider');
  slider.length = {
    total: totalWidth,
    free: totalWidth - (num-1)*style.handle.width
  };
  var segments = g.segments = new Array(num);
  var tail = slider.length.free;
  for (var i = 0; i < num-1; ++i) {
    var current = Math.round(proportion[i]/100*slider.length.free);
    segments[i] = current;
    tail -= current;
  }
  segments[num-1] = tail;
  slider.style.width = slider.length.total + 'px';
  slider.style.height = style.slider.height + 'px';
  var canvas = g.canvas = g.makeElement('canvas'),
      context = g.context = canvas.getContext('2d');
  g.makeUnselectable(slider);
  g.makeUnselectable(canvas);
  canvas.width = slider.length.total;
  canvas.height = style.slider.height;
  slider.appendChild(canvas);
  var handles = g.handles = new Array(num-1);
  var left = 0;
  for (var i = 0; i < num; ++i) {
    context.fillStyle = swatches[i].css;
    context.fillRect(left, 0, segments[i], canvas.height);
    if (i == num-1) {
      break;
    }
    var handle = handles[i] = g.makeElement('div', 'handle', '', true);
    handle.pos = i;
    handle.style.width = style.handle.width + 'px';
    handle.style.height = style.handle.height + 'px';
    handle.style.top = (style.slider.height - style.handle.height)/2 + 'px';
    handle.left = left + segments[i];
    handle.style.left = handle.left + 'px';
    handle.right = handle.left + style.handle.width;
    left = handle.right;
    handle.onmousedown = g.handleDown;
    slider.appendChild(handle);
  }

  g.mixColors();
};

window.onload = Mixer.load;
&#13;
body {
  font-family: sans-serif;
  color: #444;
}

.unselectable {
  -webkit-user-select: none;
  -khtml-user-drag: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -moz-user-select: -moz-none;
  -ms-user-select: none;
  user-select: none;
}

#blend {
  position: relative;
  padding: 10px 0 90px;
}
#blend .swatchContainer {
  position: absolute;
}
#blend .swatchContainer .title {
  font-size: 17px;
  padding-bottom: 5px;
}

#slider {
  margin: 20px 0;
  position: relative;
}
.handle {
  position: absolute;
  background: #444;
  border-radius: 5px;
  cursor: pointer;
}

.swatchContainer {
  float: left;
}
.swatchContainer .title {
  font-size: 25px;
  text-align: center;
}
.swatchContainer .label {
  font-size: 17px;
}
&#13;
<div id="blend"></div>

<div id="slider"></div>

<div id="palette"></div>
&#13;
&#13;
&#13;