Skip to content

Commit 2fa1259

Browse files
authored
Merge pull request #3806 from Tyriar/3720
Allow ensureContrastRatio to change luminance the other way
2 parents a38e97f + de03391 commit 2fa1259

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

src/common/Color.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,42 @@ export namespace rgb {
150150
* Helper functions where the source type is "rgba" (number: 0xrrggbbaa).
151151
*/
152152
export namespace rgba {
153+
/**
154+
* Given a foreground color and a background color, either increase or reduce the luminance of the
155+
* foreground color until the specified contrast ratio is met. If pure white or black is hit
156+
* without the contrast ratio being met, go the other direction using the background color as the
157+
* foreground color and take either the first or second result depending on which has the higher
158+
* contrast ratio.
159+
*
160+
* `undefined` will be returned if the contrast ratio is already met.
161+
*
162+
* @param bgRgba The background color in rgba format.
163+
* @param fgRgba The foreground color in rgba format.
164+
* @param ratio The contrast ratio to achieve.
165+
*/
153166
export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {
154167
const bgL = rgb.relativeLuminance(bgRgba >> 8);
155168
const fgL = rgb.relativeLuminance(fgRgba >> 8);
156169
const cr = contrastRatio(bgL, fgL);
157170
if (cr < ratio) {
158171
if (fgL < bgL) {
159-
return reduceLuminance(bgRgba, fgRgba, ratio);
172+
const resultA = reduceLuminance(bgRgba, fgRgba, ratio);
173+
const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));
174+
if (resultARatio < ratio) {
175+
const resultB = increaseLuminance(bgRgba, bgRgba, ratio);
176+
const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));
177+
return resultARatio > resultBRatio ? resultA : resultB;
178+
}
179+
return resultA;
180+
}
181+
const resultA = increaseLuminance(bgRgba, fgRgba, ratio);
182+
const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));
183+
if (resultARatio < ratio) {
184+
const resultB = reduceLuminance(bgRgba, bgRgba, ratio);
185+
const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));
186+
return resultARatio > resultBRatio ? resultA : resultB;
160187
}
161-
return increaseLuminance(bgRgba, fgRgba, ratio);
188+
return resultA;
162189
}
163190
return undefined;
164191
}

0 commit comments

Comments
 (0)