diff --git a/packages/keybr-color/lib/mix.test.ts b/packages/keybr-color/lib/mix.test.ts index 8f057ca4..50216ffe 100644 --- a/packages/keybr-color/lib/mix.test.ts +++ b/packages/keybr-color/lib/mix.test.ts @@ -8,7 +8,7 @@ test("mix", () => { const b = hexColor(0xff8000); equal(mixColors(a, b, -100.0).hex(), 0x0080ff); equal(mixColors(a, b, 0.0).hex(), 0x0080ff); - equal(mixColors(a, b, 0.5).hex(), 0x808080); + equal(mixColors(a, b, 0.5).hex(), 0xbc80bc); equal(mixColors(a, b, 1.0).hex(), 0xff8000); equal(mixColors(a, b, 100.0).hex(), 0xff8000); }); diff --git a/packages/keybr-color/lib/mix.ts b/packages/keybr-color/lib/mix.ts index 60fb9c81..ddf3a837 100644 --- a/packages/keybr-color/lib/mix.ts +++ b/packages/keybr-color/lib/mix.ts @@ -1,16 +1,23 @@ import { clamp } from "@keybr/lang"; import { RgbColor } from "./color-rgb.ts"; +import { rgbGammaToLinear, rgbLinearToGamma } from "./convert-xyz.ts"; import { type Rgb } from "./types.ts"; +const u: Rgb = { r: 0, g: 0, b: 0, alpha: 1 }; +const v: Rgb = { r: 0, g: 0, b: 0, alpha: 1 }; + export function mixColors( a: Readonly, b: Readonly, - n: number, + r: number, ): RgbColor { - n = clamp(n, 0, 1); - return new RgbColor( - (b.r - a.r) * n + a.r, - (b.g - a.g) * n + a.g, - (b.b - a.b) * n + a.b, - ); + r = clamp(r, 0, 1); + rgbGammaToLinear(a, u); + rgbGammaToLinear(b, v); + u.r = (v.r - u.r) * r + u.r; + u.g = (v.g - u.g) * r + u.g; + u.b = (v.b - u.b) * r + u.b; + u.alpha = (v.alpha - u.alpha) * r + u.alpha; + rgbLinearToGamma(u, v); + return new RgbColor(v.r, v.g, v.b, v.alpha); }