Skip to content

Commit 032d0c8

Browse files
authored
fix(color-generator): contrast color calculation (#3274)
* fix(color-generator): contrast color calculation * refactor: apply types and code style
1 parent c6807ac commit 032d0c8

File tree

1 file changed

+27
-2
lines changed
  • src/components/page/theming/_utils

1 file changed

+27
-2
lines changed

src/components/page/theming/_utils/color.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,28 @@ const rgbToYIQ = ({ r, g, b }: RGB): number => {
133133
return (r * 299 + g * 587 + b * 114) / 1000;
134134
};
135135

136+
const RED = 0.2126;
137+
const GREEN = 0.7152;
138+
const BLUE = 0.0722;
139+
const GAMMA = 2.4;
140+
141+
const luminance = ({ r, g, b }: RGB) => {
142+
const a = [r, g, b].map((v) => {
143+
v /= 255;
144+
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, GAMMA);
145+
});
146+
return a[0] * RED + a[1] * GREEN + a[2] * BLUE;
147+
};
148+
149+
// Original source: https://stackoverflow.com/a/9733420
150+
const contrast = (rgb1: RGB, rgb2: RGB) => {
151+
const lum1 = luminance(rgb1);
152+
const lum2 = luminance(rgb2);
153+
const brightest = Math.max(lum1, lum2);
154+
const darkest = Math.min(lum1, lum2);
155+
return (brightest + 0.05) / (darkest + 0.05);
156+
};
157+
136158
export class Color {
137159
readonly hex: string;
138160
readonly hsl: HSL;
@@ -176,8 +198,11 @@ export class Color {
176198
return /(^#[0-9a-fA-F]+)/.test(value.trim());
177199
}
178200

179-
contrast(threshold = 128): Color {
180-
return new Color(this.yiq >= threshold ? '#000' : '#fff');
201+
contrast(): Color {
202+
const blackContrastRatio = contrast(this.rgb, { r: 0, g: 0, b: 0 });
203+
const whiteContrastRatio = contrast(this.rgb, { r: 255, g: 255, b: 255 });
204+
205+
return new Color(blackContrastRatio >= whiteContrastRatio ? '#000' : '#fff');
181206
}
182207

183208
mix(from: string | RGB | HSL | Color, amount = 0.5): Color {

0 commit comments

Comments
 (0)