Skip to content

Interpolate MixOklab, Lerp and Gradient premultiplied, so a transparent end adds no color [minor] - #528

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/526-premultiplied-interpolation
Nov 4, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/526-premultiplied-interpolation

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #526

What changed

  • MixOklab now weights each color's L/a/b by its alpha, and Lerp weights its linear R/G/B the same way. Both divide by the mixed alpha afterwards, as CSS Color 4 §12.3 specifies. Gradient goes through MixOklab, so it picks up the fix too.
  • When the mixed alpha is 0, the result is transparent black.
  • Two opaque inputs give alpha 1, so their results are unchanged.
  • The <remarks> now say interpolation is premultiplied. Colors are still stored with straight alpha.

Results

Call Before After
Transparent.MixOklab(White, 0.5) #63636380 #FFFFFF80
Transparent.Lerp(White, 0.5) #BCBCBC80 #FFFFFF80
Transparent.Gradient(White, 5) #00000000 #22222240 #63636380 #AEAEAEBF #FFFFFF #00000000 #FFFFFF40 #FFFFFF80 #FFFFFFBF #FFFFFF
Red.WithAlpha(0).MixOklab(Blue, 0.5) #8C53A280 #0000FF80

Tests

  • Added five tests to ColorGamutAndAlphaTests: mixing from Transparent in both directions, a fade-in gradient, an invisible end, two transparent ends, and an opaque control.
  • Reverting Color.Operations.cs makes four of them fail. The opaque control passes both ways, which shows opaque mixes did not change.
  • Full Semantics.Test: 1967 passed, 14 skipped, 0 failed.

This changes behavior, so the commit is tagged [minor].


Generated by Claude Code

…nt end adds no color [minor]

Each color's channels now count in proportion to its alpha, as CSS Color 4
specifies, so Transparent.MixOklab(White, 0.5) is #FFFFFF80 rather than
#63636380 and a fade-in from Transparent no longer passes through dark grey.
A result with alpha 0 is transparent black. Opaque inputs mix as before.

Fixes #526

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW5AXVu7aN3GSXPwGnx
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit ec894c6 into main Nov 4, 2026
16 checks passed
@matt-edmondson
matt-edmondson deleted the fix/526-premultiplied-interpolation branch November 4, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants