Skip to content

Commit 7ab4d00

Browse files
authored
Fixes Tint, Shade, and Contrast Alpha Interference Issue (#26)
* Fixes an issue where the tint, shade, and contrast adjusters incorrectly modified the alpha value of the base color.
1 parent 08f8b23 commit 7ab4d00

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

lib/adjusters.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,18 @@ exports.blackness = exports.b = hslwbAdjuster('blackness');
3636
*/
3737

3838
exports.blend = function (color, args) {
39+
var targetAlpha = color.alpha();
40+
41+
// Reset the alpha value to one. This is required because color.mix mixes
42+
// the alpha value as well as rgb values. For blend() purposes, that's not
43+
// what we want.
44+
color.alpha(1);
45+
3946
var other = new Color(args[0].value);
4047
var percentage = 1 - parseInt(args[1].value, 10) / 100;
41-
color.mix(other, percentage);
48+
49+
// Finally set the alpha value of the mixed color to the target value.
50+
color.mix(other, percentage).alpha(targetAlpha);
4251
};
4352

4453
/**
@@ -79,7 +88,11 @@ exports.contrast = function (color, args) {
7988
var minRatio = 4.5;
8089
if (color.contrast(max) > minRatio) {
8190
var min = binarySearchBWContrast(minRatio, color, max);
82-
min.mix(max, percentage);
91+
var targetMinAlpha = min.alpha();
92+
// Set the alpha to 1 to avoid mix()-ing the alpha value.
93+
min.alpha(1);
94+
// mixes the colors then sets the alpha back to the target alpha.
95+
min.mix(max, percentage).alpha(targetMinAlpha);
8396
}
8497
color.hwb(min.hwb());
8598
};

test/convert.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,32 @@ describe('#convert', function () {
275275
});
276276
});
277277

278+
describe('tint with alpha', function () {
279+
it('should blend a color with white and adjust the alpha', function () {
280+
convert('red a(40%) tint(50%)', 'rgba(255, 128, 128, 0.4)');
281+
});
282+
283+
it('should blend a color with white and adjust the alpha', function () {
284+
convert('red tint(50%) a(20%)', 'rgba(255, 128, 128, 0.2)');
285+
});
286+
});
287+
278288
describe('shade', function () {
279289
it('should blend a color with black', function () {
280290
convert('red shade(50%)', 'rgb(128, 0, 0)');
281291
});
282292
});
283293

294+
describe('shade with alpha', function () {
295+
it('should blend a color with black and adjust the alpha', function () {
296+
convert('red a(40%) shade(50%)', 'rgba(128, 0, 0, 0.4)');
297+
});
298+
299+
it('should blend a color with black and adjust the alpha', function () {
300+
convert('red shade(50%) a(25%)', 'rgba(128, 0, 0, 0.25)');
301+
});
302+
});
303+
284304
describe('contrast', function () {
285305
it('should darken the same hue with a light color', function () {
286306
convert('hwb(180, 10%, 0%) contrast(0%)', 'rgb(13, 115, 115)'); // hwb(180, 5%, 55%)
@@ -299,6 +319,16 @@ describe('#convert', function () {
299319
});
300320
});
301321

322+
describe('contrast with alpha', function () {
323+
it('should go to white with a dark color and the given alpha', function() {
324+
convert('black a(40%) contrast(99%)', 'rgba(255, 255, 255, 0.4)');
325+
});
326+
327+
it('should go to black with a light color and the given alpha', function() {
328+
convert('white a(50%) contrast(99%)', 'rgba(0, 0, 0, 0.5)');
329+
});
330+
});
331+
302332
describe('nested color functions', function () {
303333
it('should convert nested color functions', function () {
304334
convert('color(rebeccapurple a(- 10%)) a(- 10%)', 'rgba(102, 51, 153, 0.81)');

0 commit comments

Comments
 (0)