foregroundTone static method

double foregroundTone(
  1. double bgTone,
  2. double ratio
)

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 lighterTone = Contrast.lighterUnsafe(tone: bgTone, ratio: ratio);
  final darkerTone = Contrast.darkerUnsafe(tone: bgTone, ratio: ratio);
  final lighterRatio = Contrast.ratioOfTones(lighterTone, bgTone);
  final darkerRatio = Contrast.ratioOfTones(darkerTone, bgTone);
  final 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 negligibleDifference = ((lighterRatio - darkerRatio).abs() < 0.1 &&
        lighterRatio < ratio &&
        darkerRatio < ratio);
    return lighterRatio >= ratio ||
            lighterRatio >= darkerRatio ||
            negligibleDifference
        ? lighterTone
        : darkerTone;
  } else {
    return darkerRatio >= ratio || darkerRatio >= lighterRatio
        ? darkerTone
        : lighterTone;
  }
}