MexitekPHPColorsColor

A color utility that helps manipulate HEX colors.

Defined (1)

The class is defined in the following location(s).

/vendor/mexitek/phpcolors/src/Mexitek/PHPColors/Color.php  
  1. class Color { 
  2.  
  3. private $_hex; 
  4. private $_hsl; 
  5. private $_rgb; 
  6.  
  7. /** 
  8. * Auto darkens/lightens by 10% for sexily-subtle gradients. 
  9. * Set this to FALSE to adjust automatic shade to be between given color 
  10. * and black (for darken) or white (for lighten) 
  11. */ 
  12. const DEFAULT_ADJUST = 10; 
  13.  
  14. /** 
  15. * Instantiates the class with a HEX value 
  16. * @param string $hex 
  17. * @throws Exception "Bad color format" 
  18. */ 
  19. function __construct( $hex ) { 
  20. // Strip # sign is present 
  21. $color = str_replace("#", "", $hex); 
  22.  
  23. // Make sure it's 6 digits 
  24. if( strlen($color) === 3 ) { 
  25. $color = $color[0].$color[0].$color[1].$color[1].$color[2].$color[2]; 
  26. } else if( strlen($color) != 6 ) { 
  27. throw new Exception("HEX color needs to be 6 or 3 digits long"); 
  28.  
  29. $this->_hsl = self::hexToHsl( $color ); 
  30. $this->_hex = $color; 
  31. $this->_rgb = self::hexToRgb( $color ); 
  32.  
  33. // ==================== 
  34. // = Public Interface = 
  35. // ==================== 
  36.  
  37. /** 
  38. * Given a HEX string returns a HSL array equivalent. 
  39. * @param string $color 
  40. * @return array HSL associative array 
  41. */ 
  42. public static function hexToHsl( $color ) { 
  43.  
  44. // Sanity check 
  45. $color = self::_checkHex($color); 
  46.  
  47. // Convert HEX to DEC 
  48. $R = hexdec($color[0].$color[1]); 
  49. $G = hexdec($color[2].$color[3]); 
  50. $B = hexdec($color[4].$color[5]); 
  51.  
  52. $HSL = array(); 
  53.  
  54. $var_R = ($R / 255); 
  55. $var_G = ($G / 255); 
  56. $var_B = ($B / 255); 
  57.  
  58. $var_Min = min($var_R, $var_G, $var_B); 
  59. $var_Max = max($var_R, $var_G, $var_B); 
  60. $del_Max = $var_Max - $var_Min; 
  61.  
  62. $L = ($var_Max + $var_Min)/2; 
  63.  
  64. if ($del_Max == 0) 
  65. $H = 0; 
  66. $S = 0; 
  67. else 
  68. if ( $L < 0.5 ) $S = $del_Max / ( $var_Max + $var_Min ); 
  69. else $S = $del_Max / ( 2 - $var_Max - $var_Min ); 
  70.  
  71. $del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; 
  72. $del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; 
  73. $del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; 
  74.  
  75. if ($var_R == $var_Max) $H = $del_B - $del_G; 
  76. else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B; 
  77. else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R; 
  78.  
  79. if ($H<0) $H++; 
  80. if ($H>1) $H--; 
  81.  
  82. $HSL['H'] = ($H*360); 
  83. $HSL['S'] = $S; 
  84. $HSL['L'] = $L; 
  85.  
  86. return $HSL; 
  87.  
  88. /** 
  89. * Given a HSL associative array returns the equivalent HEX string 
  90. * @param array $hsl 
  91. * @return string HEX string 
  92. * @throws Exception "Bad HSL Array" 
  93. */ 
  94. public static function hslToHex( $hsl = array() ) { 
  95. // Make sure it's HSL 
  96. if(empty($hsl) || !isset($hsl["H"]) || !isset($hsl["S"]) || !isset($hsl["L"]) ) { 
  97. throw new Exception("Param was not an HSL array"); 
  98.  
  99. list($H, $S, $L) = array( $hsl['H']/360, $hsl['S'], $hsl['L'] ); 
  100.  
  101. if( $S == 0 ) { 
  102. $r = $L * 255; 
  103. $g = $L * 255; 
  104. $b = $L * 255; 
  105. } else { 
  106.  
  107. if($L<0.5) { 
  108. $var_2 = $L*(1+$S); 
  109. } else { 
  110. $var_2 = ($L+$S) - ($S*$L); 
  111.  
  112. $var_1 = 2 * $L - $var_2; 
  113.  
  114. $r = round(255 * self::_huetorgb( $var_1, $var_2, $H + (1/3) )); 
  115. $g = round(255 * self::_huetorgb( $var_1, $var_2, $H )); 
  116. $b = round(255 * self::_huetorgb( $var_1, $var_2, $H - (1/3) )); 
  117.  
  118.  
  119. // Convert to hex 
  120. $r = dechex($r); 
  121. $g = dechex($g); 
  122. $b = dechex($b); 
  123.  
  124. // Make sure we get 2 digits for decimals 
  125. $r = (strlen("".$r)===1) ? "0".$r:$r; 
  126. $g = (strlen("".$g)===1) ? "0".$g:$g; 
  127. $b = (strlen("".$b)===1) ? "0".$b:$b; 
  128.  
  129. return $r.$g.$b; 
  130.  
  131.  
  132. /** 
  133. * Given a HEX string returns a RGB array equivalent. 
  134. * @param string $color 
  135. * @return array RGB associative array 
  136. */ 
  137. public static function hexToRgb( $color ) { 
  138.  
  139. // Sanity check 
  140. $color = self::_checkHex($color); 
  141.  
  142. // Convert HEX to DEC 
  143. $R = hexdec($color[0].$color[1]); 
  144. $G = hexdec($color[2].$color[3]); 
  145. $B = hexdec($color[4].$color[5]); 
  146.  
  147. $RGB['R'] = $R; 
  148. $RGB['G'] = $G; 
  149. $RGB['B'] = $B; 
  150.  
  151. return $RGB; 
  152.  
  153.  
  154. /** 
  155. * Given an RGB associative array returns the equivalent HEX string 
  156. * @param array $rgb 
  157. * @return string RGB string 
  158. * @throws Exception "Bad RGB Array" 
  159. */ 
  160. public static function rgbToHex( $rgb = array() ) { 
  161. // Make sure it's RGB 
  162. if(empty($rgb) || !isset($rgb["R"]) || !isset($rgb["G"]) || !isset($rgb["B"]) ) { 
  163. throw new Exception("Param was not an RGB array"); 
  164.  
  165. // https://github.com/mexitek/phpColors/issues/25#issuecomment-88354815 
  166. // Convert RGB to HEX 
  167. $hex[0] = str_pad(dechex($rgb['R']), 2, '0', STR_PAD_LEFT); 
  168. $hex[1] = str_pad(dechex($rgb['G']), 2, '0', STR_PAD_LEFT); 
  169. $hex[2] = str_pad(dechex($rgb['B']), 2, '0', STR_PAD_LEFT); 
  170.  
  171. return implode( '', $hex ); 
  172.  
  173.  
  174.  
  175. /** 
  176. * Given a HEX value, returns a darker color. If no desired amount provided, then the color halfway between 
  177. * given HEX and black will be returned. 
  178. * @param int $amount 
  179. * @return string Darker HEX value 
  180. */ 
  181. public function darken( $amount = self::DEFAULT_ADJUST ) { 
  182. // Darken 
  183. $darkerHSL = $this->_darken($this->_hsl, $amount); 
  184. // Return as HEX 
  185. return self::hslToHex($darkerHSL); 
  186.  
  187. /** 
  188. * Given a HEX value, returns a lighter color. If no desired amount provided, then the color halfway between 
  189. * given HEX and white will be returned. 
  190. * @param int $amount 
  191. * @return string Lighter HEX value 
  192. */ 
  193. public function lighten( $amount = self::DEFAULT_ADJUST ) { 
  194. // Lighten 
  195. $lighterHSL = $this->_lighten($this->_hsl, $amount); 
  196. // Return as HEX 
  197. return self::hslToHex($lighterHSL); 
  198.  
  199. /** 
  200. * Given a HEX value, returns a mixed color. If no desired amount provided, then the color mixed by this ratio 
  201. * @param string $hex2 Secondary HEX value to mix with 
  202. * @param int $amount = -100..0..+100 
  203. * @return string mixed HEX value 
  204. */ 
  205. public function mix($hex2, $amount = 0) { 
  206. $rgb2 = self::hexToRgb($hex2); 
  207. $mixed = $this->_mix($this->_rgb, $rgb2, $amount); 
  208. // Return as HEX 
  209. return self::rgbToHex($mixed); 
  210.  
  211. /** 
  212. * Creates an array with two shades that can be used to make a gradient 
  213. * @param int $amount Optional percentage amount you want your contrast color 
  214. * @return array An array with a 'light' and 'dark' index 
  215. */ 
  216. public function makeGradient( $amount = self::DEFAULT_ADJUST ) { 
  217. // Decide which color needs to be made 
  218. if( $this->isLight() ) { 
  219. $lightColor = $this->_hex; 
  220. $darkColor = $this->darken($amount); 
  221. } else { 
  222. $lightColor = $this->lighten($amount); 
  223. $darkColor = $this->_hex; 
  224.  
  225. // Return our gradient array 
  226. return array( "light" => $lightColor, "dark" => $darkColor ); 
  227.  
  228.  
  229. /** 
  230. * Returns whether or not given color is considered "light" 
  231. * @param string|Boolean $color 
  232. * @param int $lighterThan 
  233. * @return boolean 
  234. */ 
  235. public function isLight( $color = FALSE, $lighterThan = 130 ) { 
  236. // Get our color 
  237. $color = ($color) ? $color : $this->_hex; 
  238.  
  239. // Calculate straight from rbg 
  240. $r = hexdec($color[0].$color[1]); 
  241. $g = hexdec($color[2].$color[3]); 
  242. $b = hexdec($color[4].$color[5]); 
  243.  
  244. return (( $r*299 + $g*587 + $b*114 )/1000 > $lighterThan); 
  245.  
  246. /** 
  247. * Returns whether or not a given color is considered "dark" 
  248. * @param string|Boolean $color 
  249. * @param int $darkerThan 
  250. * @return boolean 
  251. */ 
  252. public function isDark( $color = FALSE, $darkerThan = 130 ) { 
  253. // Get our color 
  254. $color = ($color) ? $color:$this->_hex; 
  255.  
  256. // Calculate straight from rbg 
  257. $r = hexdec($color[0].$color[1]); 
  258. $g = hexdec($color[2].$color[3]); 
  259. $b = hexdec($color[4].$color[5]); 
  260.  
  261. return (( $r*299 + $g*587 + $b*114 )/1000 <= $darkerThan); 
  262.  
  263. /** 
  264. * Returns the complimentary color 
  265. * @return string Complementary hex color 
  266. */ 
  267. public function complementary() { 
  268. // Get our HSL 
  269. $hsl = $this->_hsl; 
  270.  
  271. // Adjust Hue 180 degrees 
  272. $hsl['H'] += ($hsl['H']>180) ? -180:180; 
  273.  
  274. // Return the new value in HEX 
  275. return self::hslToHex($hsl); 
  276.  
  277. /** 
  278. * Returns your color's HSL array 
  279. */ 
  280. public function getHsl() { 
  281. return $this->_hsl; 
  282. /** 
  283. * Returns your original color 
  284. */ 
  285. public function getHex() { 
  286. return $this->_hex; 
  287. /** 
  288. * Returns your color's RGB array 
  289. */ 
  290. public function getRgb() { 
  291. return $this->_rgb; 
  292.  
  293. /** 
  294. * Returns the cross browser CSS3 gradient 
  295. * @param int $amount Optional: percentage amount to light/darken the gradient 
  296. * @param boolean $vintageBrowsers Optional: include vendor prefixes for browsers that almost died out already 
  297. * @param string $prefix Optional: prefix for every lines 
  298. * @param string $suffix Optional: suffix for every lines 
  299. * @link http://caniuse.com/css-gradients Resource for the browser support 
  300. * @return string CSS3 gradient for chrome, safari, firefox, opera and IE10 
  301. */ 
  302. public function getCssGradient( $amount = self::DEFAULT_ADJUST, $vintageBrowsers = FALSE, $suffix = "" , $prefix = "" ) { 
  303.  
  304. // Get the recommended gradient 
  305. $g = $this->makeGradient($amount); 
  306.  
  307. $css = ""; 
  308. /** fallback/image non-cover color */ 
  309. $css .= "{$prefix}background-color: #".$this->_hex.";{$suffix}"; 
  310.  
  311. /** IE Browsers */ 
  312. $css .= "{$prefix}filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#".$g['light']."', endColorstr='#".$g['dark']."');{$suffix}"; 
  313.  
  314. /** Safari 4+, Chrome 1-9 */ 
  315. if ( $vintageBrowsers ) { 
  316. $css .= "{$prefix}background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#".$g['light']."), to(#".$g['dark']."));{$suffix}"; 
  317.  
  318. /** Safari 5.1+, Mobile Safari, Chrome 10+ */ 
  319. $css .= "{$prefix}background-image: -webkit-linear-gradient(top, #".$g['light'].", #".$g['dark'].");{$suffix}"; 
  320.  
  321. /** Firefox 3.6+ */ 
  322. if ( $vintageBrowsers ) { 
  323. $css .= "{$prefix}background-image: -moz-linear-gradient(top, #".$g['light'].", #".$g['dark'].");{$suffix}"; 
  324.  
  325. /** Opera 11.10+ */ 
  326. if ( $vintageBrowsers ) { 
  327. $css .= "{$prefix}background-image: -o-linear-gradient(top, #".$g['light'].", #".$g['dark'].");{$suffix}"; 
  328.  
  329. /** Unprefixed version (standards): FF 16+, IE10+, Chrome 26+, Safari 7+, Opera 12.1+ */ 
  330. $css .= "{$prefix}background-image: linear-gradient(to bottom, #".$g['light'].", #".$g['dark'].");{$suffix}"; 
  331.  
  332. // Return our CSS 
  333. return $css; 
  334.  
  335. // =========================== 
  336. // = Private Functions Below = 
  337. // =========================== 
  338.  
  339.  
  340. /** 
  341. * Darkens a given HSL array 
  342. * @param array $hsl 
  343. * @param int $amount 
  344. * @return array $hsl 
  345. */ 
  346. private function _darken( $hsl, $amount = self::DEFAULT_ADJUST) { 
  347. // Check if we were provided a number 
  348. if( $amount ) { 
  349. $hsl['L'] = ($hsl['L'] * 100) - $amount; 
  350. $hsl['L'] = ($hsl['L'] < 0) ? 0:$hsl['L']/100; 
  351. } else { 
  352. // We need to find out how much to darken 
  353. $hsl['L'] = $hsl['L']/2 ; 
  354.  
  355. return $hsl; 
  356.  
  357. /** 
  358. * Lightens a given HSL array 
  359. * @param array $hsl 
  360. * @param int $amount 
  361. * @return array $hsl 
  362. */ 
  363. private function _lighten( $hsl, $amount = self::DEFAULT_ADJUST) { 
  364. // Check if we were provided a number 
  365. if( $amount ) { 
  366. $hsl['L'] = ($hsl['L'] * 100) + $amount; 
  367. $hsl['L'] = ($hsl['L'] > 100) ? 1:$hsl['L']/100; 
  368. } else { 
  369. // We need to find out how much to lighten 
  370. $hsl['L'] += (1-$hsl['L'])/2; 
  371.  
  372. return $hsl; 
  373.  
  374. /** 
  375. * Mix 2 rgb colors and return an rgb color 
  376. * @param array $rgb1 
  377. * @param array $rgb2 
  378. * @param int $amount ranged -100..0..+100 
  379. * @return array $rgb 
  380. * ported from http://phpxref.pagelines.com/nav.html?includes/class.colors.php.source.html 
  381. */ 
  382. private function _mix($rgb1, $rgb2, $amount = 0) { 
  383.  
  384. $r1 = ($amount + 100) / 100; 
  385. $r2 = 2 - $r1; 
  386.  
  387. $rmix = (($rgb1['R'] * $r1) + ($rgb2['R'] * $r2)) / 2; 
  388. $gmix = (($rgb1['G'] * $r1) + ($rgb2['G'] * $r2)) / 2; 
  389. $bmix = (($rgb1['B'] * $r1) + ($rgb2['B'] * $r2)) / 2; 
  390.  
  391. return array('R' => $rmix, 'G' => $gmix, 'B' => $bmix); 
  392.  
  393. /** 
  394. * Given a Hue, returns corresponding RGB value 
  395. * @param int $v1 
  396. * @param int $v2 
  397. * @param int $vH 
  398. * @return int 
  399. */ 
  400. private static function _huetorgb( $v1, $v2, $vH ) { 
  401. if( $vH < 0 ) { 
  402. $vH += 1; 
  403.  
  404. if( $vH > 1 ) { 
  405. $vH -= 1; 
  406.  
  407. if( (6*$vH) < 1 ) { 
  408. return ($v1 + ($v2 - $v1) * 6 * $vH); 
  409.  
  410. if( (2*$vH) < 1 ) { 
  411. return $v2; 
  412.  
  413. if( (3*$vH) < 2 ) { 
  414. return ($v1 + ($v2-$v1) * ( (2/3)-$vH ) * 6); 
  415.  
  416. return $v1; 
  417.  
  418.  
  419. /** 
  420. * You need to check if you were given a good hex string 
  421. * @param string $hex 
  422. * @return string Color 
  423. * @throws Exception "Bad color format" 
  424. */ 
  425. private static function _checkHex( $hex ) { 
  426. // Strip # sign is present 
  427. $color = str_replace("#", "", $hex); 
  428.  
  429. // Make sure it's 6 digits 
  430. if( strlen($color) == 3 ) { 
  431. $color = $color[0].$color[0].$color[1].$color[1].$color[2].$color[2]; 
  432. } else if( strlen($color) != 6 ) { 
  433. throw new Exception("HEX color needs to be 6 or 3 digits long"); 
  434.  
  435. return $color; 
  436.