Browse Source

Merge 1de2b69dac into dd1c14074e

pull/6681/merge
David Harvey 4 weeks ago
committed by GitHub
parent
commit
58c7c84ec4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 139
      packages/core/src/utils/ColorPicker.ts

139
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
// ---------------------
// <http://www.w3.org/TR/AERT#color-contrast>
// <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
// `readability`
// Analyze the 2 colors and returns an object with the following properties:
// `brightness`: difference in brightness between the two colors
// `color`: difference in color/hue between the two colors
// `readibility`
// Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2)
tinycolor.readability = function (color1, color2) {
var c1 = tinycolor(color1);
var c2 = tinycolor(color2);
var rgb1 = c1.toRgb();
var rgb2 = c2.toRgb();
var brightnessA = c1.getBrightness();
var brightnessB = c2.getBrightness();
var colorDiff =
Math.max(rgb1.r, rgb2.r) -
Math.min(rgb1.r, rgb2.r) +
Math.max(rgb1.g, rgb2.g) -
Math.min(rgb1.g, rgb2.g) +
Math.max(rgb1.b, rgb2.b) -
Math.min(rgb1.b, rgb2.b);
return {
brightness: Math.abs(brightnessA - brightnessB),
color: colorDiff,
};
return (
(Math.max(c1.getLuminance(), c2.getLuminance()) + 0.05) / (Math.min(c1.getLuminance(), c2.getLuminance()) + 0.05)
);
};
// `readable`
// http://www.w3.org/TR/AERT#color-contrast
// Ensure that foreground and background color combinations provide sufficient contrast.
// `isReadable`
// Ensure that foreground and background color combinations meet WCAG2 guidelines.
// The third argument is an optional Object.
// the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA';
// the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'.
// If the entire object is absent, isReadable defaults to {level:"AA",size:"small"}.
// *Example*
// tinycolor.isReadable("#000", "#111") => 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;
//})();

Loading…
Cancel
Save