diff --git a/.changeset/set-preserve-alpha.md b/.changeset/set-preserve-alpha.md new file mode 100644 index 00000000..aededaf8 --- /dev/null +++ b/.changeset/set-preserve-alpha.md @@ -0,0 +1,5 @@ +--- +"chroma-js": patch +--- + +Preserve opacity when setting an individual color channel. diff --git a/src/ops/set.js b/src/ops/set.js index e4a56fc6..2d2cfd17 100644 --- a/src/ops/set.js +++ b/src/ops/set.js @@ -29,7 +29,7 @@ Color.prototype.set = function (mc, value, mutate = false) { } else { throw new Error(`unsupported value for Color.set`); } - const out = new Color(src, mode); + const out = new Color(src, mode).alpha(this.alpha(), true); if (mutate) { this._rgb = out._rgb; return this; diff --git a/test/alpha.test.js b/test/alpha.test.js index 1553915d..d067d2cf 100644 --- a/test/alpha.test.js +++ b/test/alpha.test.js @@ -2,6 +2,37 @@ import { describe, it, expect } from 'vitest'; import chroma from 'chroma-js'; describe('Tests for the alpha channel', () => { + describe.each([ + ['rgb.r', 128], + ['hsv.h', 120], + ['hsi.h', 120], + ['cmyk.c', 0.5], + ['hsl.h', 120], + ['lab.l', 50] + ])('setting %s', (channel, value) => { + it.each([0, 0.4, 1])('preserves alpha %s in a new color', (alpha) => { + const color = chroma('red').alpha(alpha); + const rgba = color.rgba(); + const result = color.set(channel, value); + expect(result.alpha()).toBe(alpha); + expect(result.rgb()).toEqual(chroma('red').set(channel, value).rgb()); + expect(result).not.toBe(color); + expect(color.rgba()).toEqual(rgba); + }); + + it.each([0, 0.4, 1])('preserves alpha %s when mutating', (alpha) => { + const color = chroma('red').alpha(alpha); + const result = color.set(channel, value, true); + expect(result.alpha()).toBe(alpha); + expect(result.rgb()).toEqual(chroma('red').set(channel, value).rgb()); + expect(result).toBe(color); + }); + }); + + it('preserves alpha in a relative channel change', () => { + expect(chroma('red').alpha(0.4).set('rgb.r', '*0.5').rgba()).toEqual([128, 0, 0, 0.4]); + }); + it('setting & getting alpha channel', () => { const color = chroma('red'); expect(color.alpha()).toBe(1);