diff --git a/packages/core/src/utils/ColorPicker.ts b/packages/core/src/utils/ColorPicker.ts index 8ec90f938..d6a8aa49e 100644 --- a/packages/core/src/utils/ColorPicker.ts +++ b/packages/core/src/utils/ColorPicker.ts @@ -1343,6 +1343,21 @@ export default function ($, undefined?: any) { var rgb = this.toRgb(); return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; }, + getLuminance: function () { + // http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef + var rgb = this.toRgb(); + var RsRGB, GsRGB, BsRGB, R, G, B; + RsRGB = rgb.r / 255; + GsRGB = rgb.g / 255; + BsRGB = rgb.b / 255; + if (RsRGB <= 0.03928) R = RsRGB / 12.92; + else R = Math.pow((RsRGB + 0.055) / 1.055, 2.4); + if (GsRGB <= 0.03928) G = GsRGB / 12.92; + else G = Math.pow((GsRGB + 0.055) / 1.055, 2.4); + if (BsRGB <= 0.03928) B = BsRGB / 12.92; + else B = Math.pow((BsRGB + 0.055) / 1.055, 2.4); + return 0.2126 * R + 0.7152 * G + 0.0722 * B; + }, setAlpha: function (value) { this._a = boundAlpha(value); this._roundA = mathRound(100 * this._a) / 100; @@ -2013,71 +2028,85 @@ export default function ($, undefined?: any) { // Readability Functions // --------------------- - // + // false - tinycolor.isReadable = function (color1, color2) { + // tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false + tinycolor.isReadable = function (color1, color2, wcag2) { var readability = tinycolor.readability(color1, color2); - return readability.brightness > 125 && readability.color > 500; + var wcag2Parms, out; + out = false; + wcag2Parms = validateWCAG2Parms(wcag2); + switch (wcag2Parms.level + wcag2Parms.size) { + case 'AAsmall': + case 'AAAlarge': + out = readability >= 4.5; + break; + case 'AAlarge': + out = readability >= 3; + break; + case 'AAAsmall': + out = readability >= 7; + break; + } + return out; }; // `mostReadable` // Given a base color and a list of possible foreground or background // colors for that base, returns the most readable color. + // Optionally returns Black or White if the most readable color is unreadable. // *Example* - // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000" - tinycolor.mostReadable = function (baseColor, colorList) { + // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255" + // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff" + // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3" + // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff" + tinycolor.mostReadable = function (baseColor, colorList, args) { var bestColor = null; var bestScore = 0; - var bestIsReadable = false; + var readability; + var includeFallbackColors, level, size; + args = args || {}; + includeFallbackColors = args.includeFallbackColors; + level = args.level; + size = args.size; for (var i = 0; i < colorList.length; i++) { - // We normalize both around the "acceptable" breaking point, - // but rank brightness constrast higher than hue. - - var readability = tinycolor.readability(baseColor, colorList[i]); - var readable = readability.brightness > 125 && readability.color > 500; - var score = 3 * (readability.brightness / 125) + readability.color / 500; - - if ( - (readable && !bestIsReadable) || - (readable && bestIsReadable && score > bestScore) || - (!readable && !bestIsReadable && score > bestScore) - ) { - bestIsReadable = readable; - bestScore = score; + readability = tinycolor.readability(baseColor, colorList[i]); + if (readability > bestScore) { + bestScore = readability; bestColor = tinycolor(colorList[i]); } } - return bestColor; + if ( + tinycolor.isReadable(baseColor, bestColor, { + level: level, + size: size, + }) || + !includeFallbackColors + ) { + return bestColor; + } else { + args.includeFallbackColors = false; + return tinycolor.mostReadable(baseColor, ['#fff', '#000'], args); + } }; // Big List of Colors @@ -2433,6 +2462,28 @@ export default function ($, undefined?: any) { return false; } + function validateWCAG2Parms(parms) { + // return valid WCAG2 parms for isReadable. + // If input parms are invalid, return {'level':'AA', 'size':'small'} + var level, size; + parms = parms || { + level: 'AA', + size: 'small', + }; + level = (parms.level || 'AA').toUpperCase(); + size = (parms.size || 'small').toLowerCase(); + if (level !== 'AA' && level !== 'AAA') { + level = 'AA'; + } + if (size !== 'small' && size !== 'large') { + size = 'small'; + } + return { + level: level, + size: size, + }; + } + window.tinycolor = tinycolor; //})();