Skip to content

Commit

Permalink
fix(mix): Fix algorithm directly instead of returning early
Browse files Browse the repository at this point in the history
Correctly handles the edge cases of bug #408. Based on the updated implementation in dart-sass: https://github.com/sass/dart-sass/blob/169178af6c6414d01bc66144b437701057ff3684/lib/src/functions/color.dart#L800-L838
  • Loading branch information
delucis committed Jan 1, 2022
1 parent dbed562 commit 9320430
Showing 1 changed file with 6 additions and 7 deletions.
13 changes: 6 additions & 7 deletions src/mix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import rgba from './rgba';
* Mixes two colors together. Taken from sass's implementation.
*/
function mix(color1: string, color2: string, weight: number): string {
if (weight <= 0) return rgba(...parseToRgba(color1));
if (weight >= 1) return rgba(...parseToRgba(color2));

const normalize = (n: number, index: number) =>
// 3rd index is alpha channel which is already normalized
index === 3 ? n : n / 255;
Expand All @@ -18,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;
Expand Down

0 comments on commit 9320430

Please sign in to comment.