diff --git a/src/mix.test.ts b/src/mix.test.ts index a357f25..e9f2804 100644 --- a/src/mix.test.ts +++ b/src/mix.test.ts @@ -51,3 +51,15 @@ test('mix blue and green', () => { ); expect(mix('blue', 'green', 1)).toMatchInlineSnapshot(`"rgba(0, 128, 0, 1)"`); }); + +test('mix with transparent and weight 0%', () => { + expect(mix('transparent', 'blue', 0)).toMatchInlineSnapshot( + `"rgba(0, 0, 0, 0)"` + ); +}); + +test('mix with transparent and weight 100%', () => { + expect(mix('red', 'rgba(255, 0, 0, 0)', 1)).toMatchInlineSnapshot( + `"rgba(255, 0, 0, 0)"` + ); +}); diff --git a/src/mix.ts b/src/mix.ts index 274975b..b7a2fe4 100644 --- a/src/mix.ts +++ b/src/mix.ts @@ -15,10 +15,12 @@ function mix(color1: string, color2: string, weight: number): string { // The formula is copied from the original Sass implementation: // http://sass-lang.com/documentation/Sass/Script/Functions.html#mix-instance_method const alphaDelta = a2 - a1; - const x = weight * 2 - 1; - const y = x * alphaDelta === -1 ? x : x + alphaDelta; - const z = 1 + x * alphaDelta; - const weight2 = (y / z + 1) / 2.0; + const normalizedWeight = weight * 2 - 1; + const combinedWeight = + normalizedWeight * alphaDelta === -1 + ? normalizedWeight + : normalizedWeight + alphaDelta / (1 + normalizedWeight * alphaDelta); + const weight2 = (combinedWeight + 1) / 2; const weight1 = 1 - weight2; const r = (r1 * weight1 + r2 * weight2) * 255;