create method
Creates a key color from a hue and a requestedChroma. The key color is the first tone, starting from T50, matching the given hue and chroma.
@return Key color Hct
Implementation
Hct create() {
// Pivot around T50 because T50 has the most chroma available, on
// average. Thus it is most likely to have a direct answer.
const pivotTone = 50;
const toneStepSize = 1;
// Epsilon to accept values slightly higher than the requested chroma.
const epsilon = 0.01;
// Binary search to find the tone that can provide a chroma that is closest
// to the requested chroma.
var lowerTone = 0;
var upperTone = 100;
while (lowerTone < upperTone) {
final midTone = (lowerTone + upperTone) ~/ 2;
final isAscending =
_maxChroma(midTone) < _maxChroma(midTone + toneStepSize);
final sufficientChroma = _maxChroma(midTone) >= requestedChroma - epsilon;
if (sufficientChroma) {
// Either range [lowerTone, midTone] or [midTone, upperTone] has
// the answer, so search in the range that is closer the pivot tone.
if ((lowerTone - pivotTone).abs() < (upperTone - pivotTone).abs()) {
upperTone = midTone;
} else {
if (lowerTone == midTone) {
return Hct.from(hue, requestedChroma, lowerTone.toDouble());
}
lowerTone = midTone;
}
} else {
// As there is no sufficient chroma in the midTone, follow the direction
// to the chroma peak.
if (isAscending) {
lowerTone = midTone + toneStepSize;
} else {
// Keep midTone for potential chroma peak.
upperTone = midTone;
}
}
}
return Hct.from(hue, requestedChroma, lowerTone.toDouble());
}