foregroundTone static method
Given a background tone, find a foreground tone, while ensuring they reach
a contrast ratio that is as close to ratio
as possible.
bgTone
Tone in HCT. Range is 0 to 100, undefined behavior when it falls
outside that range.
ratio
The contrast ratio desired between bgTone
and the return value.
Implementation
static double foregroundTone(double bgTone, double ratio) {
final double lighterTone =
Contrast.lighterUnsafe(tone: bgTone, ratio: ratio);
final double darkerTone = Contrast.darkerUnsafe(tone: bgTone, ratio: ratio);
final double lighterRatio = Contrast.ratioOfTones(lighterTone, bgTone);
final double darkerRatio = Contrast.ratioOfTones(darkerTone, bgTone);
final bool preferLighter = tonePrefersLightForeground(bgTone);
if (preferLighter) {
// This handles an edge case where the initial contrast ratio is high
// (ex. 13.0), and the ratio passed to the function is that high ratio,
// and both the lighter and darker ratio fails to pass that ratio.
//
// This was observed with Tonal Spot's On Primary Container turning black
// momentarily between high and max contrast in light mode.
// PC's standard tone was T90, OPC's was T10, it was light mode, and the
// contrast value was 0.6568521221032331.
final bool negligibleDifference =
(lighterRatio - darkerRatio).abs() < 0.1 &&
lighterRatio < ratio &&
darkerRatio < ratio; // coverage:ignore-line
return lighterRatio >= ratio ||
lighterRatio >= darkerRatio ||
negligibleDifference
? lighterTone
: darkerTone;
} else {
return darkerRatio >= ratio || darkerRatio >= lighterRatio
? darkerTone
: lighterTone;
}
}