711 |
712 | This program is free software: you can redistribute it and/or modify
713 | it under the terms of the GNU Affero General Public License as published
714 | by the Free Software Foundation, either version 3 of the License, or
715 | (at your option) any later version.
716 |
717 | This program is distributed in the hope that it will be useful,
718 | but WITHOUT ANY WARRANTY; without even the implied warranty of
719 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
720 | GNU Affero General Public License for more details.
721 |
722 | You should have received a copy of the GNU Affero General Public License
723 | along with this program. If not, see .
724 |
725 | Also add information on how to contact you by electronic and paper mail.
726 |
727 | If your software can interact with users remotely through a computer
728 | network, you should also make sure that it provides a way for users to
729 | get its source. For example, if your program is a web application, its
730 | interface could display a "Source" link that leads users to an archive
731 | of the code. There are many ways you could offer source, and different
732 | solutions will be better for different programs; see section 13 for the
733 | specific requirements.
734 |
735 | You should also get your employer (if you work as a programmer) or school,
736 | if any, to sign a "copyright disclaimer" for the program, if necessary.
737 | For more information on this, and how to apply and follow the GNU AGPL, see
738 | .
739 |
740 | ```
741 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | # 𝜟𝜱✴︎ _(delta phi star) DPS Contrast_
27 | $𝜟𝜱✴︎$ or Delta Phi Star or DPS Contrast, is a method of determining perceptual lightness contrast developed by Andrew Somers (Myndex Research), and is a sibling of [APCA](https://github.com/Myndex/SAPC-APCA) and SAPC/SACAM. It is a simplified method using easily invertible standardized maths, however it lacks some useful properties such as polarity sensitivity.
28 |
29 | But In fact, $𝜟𝜱✴︎$ is intended for applications where a "general" simplifed perceptual contrast is desired, where polarity sensitivity is not needed or is more ambiguous. Nevertheless, polarity sensitivity can be emulated by adding $Lc\ 5$ to negative polarity situations.
30 |
31 | 𝜟𝜱✴︎ DPS Contrast was created on the path toward SACAM and APCA.
32 |
33 | **TUTORIAL:** create Lstar from the piecewise $sRGB$ → $Y$ and $L^*$ per the standard CIE math (see the [See Stars](https://github.com/Myndex/seestars) microlibrary), then:
34 |
35 | ```js
36 | deltaPhiStar = (Math.abs(bgLstar ** 1.618 - txLstar ** 1.618) ** 0.618) * 1.414 - 40 ;
37 |
38 | // ** is equiv to Math.pow
39 | ```
40 |
41 | This mainly works for "Light Mode" but does not track dark mode as well as APCA.
42 |
43 | Also, while this is close to parity with light mode APCA for $Lc\ +45$ thru $Lc\ +75$. The very low and very high contrasts reported by 𝜟𝜱✴︎ higher than those reported by APCA.
44 |
45 | As the difference has a power curve exponent of $1/𝜱$ applied, the difference must be an absolute value. $𝜟𝜱✴︎$ returns a positive value always, and is symmetrical in regards to polarity (text and BG order do not affect results).
46 |
47 |
48 |
49 |
50 | ## DELTA PHI STAR CONTRAST FAQ
51 | ***DPS Contrast***, also known as ***Delta Phi Star 𝜟𝜱✴︎***, is a simple formula for predicting human visual perception of contrast between text and background on computer monitors and devices.
52 |
53 | - **WHO WHAT WHERE WHEN WHY HOW**
54 | - Delta Phi Star was developed by Andrew Somers, in the pursuit of better (and simpler) readability guidelines.
55 | - Delta Phi Star is a formula that predicts the contrast of text against the background for a given pair of colors.
56 | - Delta Phi Star emerged from the SAPC/APCA project developing new standards for better beat ability on the web.
57 | - To provide a simple, yet usefully accurate and perceptually uniform contrast metric.
58 | - Convert a color pair to D65 CIELAB, then send the $L^*$ (Lstar) values to DPS, and it returns an $L^c$ (lightness contrast) value.
59 |
60 | ---
61 | - **BASIC READABILITY GUIDELINES:**
62 | - Delta Phi Star Readability Guidelines are set as simple thresholds similar to WCAG 2.x
63 | - Linear interpolation is permitted intra-level.
64 | - These values are based on reference fonts such as Helvetica or Arial.
65 | - To use a 300 weight font, add $L^c\ 10$ to the contrast threshold needed for normal weight.
66 | - CSS `font-smoothing: antialiased` is prohibited for 300 weight fonts smaller than 36px and for 400 fonts which are smaller than 24px.
67 | - `font-smoothing: auto` should be used for small and thin fonts.
68 |
69 | - **_FOR PRIMARY CONTENT TEXT_**
70 | - $L^c\ 75$ permits a minimum font size of:
71 | - 16px normal or 12px bold
72 | - $L^c\ 60$ permits a minimum font size of:
73 | - 24px normal or 16px bold
74 | - $L^c\ 45$ permits a minimum font size of:
75 | - 42px normal or 24px bold
76 | - **_FOR SECONDARY CONTENT, "SPOT" READABLE TEXT_**
77 | - _subtract_ $L^c\ 15$ from the above values.
78 | - at $L^c\ 90$ (which calculates as $L^c\ 75$ _after_ subtracting $L^c\ 15$)
79 | - minimum font size is 11px for secondary content only.
80 | - secondary content includes things like "copyright" or "placeholder text" or other textual elements that are not directly related to the primary contact of the page or primary navigation.
81 |
82 | - **_FOR SEMANTIC NON-TEXT (icons and pictograms)_**
83 | - $L^c\ 60$ for thin outline icons or thin line drawings
84 | - $L^c\ 45$ for solid icons or bolder line drawings
85 | - **_FOR NON-SEMANTIC NON-TEXT (chart elements or button shapes)_**
86 | - $L^c\ 45$ for button outlines, thin chart lines, small pie pieces
87 | - $L^c\ 30$ for solid buttons, bar charts, large pie pieces
88 |
89 |
90 | - **VISUAL COMPARISON**
91 | While there isn't a tool up and running here, at [LeaVerou](https://github.com/LeaVerou)'s [color.js](https://github.com/LeaVerou/color.js) demo site, DeltaPhiStar's part of the demo for when to flip from black to white. In this demo you can compare a number of different contrast algorithms, including WCAG2, APCA, DeltaPhiStar, and others.
92 |
93 | [**_Black or White?_**](https://colorjs.io/apps/blackwhite/) at color.js
94 |
95 | Here's a screenshot of that demo comparing DeltaPhiStar to APCA, the boxes with a dashed border around them indicate where DeltaPhiStar is different than APCA, with DPS showing black text instead of white.
96 |
97 | This is largely attributable to the the following:
98 | - The difference in how sRGB colors are processed between APCA & DeltaPhiStar
99 | - DeltaPhiStar using the IEC _piecewise_ linearization and CIE conversion to $L^*$.
100 | - APCA uses an optimized conversion that compensates for gamma gain.
101 | - APCA is polarity sensitive, DeltaPhiStar is not.
102 | - as a result, near the flip point for black and white, DeltaPhiStar is slightly under reporting the actual contrast of negative polarity (White text).
103 |
104 | _click to enlarge_
105 |
106 |
107 | As you can see, DeltaPhiStar is not as accurate around the Extreme flip point, but otherwise in relatively decent agreement, and probably well suited for a simplified guideline.
108 |
109 |
110 | ---
111 | - **UNIFORMITY:**
112 | - DPS Contrast is quasi-uniform for human perception of text against a background on a self-illuminated display
113 | - reasonably accurate within a defined range $L^c 45$ to $L^c 75$ and for positive polarity (dark text on a light background)
114 | - The perception curve is based on the output of SACMX-based mixed-mode high-spatial-frequency contrast matching data, using
115 | - hardware-calibrated standard-dynamic-range (SDR) sRGB displays
116 | - a typical office lighting environment with a nominal ambient illumination of 350 lux.
117 | - proximal screen set at or close to white.
118 |
119 | - **DEPENDENCIES:**
120 | - DPS Contrast itself is a *single line of code*, but it's inputs require that a color has been reduced to a $CIE\ L^*$ value.
121 | - therefore, DPS contrast has a dependency for a library that can parse an sRGB color and convert it to D65 CIELAB.
122 | - depending on the application, it may be useful to add logic to determine the polarity of the text and background, and for negative polarity to add $5$ to the LC value (or alternately, offset $-35$ instead of $-40$ at the return).
123 |
124 | - **LIMITATIONS:**
125 | - DPS Contrast becomes substantially less accurate at very high and very low contrasts
126 | - $L^c$ values lower than $L^c 45$ or higher than $L^c 75$ are generally higher than actual perception
127 | - as such $L^c$ values lower than $L^c 45$ or higher than $L^c 75$ should be derated
128 | - otherwise, the range between 45 to 75 is the area of the thresholds most important for text, Arguably this is the only thing that's really necessary for use in defined guidelines such as those needed for WCAG.
129 | - DPS Contrast is not polarity aware
130 | - and $L^c$ values for reverse polarity aka "dark mode" are generally lower
131 | - in dark mode, actual contrast is higher than the reported $L^c$ values between $L^c 40$ & $L^c 70$
132 | - to approximate the polarity difference, add **$5$** to the $L^c$ value for dark mode results between $L^c 40$ & $L^c 70$
133 |
134 | - **INITALISMS and ACRONYMS:**
135 | - APCA™: Accessible Perceptual Contrast Algorithm™ *(aye pea see aye)*
136 | - sometimes referred to as the Advanced Perceptual Contrast Algorithm
137 | - is a perceptual uniform model of text on a self-illuminated display
138 | - APCA-W3: APCA World Wide Web version
139 | - specific APCA version intended for WCAG guidelines
140 | - includes a version of APCA-RDG accessibility guidelines for visual readability
141 | - APCA-RDG: APCA Readability Design Guidelines
142 | - an independent set of design guidelines to promote effective readability and accessibility for visually readable content
143 | - DPS-C: Delta Phi Star™ Contrast *(dee pea ess)*
144 | - simplified quasi-uniform perceptual contrast model
145 | - SACAM™: SLuv Accessible Color Appearance Model™ *(say cam)*
146 | - color appearance model that is designed specifically for self-illuminated displays
147 | - features utilities to accommodate various visual impairments
148 | - SAPC™: SLuv Accessible Perceptual Contrast™ *(sap see)*
149 | - an earlier contrast appearance model that laid the foundation for APCA and SACAM
150 | - SACMX: Spatially Aware Contrast Matching eXperiment
151 | - a method of measuring the perceived suprathreshold contrast at high spatial frequencies
152 |
153 | - **COPYRIGHT and TRADEMARKS:**
154 | - this repo and all materials contained here in, are copyright © 2022 by Andrew Somers. All Rights Reserved. Use permitted as defined in this license agreement.
155 | - Nothing in the license agreement extends to nor permits the use of any trademarks shown anywhere in this repo, unless specifically stated.
156 | - The term "Delta Phi Star™" may be used to describe instantiations, integrations, applications, libraries, or frameworks which are using the materials in this repo, provided that such usage is unaltered except as may be needed to port to different languages.
157 |
158 | - **PHI BONUS**
159 | ```math
160 | \begin{align} \phi = 5^{0.5} \times 0.5 + 0.5 \end{align}
161 | ```
162 |
163 |
--------------------------------------------------------------------------------
/node_modules/.cache/ava/failing-tests.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "deltaphistar",
3 | "version": "0.0.1",
4 | "type": "module",
5 | "description": "Delta Phi Star is a general purpose method of determining perceptual lightness contrast developed by Andrew Somers (Myndex Research), and is a sibling of APCA and SACAM. It is a simplified method using easily invertible standardized maths, however it lacks some useful APCA properties such as polarity sensitivity.",
6 | "main": "./src/deltaphistar.js",
7 | "keywords": [
8 | "CSS",
9 | "HTML",
10 | "PDF",
11 | "RTF",
12 | "sRGB",
13 | "RGB",
14 | "P3",
15 | "displayP3",
16 | "Adobe RGB",
17 | "LCh",
18 | "Lstar",
19 | "color",
20 | "colour",
21 | "contrast",
22 | "lightness",
23 | "brightness",
24 | "luminance",
25 | "luminance contrast",
26 | "lightness contrast",
27 | "perceptual contrast",
28 | "visual contrast",
29 | "color contrast",
30 | "colour contrast",
31 | "text contrast",
32 | "APCA contrast",
33 | "A11y contrast",
34 | "constant contrast",
35 | "accessible contrast",
36 | "readability contrast",
37 | "readability",
38 | "accessibility",
39 | "contrast sensitivity",
40 | "spatial frequency",
41 | "spacial frequency",
42 | "design tools",
43 | "design systems",
44 | "design guidelines",
45 | "typography",
46 | "a11y",
47 | "W3C",
48 | "WCAG",
49 | "WCAG 2",
50 | "WCAG 3",
51 | "SACAM",
52 | "SAPC",
53 | "APCA"
54 | ],
55 | "author": "Andrew Somers",
56 | "license": "AGPL v3",
57 | "bugs": {
58 | "url": "https://github.com/Myndex/deltaphistar/issues"
59 | },
60 | "forum": {
61 | "url": "https://github.com/Myndex/deltaphistar/discussion"
62 | },
63 | "repository": {
64 | "type": "git",
65 | "url": "https://github.com/Myndex/deltaphistar.git"
66 | },
67 | "homepage": "https://git.myndex.com",
68 | "scripts": {
69 | "test": "ava test/index.js"
70 | },
71 | "devDependencies": {
72 | "ava": "^4.3.0"
73 | },
74 | "dependencies": {
75 | "colorparsley": "^0.1.8",
76 | "seestars": "^0.0.1"
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/deltaphistar.js:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | /////
3 | ///// DELTA PHI STAR - General purpose perceptual contrast
4 | ///// Beta 0.0.1
5 | ///// Copyright © 2022 by Andrew Somers. All Rights Reserved.
6 | ///// LICENSE: AGPL 3 LICENSE
7 | ///// CONTACT: Please use the ISSUES or DISCUSSIONS tab at:
8 | ///// https://github.com/Myndex/deltaphistar/
9 | /////
10 | ///////////////////////////////////////////////////////////////////////////////
11 | /////
12 | ///// MINIMAL IMPORTS:
13 | ///// import { seestars } from 'seestars';
14 | /////
15 | /////
16 | ////////////////////////////////////////////////////////////////////////////////
17 |
18 | ////////// DELTA PHI STAR 0.0.1 USAGE //////////////////////////////////////
19 | ///
20 | /// ________________________________________________________________________
21 | ///
22 | /// ********** QUICK START **********
23 | ///
24 | /// let contrast = contrastDPS(foreground, background)
25 | ///
26 | /// // foreground, background are any sRGB color string
27 | ///
28 | ////////////////////////////////////////////////////////////////////////////////
29 |
30 |
31 | ////////////////////////////////////////////////////////////////////////////////
32 | ///////////////////////////////////////////////////////////////////////////////
33 | ///// BEGIN DELTA PHI STAR 0.0.1 BLOCK \////////////////////////////////
34 | //// \//////////////////////////////
35 | /// \////////////////////////////
36 | // \//////////////////////////
37 |
38 |
39 | ///// DEPENDENCIES /////
40 |
41 | // The following imports are not needed for the main APCA function,
42 | // but are needed for the shortcut/alias calcAPCA(), and for the
43 | // future invertAPCA function, which examines hue.
44 |
45 |
46 | //// (add slash to line start for local test mode, remove before push)
47 | /* //// LOCAL TESTING SWITCH for using test.html
48 | // import { colorParsley } from'../../colorparsley/src/colorparsley.js';
49 | import { seeStars } from'../../seestars/src/seestars.js';
50 | /*/ //// TOGGLE
51 | // import { colorParsley } from 'colorparsley';
52 | import { seeStars } from "seestars";
53 | // */ //// END LOCAL TESTING SWITCH
54 |
55 | const phi = Math.pow(5, 0.5) * 0.5 + 0.5; // Math.phi can be used if Math.js
56 |
57 | export function contrastDPS (foreground, background) {
58 | // send it a text and a bg color string, returns a value 0-100
59 | let txLstar = seeStars(foreground);
60 | let bgLstar = seeStars(background);
61 |
62 | let contrast = Math.pow( Math.abs(Math.pow(bgLstar, phi) -
63 | Math.pow(txLstar,phi)), (1 / phi) ) * Math.SQRT2 - 40;
64 |
65 | return (contrast < 7.5) ? 0.0 : contrast ;
66 |
67 | }
68 |
69 | // (Math.pow(bgLstar,1.618) - Math.pow(txLstar,1.618))**0.618 //
70 |
--------------------------------------------------------------------------------
/src/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | 𝜟𝜱✴︎delta phi star TEST
4 |
5 |
6 | 𝜟𝜱✴︎delta phi star Script Test 0.0.1
7 |
8 | Usage:
9 |
10 | 𝜟𝜱✴ = contrastDPS(color1, color2);
11 |
12 |
13 |
14 |
15 | Enable Javascript
16 |
17 |
18 | TESTING YOUR IMPLEMENTATION
19 |
20 | If you've implemented the code and want a quick sanity check, Here are some keystone checks with no rounding. The first color is TEXT and the second color is BACKGROUND:
21 |
22 |
Test Values for 0.0.1 constants.
23 |
24 |
TEXT vs BKGND • EXPECTED RESULT for 0.0.1
25 |
26 | #000 & #9e9e9e ∆Φ✴: 52.042324818974436
27 | #9e9e9e & #FFF ∆Φ✴: 52.15817941439123
28 | #FFF & #888 ∆Φ✴: 63.155229570915864
29 | #888 & #000 ∆Φ✴: 40.15402173709839
30 | #000 & #aaa ∆Φ✴: 58.397040139078555
31 | #aaa & #234 ∆Φ✴: 49.71988060967246
32 | #234 & #def ∆Φ✴: 84.77424837874361
33 | #def & #123 ∆Φ✴: 88.70761679910729
34 | #123 & #444 ∆Φ✴: 0.0
35 | #444 & #777 ∆Φ✴: 11.029421871598664
36 | #777 & #a4a4a4 ∆Φ✴: 12.543444585172274
37 | #a4a4a4 & #fff ∆Φ✴: 48.902933046054386
38 | #fff & #000 ∆Φ✴: 101.35051965850337
39 | #000 & #595959 ∆Φ✴: 13.468722550811329
40 |
41 | Some APCA Lc values for comparison:
42 |
43 | #888 vs #fff APCA Lc 63.056469930209424
44 | ∆Φ✴: 63.155229570915864
45 |
46 | #000 vs #aaa APCA Lc 58.146262578561334
47 | ∆Φ✴: 58.397040139078555
48 |
49 | #123 vs #def APCA Lc 91.66830811481631
50 | ∆Φ✴: 88.70761679910729
51 |
52 | #123 vs #444 APCA Lc 8.32326136957393
53 | ∆Φ✴: 0.0
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/test/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Myndex/deltaphistar/4b5fb4a5726937ce182e59e42756b65c141b2e96/test/.DS_Store
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | // Delta Phi Star Test Script for 0.0.1
2 |
3 | import test from 'ava';
4 |
5 | import { contrastDPS } from '../src/deltaphistar.js';
6 |
7 | console.log('BEGIN TESTS')
8 |
9 | test.todo("Testing Delta Phi Star calculations\n")
10 |
11 | let color = ['#000', '#9e9e9e', '#FFF', '#888','#000', '#aaa', '#234', '#def', '#123', '#444', '#777', '#a4a4a4','#fff', '#000', '#595959'];
12 |
13 | let colorLength = color.length - 1;
14 |
15 | let contrastResult = [ 52.042324818974436, 52.15817941439123, 63.155229570915864, 40.15402173709839, 58.397040139078555, 49.71988060967246, 84.77424837874364, 88.70761679910729, 0.0, 11.029421871598664, 12.543444585172253, 48.9029330460544, 101.35051965850337, 13.468722550811329, ];
16 |
17 |
18 | for (let eye = 1, eyePlus; eye < colorLength; eye++) {
19 |
20 | eyePlus = eye + 1;
21 | test('Lc value for ' + color[eye] + ' and ' + color[eyePlus], (t) => {
22 | t.deepEqual(contrastResult[eye], contrastDPS(color[eye],color[eyePlus]));
23 | });
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/versionHistory.md:
--------------------------------------------------------------------------------
1 | # 𝜟𝜱✴︎ _(delta phi star)_
2 | ```javascript
3 | let phiStarContrast = contrastDPS('colorString','colorString') `
4 | ```
5 | ## _Version History_
6 |
7 | ### Current Version: **0.0.1**
8 |
9 | 0.0.1 - (Aug 9 2022)
10 |
11 | - Initial Beta Release
12 |
13 |
14 |
--------------------------------------------------------------------------------