如果知道红色,绿色和蓝色的“重量”,可以使用像
这样的类来创建颜色.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
(实际上它们看起来更像森林绿,道奇蓝,红橙和黄色。)
答案 0 :(得分:2)
编辑:好的,让我澄清一下。从我的理解来看,这本身是不可能的。但是,使用Less和Sass可能会有一些事情可以达到您想要的效果。 Here是关于Less Color函数的一些教程。最有趣的是关于混色的部分:
.box.mix {
background-color: mix(@blue, @yellow, 50%);
}
然而,你需要探索这个,因为我没有经验。
答案 1 :(得分:2)
根据您使用的颜色模型,有很多种方法可以混合颜色:
以下代码段演示了两种混合方法。最左边的列显示四种原始颜色。下一列显示相同颜色,0.25不透明度,产生半透明颜色。第三列将半透明颜色叠加在一起,相当于alpha合成。
第四栏显示了另一种混合方法。在这里,我们看到了对四种原始颜色中每一种的R,G和B分量进行单独平均的结果。
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;
在上面的演示中,我们让网络浏览器为我们进行alpha合成。我们也可以直接进行alpha合成。图层不透明度等同于Alpha通道,因此我们将每种颜色的Alpha通道设置为颜色的重量。换句话说,如果颜色的权重是25%,我们将其alpha通道设置为0.25。
请注意,alpha通道的范围是0到1.但是,我们的RGB组件范围为0到255.
假设我们混合了这两种颜色:
background
alpha.background
foreground
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组件的简单方法进行比较。运行代码并使用滑块来查看这两种方法之间的区别。
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;