collateral fixes, removed alpha control for alerts, added contrast text
generation for alerts, updated getTextColor to also have fallback to black/white if resulting contrast isn't passable (only when inverting lightness!), updated UI to use tabs.
This commit is contained in:
parent
1723f427f5
commit
e7fe2dc9f9
11 changed files with 200 additions and 187 deletions
|
@ -80,30 +80,23 @@ const getContrastRatio = (a, b) => {
|
|||
}
|
||||
|
||||
/**
|
||||
* This generates what "worst case" color would look like for transparent
|
||||
* segments. I.e. transparent black with yellow text over yellow background.
|
||||
* This performs alpha blending between solid background and semi-transparent foreground
|
||||
*
|
||||
* @param {Object} srgb - transparent color
|
||||
* @param {Number} alpha - color's opacity/alpha channel
|
||||
* @param {Object} textSrgb - text color (considered as worst case scenario for transparent background)
|
||||
* @param {Object} fg - top layer color
|
||||
* @param {Number} fga - top layer's alpha
|
||||
* @param {Object} bg - bottom layer color
|
||||
* @returns {Object} sRGB of resulting color
|
||||
*/
|
||||
const transparentWorstCase = (srgb, alpha, textSrgb) => {
|
||||
const alphaBlend = (fg, fga, bg) => {
|
||||
if (fga === 1 || typeof fga === 'undefined') return fg
|
||||
return 'rgb'.split('').reduce((acc, c) => {
|
||||
// Simplified https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
|
||||
// for opaque bg and transparent fg
|
||||
acc[c] = (srgb[c] * alpha + textSrgb[c] * (1 - alpha))
|
||||
acc[c] = (fg[c] * fga + bg[c] * (1 - fga))
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
const worstCase = (bg, bga, text) => {
|
||||
console.log(bg)
|
||||
console.log(text)
|
||||
if (bga === 1 || typeof bga === 'undefined') return bg
|
||||
return transparentWorstCase(bg, bga, text)
|
||||
}
|
||||
|
||||
const hex2rgb = (hex) => {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
||||
return result ? {
|
||||
|
@ -134,5 +127,5 @@ export {
|
|||
mixrgb,
|
||||
rgbstr2hex,
|
||||
getContrastRatio,
|
||||
worstCase
|
||||
alphaBlend
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { times } from 'lodash'
|
||||
import { brightness, invertLightness, convert } from 'chromatism'
|
||||
import { rgb2hex, hex2rgb, mixrgb } from '../color_convert/color_convert.js'
|
||||
import { brightness, invertLightness, convert, contrastRatio } from 'chromatism'
|
||||
import { rgb2hex, hex2rgb, mixrgb, getContrastRatio, alphaBlend } from '../color_convert/color_convert.js'
|
||||
|
||||
// While this is not used anymore right now, I left it in if we want to do custom
|
||||
// styles that aren't just colors, so user can pick from a few different distinct
|
||||
|
@ -58,13 +58,17 @@ const rgb2rgba = function (rgba) {
|
|||
return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`
|
||||
}
|
||||
|
||||
const getTextColor = function (bg, text) {
|
||||
const getTextColor = function (bg, text, preserve) {
|
||||
const bgIsLight = convert(bg).hsl.l > 50
|
||||
const textIsLight = convert(text).hsl.l > 50
|
||||
|
||||
if ((bgIsLight && textIsLight) || (!bgIsLight && !textIsLight)) {
|
||||
const base = typeof text.a !== 'undefined' ? { a: text.a } : {}
|
||||
return Object.assign(base, invertLightness(text).rgb)
|
||||
const result = Object.assign(base, invertLightness(text).rgb)
|
||||
if (!preserve && getContrastRatio(bg, result) < 4.5) {
|
||||
return contrastRatio(bg, text).rgb
|
||||
}
|
||||
return result
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
@ -104,7 +108,12 @@ const generatePreset = (input) => {
|
|||
alert: 0.5,
|
||||
input: 0.5,
|
||||
faint: 0.5
|
||||
}, input.opacity)
|
||||
}, Object.entries(input.opacity || {}).reduce((acc, [k, v]) => {
|
||||
if (typeof v !== 'undefined') {
|
||||
acc[k] = v
|
||||
}
|
||||
return acc
|
||||
}, {}))
|
||||
|
||||
const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
|
||||
if (typeof v === 'object') {
|
||||
|
@ -128,9 +137,9 @@ const generatePreset = (input) => {
|
|||
|
||||
colors.fg = col.fg
|
||||
colors.fgText = col.fgText || getTextColor(colors.fg, colors.text)
|
||||
colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link)
|
||||
colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link, true)
|
||||
|
||||
colors.border = col.border || brightness(20 * mod, colors.fg).rgb
|
||||
colors.border = col.border || brightness(2 * mod, colors.fg).rgb
|
||||
|
||||
colors.btn = col.btn || Object.assign({}, col.fg)
|
||||
colors.btnText = col.btnText || getTextColor(colors.btn, colors.fgText)
|
||||
|
@ -156,8 +165,11 @@ const generatePreset = (input) => {
|
|||
colors.cOrange = col.cOrange
|
||||
|
||||
colors.alertError = col.alertError || Object.assign({}, col.cRed)
|
||||
colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)
|
||||
colors.alertErrorPanelText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.panel), colors.panelText)
|
||||
|
||||
colors.badgeNotification = col.badgeNotification || Object.assign({}, col.cRed)
|
||||
colors.badgeNotificationText = col.badgeNotification || Object.assign({}, col.cRed)
|
||||
colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
|
||||
|
||||
Object.entries(opacity).forEach(([ k, v ]) => {
|
||||
if (typeof v === 'undefined') return
|
||||
|
|
|
@ -11,7 +11,7 @@ const highlightStyle = (prefs) => {
|
|||
if (type === 'striped') {
|
||||
return {
|
||||
backgroundImage: [
|
||||
'repeating-linear-gradient(-45deg,',
|
||||
'repeating-linear-gradient(135deg,',
|
||||
`${tintColor} ,`,
|
||||
`${tintColor} 20px,`,
|
||||
`${tintColor2} 20px,`,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue