ru-se.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

color-calculations.js (4491B)


      1 /* global Color */
      2 /* eslint no-unused-vars: off */
      3 /**
      4  * Color Calculations.
      5  *
      6  * @since Twenty Twenty 1.0
      7  *
      8  * @param {string} backgroundColor - The background color.
      9  * @param {number} accentHue - The hue for our accent color.
     10  *
     11  * @return {Object} - this
     12  */
     13 function _twentyTwentyColor( backgroundColor, accentHue ) {
     14 	// Set the object properties.
     15 	this.backgroundColor = backgroundColor;
     16 	this.accentHue = accentHue;
     17 	this.bgColorObj = new Color( backgroundColor );
     18 	this.textColorObj = this.bgColorObj.getMaxContrastColor();
     19 	this.textColor = this.textColorObj.toCSS();
     20 	this.isDark = 0.5 > this.bgColorObj.toLuminosity();
     21 	this.isLight = ! this.isDark;
     22 
     23 	// Return the object.
     24 	return this;
     25 }
     26 
     27 /**
     28  * Builds an array of Color objects based on the accent hue.
     29  * For improved performance we only build half the array
     30  * depending on dark/light background-color.
     31  *
     32  * @since Twenty Twenty 1.0
     33  *
     34  * @return {Object} - this
     35  */
     36 _twentyTwentyColor.prototype.setAccentColorsArray = function() {
     37 	var self = this,
     38 		minSaturation = 65,
     39 		maxSaturation = 100,
     40 		minLightness = 30,
     41 		maxLightness = 80,
     42 		stepSaturation = 2,
     43 		stepLightness = 2,
     44 		pushColor = function() {
     45 			var colorObj = new Color( {
     46 					h: self.accentHue,
     47 					s: s,
     48 					l: l
     49 				} ),
     50 				item,
     51 				/**
     52 				 * Get a score for this color in contrast to its background color and surrounding text.
     53 				 *
     54 				 * @since Twenty Twenty 1.0
     55 				 *
     56 				 * @param {number} contrastBackground - WCAG contrast with the background color.
     57 				 * @param {number} contrastSurroundingText - WCAG contrast with surrounding text.
     58 				 * @return {number} - 0 is best, higher numbers have bigger difference with the desired scores.
     59 				 */
     60 				getScore = function( contrastBackground, contrastSurroundingText ) {
     61 					var diffBackground = ( 7 >= contrastBackground ) ? 0 : 7 - contrastBackground,
     62 						diffSurroundingText = ( 3 >= contrastSurroundingText ) ? 0 : 3 - contrastSurroundingText;
     63 
     64 					return diffBackground + diffSurroundingText;
     65 				};
     66 
     67 			item = {
     68 				color: colorObj,
     69 				contrastBackground: colorObj.getDistanceLuminosityFrom( self.bgColorObj ),
     70 				contrastText: colorObj.getDistanceLuminosityFrom( self.textColorObj )
     71 			};
     72 
     73 			// Check a minimum of 4.5:1 contrast with the background and 3:1 with surrounding text.
     74 			if ( 4.5 > item.contrastBackground || 3 > item.contrastText ) {
     75 				return;
     76 			}
     77 
     78 			// Get a score for this color by multiplying the 2 contrasts.
     79 			// We'll use that to sort the array.
     80 			item.score = getScore( item.contrastBackground, item.contrastText );
     81 
     82 			self.accentColorsArray.push( item );
     83 		},
     84 		s, l, aaa;
     85 
     86 	this.accentColorsArray = [];
     87 
     88 	// We're using `for` loops here because they perform marginally better than other loops.
     89 	for ( s = minSaturation; s <= maxSaturation; s += stepSaturation ) {
     90 		for ( l = minLightness; l <= maxLightness; l += stepLightness ) {
     91 			pushColor( s, l );
     92 		}
     93 	}
     94 
     95 	// Check if we have colors that are AAA compliant.
     96 	aaa = this.accentColorsArray.filter( function( color ) {
     97 		return 7 <= color.contrastBackground;
     98 	} );
     99 
    100 	// If we have AAA-compliant colors, always prefer them.
    101 	if ( aaa.length ) {
    102 		this.accentColorsArray = aaa;
    103 	}
    104 
    105 	// Sort colors by contrast.
    106 	this.accentColorsArray.sort( function( a, b ) {
    107 		return a.score - b.score;
    108 	} );
    109 	return this;
    110 };
    111 
    112 /**
    113  * Get accessible text-color.
    114  *
    115  * @since Twenty Twenty 1.0
    116  *
    117  * @return {Color} - Returns a Color object.
    118  */
    119 _twentyTwentyColor.prototype.getTextColor = function() {
    120 	return this.textColor;
    121 };
    122 
    123 /**
    124  * Get accessible color for the defined accent-hue and background-color.
    125  *
    126  * @since Twenty Twenty 1.0
    127  *
    128  * @return {Color} - Returns a Color object.
    129  */
    130 _twentyTwentyColor.prototype.getAccentColor = function() {
    131 	var fallback;
    132 
    133 	// If we have colors returns the 1st one - it has the highest score.
    134 	if ( this.accentColorsArray[0] ) {
    135 		return this.accentColorsArray[0].color;
    136 	}
    137 
    138 	// Fallback.
    139 	fallback = new Color( 'hsl(' + this.accentHue + ',75%,50%)' );
    140 	return fallback.getReadableContrastingColor( this.bgColorObj, 4.5 );
    141 };
    142 
    143 /**
    144  * Return a new instance of the _twentyTwentyColor object.
    145  *
    146  * @since Twenty Twenty 1.0
    147  *
    148  * @param {string} backgroundColor - The background color.
    149  * @param {number} accentHue - The hue for our accent color.
    150  * @return {Object} - this
    151  */
    152 function twentyTwentyColor( backgroundColor, accentHue ) {// jshint ignore:line
    153 	var color = new _twentyTwentyColor( backgroundColor, accentHue );
    154 	color.setAccentColorsArray();
    155 	return color;
    156 }