Move some accessibility helpers to Color
This commit is contained in:
parent
437a2826ea
commit
5510675f15
2 changed files with 21 additions and 21 deletions
|
|
@ -202,6 +202,22 @@ impl Color {
|
|||
let linear = self.into_linear();
|
||||
0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2]
|
||||
}
|
||||
|
||||
/// Returns the [relative contrast ratio] of the [`Color`] against another one.
|
||||
///
|
||||
/// [relative contrast ratio]: https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
|
||||
pub fn relative_contrast(self, b: Color) -> f32 {
|
||||
let lum_a = self.relative_luminance();
|
||||
let lum_b = b.relative_luminance();
|
||||
|
||||
(lum_a.max(lum_b) + 0.05) / (lum_a.min(lum_b) + 0.05)
|
||||
}
|
||||
|
||||
/// Returns true if the current [`Color`] is readable on top
|
||||
/// of the given background [`Color`].
|
||||
pub fn is_readable_on(self, background: Color) -> bool {
|
||||
background.relative_contrast(self) >= 6.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[f32; 3]> for Color {
|
||||
|
|
|
|||
|
|
@ -690,7 +690,7 @@ pub fn mix(a: Color, b: Color, factor: f32) -> Color {
|
|||
/// Computes a [`Color`] from the given text color that is
|
||||
/// readable on top of the given background color.
|
||||
pub fn readable(background: Color, text: Color) -> Color {
|
||||
if is_readable(background, text) {
|
||||
if text.is_readable_on(background) {
|
||||
return text;
|
||||
}
|
||||
|
||||
|
|
@ -699,18 +699,18 @@ pub fn readable(background: Color, text: Color) -> Color {
|
|||
// TODO: Compute factor from relative contrast value
|
||||
let candidate = improve(text, 0.1);
|
||||
|
||||
if is_readable(background, candidate) {
|
||||
if candidate.is_readable_on(background) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
let candidate = improve(text, 0.2);
|
||||
|
||||
if is_readable(background, candidate) {
|
||||
if candidate.is_readable_on(background) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
let white_contrast = relative_contrast(background, Color::WHITE);
|
||||
let black_contrast = relative_contrast(background, Color::BLACK);
|
||||
let white_contrast = background.relative_contrast(Color::WHITE);
|
||||
let black_contrast = background.relative_contrast(Color::BLACK);
|
||||
|
||||
if white_contrast >= black_contrast {
|
||||
mix(Color::WHITE, background, 0.05)
|
||||
|
|
@ -724,22 +724,6 @@ pub fn is_dark(color: Color) -> bool {
|
|||
to_oklch(color).l < 0.6
|
||||
}
|
||||
|
||||
/// Returns true if text with the given [`Color`] is readable on top
|
||||
/// of the given background [`Color`].
|
||||
pub fn is_readable(background: Color, text: Color) -> bool {
|
||||
relative_contrast(background, text) >= 6.0
|
||||
}
|
||||
|
||||
/// Returns the [relative contrast ratio] of two colors.
|
||||
///
|
||||
/// [relative contrast ratio]: https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
|
||||
pub fn relative_contrast(a: Color, b: Color) -> f32 {
|
||||
let lum_a = a.relative_luminance();
|
||||
let lum_b = b.relative_luminance();
|
||||
|
||||
(lum_a.max(lum_b) + 0.05) / (lum_a.min(lum_b) + 0.05)
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/Oklab_color_space#Conversions_between_color_spaces
|
||||
fn to_oklch(color: Color) -> Oklch {
|
||||
let [r, g, b, alpha] = color.into_linear();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue