UNPKG

@a_ng_d/utils-ui-color-palette

Version:

Core utilities library for UI Color Palette - a color management plugin for design tools. This library provides the foundational color manipulation, contrast calculation, and palette generation features used in the plugin.

188 lines (187 loc) 7.95 kB
var T = Object.defineProperty; var m = (e, t, r) => t in e ? T(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r; var a = (e, t, r) => m(e, typeof t != "symbol" ? t + "" : t, r); import { c as A } from "../../index-Beb8qoyd.js"; /** @preserve ///// SAPC APCA - Advanced Perceptual Contrast Algorithm ///// Beta 0.1.9 W3 • contrast function only ///// DIST: W3 • Revision date: July 3, 2022 ///// Function to parse color values and determine Lc contrast ///// Copyright © 2019-2022 by Andrew Somers. All Rights Reserved. ///// LICENSE: W3 LICENSE ///// CONTACT: Please use the ISSUES or DISCUSSIONS tab at: ///// https://github.com/Myndex/SAPC-APCA/ ///// /////////////////////////////////////////////////////////////////////////////// ///// ///// MINIMAL IMPORTS: ///// import { APCAcontrast, sRGBtoY, displayP3toY, ///// calcAPCA, fontLookupAPCA } from 'apca-w3'; ///// import { colorParsley } from 'colorparsley'; ///// ///// FORWARD CONTRAST USAGE: ///// Lc = APCAcontrast( sRGBtoY( TEXTcolor ) , sRGBtoY( BACKGNDcolor ) ); ///// Where the colors are sent as an rgba array [255,255,255,1] ///// ///// Retrieving an array of font sizes for the contrast: ///// fontArray = fontLookupAPCA(Lc); ///// ///// Live Demonstrator at https://www.myndex.com/APCA/ // */ const o = { mainTRC: 2.4, // 2.4 exponent for emulating actual monitor perception // sRGB coefficients sRco: 0.2126729, sGco: 0.7151522, sBco: 0.072175, // G-4g constants for use with 2.4 exponent normBG: 0.56, normTXT: 0.57, revTXT: 0.62, revBG: 0.65, // G-4g Clamps and Scalers blkThrs: 0.022, blkClmp: 1.414, scaleBoW: 1.14, scaleWoB: 1.14, loBoWoffset: 0.027, loWoBoffset: 0.027, deltaYmin: 5e-4, loClip: 0.1 }; function d(e, t, r = -1) { const h = [0, 1.1]; if (isNaN(e) || isNaN(t) || Math.min(e, t) < h[0] || Math.max(e, t) > h[1]) return 0; let n = 0, i = 0, s = "BoW"; return e = e > o.blkThrs ? e : e + Math.pow(o.blkThrs - e, o.blkClmp), t = t > o.blkThrs ? t : t + Math.pow(o.blkThrs - t, o.blkClmp), Math.abs(t - e) < o.deltaYmin ? 0 : (t > e ? (n = (Math.pow(t, o.normBG) - Math.pow(e, o.normTXT)) * o.scaleBoW, i = n < o.loClip ? 0 : n - o.loBoWoffset) : (s = "WoB", n = (Math.pow(t, o.revBG) - Math.pow(e, o.revTXT)) * o.scaleWoB, i = n > -0.1 ? 0 : n + o.loWoBoffset), r < 0 ? i * 100 : r == 0 ? Math.round(Math.abs(i) * 100) + "<sub>" + s + "</sub>" : Number.isInteger(r) ? (i * 100).toFixed(r) : 0); } function P(e, t = 2) { const r = [ ["Lc", 100, 200, 300, 400, 500, 600, 700, 800, 900], [0, 999, 999, 999, 999, 999, 999, 999, 999, 999], [10, 999, 999, 999, 999, 999, 999, 999, 999, 999], [15, 777, 777, 777, 777, 777, 777, 777, 777, 777], [20, 777, 777, 777, 777, 777, 777, 777, 777, 777], [25, 777, 777, 777, 120, 120, 108, 96, 96, 96], [30, 777, 777, 120, 108, 108, 96, 72, 72, 72], [35, 777, 120, 108, 96, 72, 60, 48, 48, 48], [40, 120, 108, 96, 60, 48, 42, 32, 32, 32], [45, 108, 96, 72, 42, 32, 28, 24, 24, 24], [50, 96, 72, 60, 32, 28, 24, 21, 21, 21], [55, 80, 60, 48, 28, 24, 21, 18, 18, 18], [60, 72, 48, 42, 24, 21, 18, 16, 16, 18], [65, 68, 46, 32, 21.75, 19, 17, 15, 16, 18], [70, 64, 44, 28, 19.5, 18, 16, 14.5, 16, 18], [75, 60, 42, 24, 18, 16, 15, 14, 16, 18], [80, 56, 38.25, 23, 17.25, 15.81, 14.81, 14, 16, 18], [85, 52, 34.5, 22, 16.5, 15.625, 14.625, 14, 16, 18], [90, 48, 32, 21, 16, 15.5, 14.5, 14, 16, 18], [95, 45, 28, 19.5, 15.5, 15, 14, 13.5, 16, 18], [100, 42, 26.5, 18.5, 15, 14.5, 13.5, 13, 16, 18], [105, 39, 25, 18, 14.5, 14, 13, 12, 16, 18], [110, 36, 24, 18, 14, 13, 12, 11, 16, 18], [115, 34.5, 22.5, 17.25, 12.5, 11.875, 11.25, 10.625, 14.5, 16.5], [120, 33, 21, 16.5, 11, 10.75, 10.5, 10.25, 13, 15], [125, 32, 20, 16, 10, 10, 10, 10, 12, 14] ], h = [ ["∆Lc", 100, 200, 300, 400, 500, 600, 700, 800, 900], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [10, 0, 0, 0, 0, 0, 0, 0, 0, 0], [15, 0, 0, 0, 0, 0, 0, 0, 0, 0], [20, 0, 0, 0, 0, 0, 0, 0, 0, 0], [25, 0, 0, 0, 12, 12, 12, 24, 24, 24], [30, 0, 0, 12, 12, 36, 36, 24, 24, 24], [35, 0, 12, 12, 36, 24, 18, 16, 16, 16], [40, 12, 12, 24, 18, 16, 14, 8, 8, 8], [45, 12, 24, 12, 10, 4, 4, 3, 3, 3], [50, 16, 12, 12, 4, 4, 3, 3, 3, 3], [55, 8, 12, 6, 4, 3, 3, 2, 2, 0], [60, 4, 2, 10, 2.25, 2, 1, 1, 0, 0], [65, 4, 2, 4, 2.25, 1, 1, 0.5, 0, 0], [70, 4, 2, 4, 1.5, 2, 1, 0.5, 0, 0], [75, 4, 3.75, 1, 0.75, 0.188, 0.188, 0, 0, 0], [80, 4, 3.75, 1, 0.75, 0.188, 0.188, 0, 0, 0], [85, 4, 2.5, 1, 0.5, 0.125, 0.125, 0, 0, 0], [90, 3, 4, 1.5, 0.5, 0.5, 0.5, 0.5, 0, 0], [95, 3, 1.5, 1, 0.5, 0.5, 0.5, 0.5, 0, 0], [100, 3, 1.5, 0.5, 0.5, 0.5, 0.5, 1, 0, 0], [105, 3, 1, 0, 0.5, 1, 1, 1, 0, 0], [110, 1.5, 1.5, 0.75, 1.5, 1.125, 0.75, 0.375, 1.5, 1.5], [115, 1.5, 1.5, 0.75, 1.5, 1.125, 0.75, 0.375, 1.5, 1.5], [120, 1, 1, 0.5, 1, 0.75, 0.5, 0.25, 1, 1], [125, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], i = [0, 100, 200, 300, 400, 500, 600, 700, 800, 900].length; let s = [e.toFixed(t), 0, 0, 0, 0, 0, 0, 0, 0, 0]; s.length; let l = 777; e = Math.abs(e); const c = 0.2, u = e == 0 ? 1 : e * c | 0; let C = 0, f = (e - r[u][C]) * c; for (C++; C < i; C++) l = r[u][C], l > 400 ? s[C] = l : e < 14.5 ? s[C] = 999 : e < 29.5 ? s[C] = 777 : l > 24 ? s[C] = Math.round(l - h[u][C] * f) : s[C] = l - (2 * h[u][C] * f | 0) * 0.5; return s; } function g(e = [0, 0, 0]) { function t(r) { return Math.pow(r / 255, o.mainTRC); } return o.sRco * t(e[0]) + o.sGco * t(e[1]) + o.sBco * t(e[2]); } class W { constructor({ backgroundColor: t = [0, 0, 0], textColor: r = "#FFFFFF" }) { a(this, "backgroundColor"); a(this, "textColor"); a(this, "getWCAGContrast", () => A.contrast(A(this.backgroundColor).hex(), this.textColor)); a(this, "getAPCAContrast", () => Math.abs( d( g(A(this.textColor).rgb()), g(this.backgroundColor) ) )); a(this, "getWCAGScore", () => this.getWCAGContrast() < 4.5 ? "A" : this.getWCAGContrast() >= 4.5 && this.getWCAGContrast() < 7 ? "AA" : "AAA"); a(this, "getWCAGScoreColor", () => this.getWCAGScore() !== "A" ? { r: 0.5294117647, g: 0.8156862745, b: 0.6941176471 } : { r: 0.8274509804, g: 0.7019607843, b: 0.7803921569 }); a(this, "getAPCAScoreColor", () => this.getRecommendedUsage() !== "AVOID" ? { r: 0.5294117647, g: 0.8156862745, b: 0.6941176471 } : { r: 0.8274509804, g: 0.7019607843, b: 0.7803921569 }); a(this, "getMinFontSizes", () => P(this.getAPCAContrast())); a(this, "getRecommendedUsage", () => this.getAPCAContrast() >= 90 ? "FLUENT_TEXT" : this.getAPCAContrast() >= 75 && this.getAPCAContrast() < 90 ? "CONTENT_TEXT" : this.getAPCAContrast() >= 60 && this.getAPCAContrast() < 75 ? "BODY_TEXT" : this.getAPCAContrast() >= 45 && this.getAPCAContrast() < 60 ? "HEADLINES" : this.getAPCAContrast() >= 30 && this.getAPCAContrast() < 45 ? "SPOT_TEXT" : this.getAPCAContrast() >= 15 && this.getAPCAContrast() < 30 ? "NON_TEXT" : this.getAPCAContrast() < 15 ? "AVOID" : "UNKNOWN"); a(this, "getContrastRatioForLightness", (t) => { const r = A.lch(t, 0, 0).rgb(); return A.contrast(A(r).hex(), this.textColor); }); a(this, "getLightnessForContrastRatio", (t, r = 0.1) => { const h = A(this.textColor).luminance() > 0.5; let n = 0, i = 100, s = h ? 20 : 80; for (; i - n > r; ) { s = (n + i) / 2; const l = this.getContrastRatioForLightness(s); h ? l < t ? i = s : n = s : l < t ? n = s : i = s; } return s; }); this.backgroundColor = t, this.textColor = r; } } export { W as default }; //# sourceMappingURL=contrast.js.map