Refactor contrast to use luminance function

This commit is contained in:
Michael Shamoon 2022-04-12 22:23:00 -07:00
parent d98a016087
commit 1c2699b16e
2 changed files with 35 additions and 4 deletions

View File

@ -9,7 +9,11 @@ import {
} from '@angular/core' } from '@angular/core'
import { Meta } from '@angular/platform-browser' import { Meta } from '@angular/platform-browser'
import { CookieService } from 'ngx-cookie-service' import { CookieService } from 'ngx-cookie-service'
import { hexToHsl } from 'src/app/utils/color' import {
BRIGHTNESS,
estimateBrightnessForColor,
hexToHsl,
} from 'src/app/utils/color'
export interface PaperlessSettings { export interface PaperlessSettings {
key: string key: string
@ -138,10 +142,9 @@ export class SettingsService {
if (themeColor) { if (themeColor) {
const hsl = hexToHsl(themeColor) const hsl = hexToHsl(themeColor)
const useDarkTextColor = const bgBrightnessEstimate = estimateBrightnessForColor(themeColor)
parseInt(themeColor.replace('#', ''), 16) > 0xffffff / 1.5
if (useDarkTextColor) { if (bgBrightnessEstimate == BRIGHTNESS.DARK) {
this.renderer.addClass(this.document.body, 'text-bg-dark') this.renderer.addClass(this.document.body, 'text-bg-dark')
this.renderer.removeClass(this.document.body, 'text-bg-light') this.renderer.removeClass(this.document.body, 'text-bg-light')
} else { } else {

View File

@ -1,5 +1,10 @@
import { HSL, RGB } from 'ngx-color' import { HSL, RGB } from 'ngx-color'
export const BRIGHTNESS = {
LIGHT: 'light',
DARK: 'dark',
}
function componentToHex(c) { function componentToHex(c) {
var hex = Math.floor(c).toString(16) var hex = Math.floor(c).toString(16)
return hex.length == 1 ? '0' + hex : hex return hex.length == 1 ? '0' + hex : hex
@ -101,6 +106,29 @@ export function hexToRGB(hex: string): RGB {
} }
} }
export function computeLuminance(color: RGB) {
// Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
const colorKeys = Object.keys(color)
for (var i = 0; i < 3; i++) {
var rgb = color[colorKeys[i]]
rgb /= 255
rgb = rgb < 0.03928 ? rgb / 12.92 : Math.pow((rgb + 0.055) / 1.055, 2.4)
color[i] = rgb
}
return 0.2126 * color[0] + 0.7152 * color[1] + 0.0722 * color[2]
}
export function estimateBrightnessForColor(colorHex: string) {
// See <https://www.w3.org/TR/WCAG20/#contrast-ratiodef>
// Adapted from https://api.flutter.dev/flutter/material/ThemeData/estimateBrightnessForColor.html
const rgb = hexToRGB(colorHex)
const luminance = computeLuminance(rgb)
const kThreshold = 0.15
return (luminance + 0.05) * (luminance + 0.05) > kThreshold
? BRIGHTNESS.LIGHT
: BRIGHTNESS.DARK
}
export function randomColor() { export function randomColor() {
let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4) let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4)
return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex( return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex(