mirror of
https://github.com/less/less.js.git
synced 2026-01-22 21:58:14 -05:00
color-blending-with-transparency: initial implementation
This commit is contained in:
@@ -367,66 +367,6 @@ tree.functions = {
|
||||
_isa: function (n, Type) {
|
||||
return (n instanceof Type) ? tree.True : tree.False;
|
||||
},
|
||||
|
||||
/* Blending modes */
|
||||
|
||||
multiply: function(color1, color2) {
|
||||
var r = color1.rgb[0] * color2.rgb[0] / 255;
|
||||
var g = color1.rgb[1] * color2.rgb[1] / 255;
|
||||
var b = color1.rgb[2] * color2.rgb[2] / 255;
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
screen: function(color1, color2) {
|
||||
var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
|
||||
var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
|
||||
var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
overlay: function(color1, color2) {
|
||||
var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
|
||||
var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
|
||||
var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
softlight: function(color1, color2) {
|
||||
var t = color2.rgb[0] * color1.rgb[0] / 255;
|
||||
var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
|
||||
t = color2.rgb[1] * color1.rgb[1] / 255;
|
||||
var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
|
||||
t = color2.rgb[2] * color1.rgb[2] / 255;
|
||||
var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
hardlight: function(color1, color2) {
|
||||
var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
|
||||
var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
|
||||
var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
difference: function(color1, color2) {
|
||||
var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
|
||||
var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
|
||||
var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
exclusion: function(color1, color2) {
|
||||
var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
|
||||
var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
|
||||
var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
average: function(color1, color2) {
|
||||
var r = (color1.rgb[0] + color2.rgb[0]) / 2;
|
||||
var g = (color1.rgb[1] + color2.rgb[1]) / 2;
|
||||
var b = (color1.rgb[2] + color2.rgb[2]) / 2;
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
negation: function(color1, color2) {
|
||||
var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
|
||||
var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
|
||||
var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
|
||||
return this.rgb(r, g, b);
|
||||
},
|
||||
tint: function(color, amount) {
|
||||
return this.mix(this.rgb(255,255,255), color, amount);
|
||||
},
|
||||
@@ -637,6 +577,85 @@ for(var i = 0; i < mathFunctions.length; i++) {
|
||||
tree.functions[mathFunctions[i].name] = createMathFunction(mathFunctions[i].name, mathFunctions[i].unit);
|
||||
}
|
||||
|
||||
// Color Blending
|
||||
// ref: http://www.w3.org/TR/compositing-1
|
||||
|
||||
function colorBlend(color1, color2, mode) {
|
||||
var ab = color1.alpha, cb, // backdrop
|
||||
as = color2.alpha, cs, // source
|
||||
ar, cr, r = []; // result
|
||||
|
||||
ar = as + ab * (1 - as);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
cb = color1.rgb[i] / 255;
|
||||
cs = color2.rgb[i] / 255;
|
||||
cr = mode(cb, cs);
|
||||
if (ar > 0) {
|
||||
cr = (as * cs + ab * (cb
|
||||
- as * (cb + cs - cr))) / ar;
|
||||
}
|
||||
r[i] = cr * 255;
|
||||
}
|
||||
|
||||
return new(tree.Color)(r, ar);
|
||||
}
|
||||
|
||||
var colorBlendMode = {
|
||||
multiply: function(cb, cs) {
|
||||
return cb * cs;
|
||||
},
|
||||
screen: function(cb, cs) {
|
||||
return cb + cs - cb * cs;
|
||||
},
|
||||
overlay: function(cb, cs) {
|
||||
cb *= 2;
|
||||
return (cb <= 1)
|
||||
? colorBlendMode.multiply(cb, cs)
|
||||
: colorBlendMode.screen(cb - 1, cs);
|
||||
},
|
||||
softlight: function(cb, cs) {
|
||||
var d = 1, e = cb;
|
||||
if (cs > 0.5) {
|
||||
e = 1;
|
||||
d = (cb > 0.25) ? Math.sqrt(cb)
|
||||
: ((16 * cb - 12) * cb + 4) * cb;
|
||||
}
|
||||
return cb - (1 - 2 * cs) * e * (d - cb);
|
||||
},
|
||||
hardlight: function(cb, cs) {
|
||||
return colorBlendMode.overlay(cs, cb);
|
||||
},
|
||||
difference: function(cb, cs) {
|
||||
return Math.abs(cb - cs);
|
||||
},
|
||||
exclusion: function(cb, cs) {
|
||||
return cb + cs - 2 * cb * cs;
|
||||
},
|
||||
|
||||
// non-w3c functions:
|
||||
average: function(cb, cs) {
|
||||
return (cb + cs) / 2;
|
||||
},
|
||||
negation: function(cb, cs) {
|
||||
return 1 - Math.abs(cb + cs - 1);
|
||||
}
|
||||
};
|
||||
|
||||
function colorBlendInit() {
|
||||
function f(m) {
|
||||
return function(c1, c2) {
|
||||
return colorBlend(c1, c2, m);
|
||||
};
|
||||
}
|
||||
|
||||
for (var m in colorBlendMode) {
|
||||
tree.functions[m] = f(colorBlendMode[m]);
|
||||
}
|
||||
|
||||
} colorBlendInit();
|
||||
|
||||
// ~ End of Color Blending
|
||||
|
||||
function hsla(color) {
|
||||
return tree.functions.hsla(color.h, color.s, color.l, color.a);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
multiply: #ed0000;
|
||||
screen: #f600f6;
|
||||
overlay: #ed0000;
|
||||
softlight: #ff0000;
|
||||
softlight: #fa0000;
|
||||
hardlight: #0000ed;
|
||||
difference: #f600f6;
|
||||
exclusion: #f600f6;
|
||||
|
||||
Reference in New Issue
Block a user