@@ -150,15 +150,42 @@ export namespace rgb {
150150 * Helper functions where the source type is "rgba" (number: 0xrrggbbaa).
151151 */
152152export 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