-
Notifications
You must be signed in to change notification settings - Fork 547
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add chroma.contrastAPCA (#353)
* feat: add chroma.contrastAPCA resolves #302 * docs: fix rendering of transparent css colors in docs * build
- Loading branch information
Showing
11 changed files
with
288 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import Color from '../Color.js'; | ||
import mix from '../generator/mix.js'; | ||
|
||
/** | ||
* @license | ||
* | ||
* The APCA contrast prediction algorithm is based of the formulas published | ||
* in the APCA-1.0.98G specification by Myndex. The specification is available at: | ||
* https://raw.githubusercontent.com/Myndex/apca-w3/master/images/APCAw3_0.1.17_APCA0.0.98G.svg | ||
* | ||
* Note that the APCA implementation is still beta, so please update to | ||
* future versions of chroma.js when they become available. | ||
* | ||
* You can read more about the APCA Readability Criterion at | ||
* https://readtech.org/ARC/ | ||
*/ | ||
|
||
// constants | ||
const W_offset = 0.027; | ||
const P_in = 0.0005; | ||
const P_out = 0.1; | ||
const R_scale = 1.14; | ||
const B_threshold = 0.022; | ||
const B_exp = 1.414; | ||
|
||
export default (text, bg) => { | ||
// parse input colors | ||
text = new Color(text); | ||
bg = new Color(bg); | ||
// if text color has alpha, blend against background | ||
if (text.alpha() < 1) { | ||
text = mix(bg, text, text.alpha(), 'rgb'); | ||
} | ||
const l_text = lum(...text.rgb()); | ||
const l_bg = lum(...bg.rgb()); | ||
|
||
// soft clamp black levels | ||
const Y_text = | ||
l_text >= B_threshold | ||
? l_text | ||
: l_text + Math.pow(B_threshold - l_text, B_exp); | ||
const Y_bg = | ||
l_bg >= B_threshold ? l_bg : l_bg + Math.pow(B_threshold - l_bg, B_exp); | ||
|
||
// normal polarity (dark text on light background) | ||
const S_norm = Math.pow(Y_bg, 0.56) - Math.pow(Y_text, 0.57); | ||
// reverse polarity (light text on dark background) | ||
const S_rev = Math.pow(Y_bg, 0.65) - Math.pow(Y_text, 0.62); | ||
// clamp noise then scale | ||
const C = | ||
Math.abs(Y_bg - Y_text) < P_in | ||
? 0 | ||
: Y_text < Y_bg | ||
? S_norm * R_scale | ||
: S_rev * R_scale; | ||
// clamp minimum contrast then offset | ||
const S_apc = Math.abs(C) < P_out ? 0 : C > 0 ? C - W_offset : C + W_offset; | ||
// scale to 100 | ||
return S_apc * 100; | ||
}; | ||
|
||
function lum(r, g, b) { | ||
return ( | ||
0.2126729 * Math.pow(r / 255, 2.4) + | ||
0.7151522 * Math.pow(g / 255, 2.4) + | ||
0.072175 * Math.pow(b / 255, 2.4) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters