| 1 |
<?php |
| 2 |
|
| 3 |
namespace FluentCart\App\Services\Theme; |
| 4 |
|
| 5 |
class ColorPaletteGenerator { |
| 6 |
|
| 7 |
private function hexToRgb($hex) { |
| 8 |
$hex = str_replace("#", "", $hex); |
| 9 |
|
| 10 |
if (strlen($hex) == 3) { |
| 11 |
$r = hexdec(substr($hex, 0, 1) . substr($hex, 0, 1)); |
| 12 |
$g = hexdec(substr($hex, 1, 1) . substr($hex, 1, 1)); |
| 13 |
$b = hexdec(substr($hex, 2, 1) . substr($hex, 2, 1)); |
| 14 |
} else { |
| 15 |
$r = hexdec(substr($hex, 0, 2)); |
| 16 |
$g = hexdec(substr($hex, 2, 2)); |
| 17 |
$b = hexdec(substr($hex, 4, 2)); |
| 18 |
} |
| 19 |
|
| 20 |
return array('r' => $r, 'g' => $g, 'b' => $b); |
| 21 |
} |
| 22 |
|
| 23 |
private function rgbToHex($r, $g, $b) { |
| 24 |
return sprintf("#%02x%02x%02x", $r, $g, $b); |
| 25 |
} |
| 26 |
|
| 27 |
private function rgbToHsl($r, $g, $b) { |
| 28 |
$r /= 255; |
| 29 |
$g /= 255; |
| 30 |
$b /= 255; |
| 31 |
|
| 32 |
$max = max($r, $g, $b); |
| 33 |
$min = min($r, $g, $b); |
| 34 |
|
| 35 |
$h = 0; |
| 36 |
$s = 0; |
| 37 |
$l = ($max + $min) / 2; |
| 38 |
$d = $max - $min; |
| 39 |
|
| 40 |
if ($d != 0) { |
| 41 |
$s = $d / (1 - abs(2 * $l - 1)); |
| 42 |
|
| 43 |
switch ($max) { |
| 44 |
case $r: |
| 45 |
$h = 60 * fmod((($g - $b) / $d), 6); |
| 46 |
if ($b > $g) { |
| 47 |
$h += 360; |
| 48 |
} |
| 49 |
break; |
| 50 |
|
| 51 |
case $g: |
| 52 |
$h = 60 * (($b - $r) / $d + 2); |
| 53 |
break; |
| 54 |
|
| 55 |
case $b: |
| 56 |
$h = 60 * (($r - $g) / $d + 4); |
| 57 |
break; |
| 58 |
} |
| 59 |
} |
| 60 |
|
| 61 |
return array(round($h), round($s * 100), round($l * 100)); |
| 62 |
} |
| 63 |
|
| 64 |
private function hslToRgb($h, $s, $l) { |
| 65 |
$h /= 360; |
| 66 |
$s /= 100; |
| 67 |
$l /= 100; |
| 68 |
|
| 69 |
$r = 0; |
| 70 |
$g = 0; |
| 71 |
$b = 0; |
| 72 |
|
| 73 |
$c = (1 - abs(2 * $l - 1)) * $s; |
| 74 |
$x = $c * (1 - abs(fmod(($h * 6), 2) - 1)); |
| 75 |
$m = $l - ($c / 2); |
| 76 |
|
| 77 |
if (0 <= $h && $h < 1/6) { |
| 78 |
$r = $c; |
| 79 |
$g = $x; |
| 80 |
$b = 0; |
| 81 |
} else if (1/6 <= $h && $h < 1/3) { |
| 82 |
$r = $x; |
| 83 |
$g = $c; |
| 84 |
$b = 0; |
| 85 |
} else if (1/3 <= $h && $h < 1/2) { |
| 86 |
$r = 0; |
| 87 |
$g = $c; |
| 88 |
$b = $x; |
| 89 |
} else if (1/2 <= $h && $h < 2/3) { |
| 90 |
$r = 0; |
| 91 |
$g = $x; |
| 92 |
$b = $c; |
| 93 |
} else if (2/3 <= $h && $h < 5/6) { |
| 94 |
$r = $x; |
| 95 |
$g = 0; |
| 96 |
$b = $c; |
| 97 |
} else if (5/6 <= $h && $h < 1) { |
| 98 |
$r = $c; |
| 99 |
$g = 0; |
| 100 |
$b = $x; |
| 101 |
} else { |
| 102 |
$r = 0; |
| 103 |
$g = 0; |
| 104 |
$b = 0; |
| 105 |
} |
| 106 |
|
| 107 |
$r = ($r + $m) * 255; |
| 108 |
$g = ($g + $m) * 255; |
| 109 |
$b = ($b + $m) * 255; |
| 110 |
|
| 111 |
return array(round($r), round($g), round($b)); |
| 112 |
} |
| 113 |
|
| 114 |
private function contrastColor($color): array { |
| 115 |
$d = 0; |
| 116 |
|
| 117 |
// Counting the perceptive luminance - human eye favors green color... |
| 118 |
$luminance = (0.299 * $color['r'] + 0.587 * $color['g'] + 0.114 * $color['b']) / 255; |
| 119 |
|
| 120 |
if ($luminance > 0.5) |
| 121 |
$d = 0; // bright colors - black font |
| 122 |
else |
| 123 |
$d = 255; // dark colors - white font |
| 124 |
|
| 125 |
return array('r' => $d, 'g' => $d, 'b' => $d); |
| 126 |
} |
| 127 |
|
| 128 |
public function generateColorPalette($hex) { |
| 129 |
$rgb = $this->hexToRgb($hex); |
| 130 |
$textColor = $this->contrastColor($rgb); |
| 131 |
|
| 132 |
$palette = array(); |
| 133 |
|
| 134 |
// Title color (darker) |
| 135 |
$titleRgb = $this->contrastColor($rgb); |
| 136 |
$palette['title'] = $this->rgbToHex($titleRgb['r'], $titleRgb['g'], $titleRgb['b']); |
| 137 |
|
| 138 |
// Subtitle color (lighter) |
| 139 |
$subtitleRgb = $this->contrastColor($rgb); |
| 140 |
$palette['subtitle'] = $this->rgbToHex($subtitleRgb['r'], $subtitleRgb['g'], $subtitleRgb['b']); |
| 141 |
|
| 142 |
// Button color (more saturated and slightly lighter) |
| 143 |
$buttonRgb = $this->contrastColor($rgb); |
| 144 |
$palette['button'] = $this->rgbToHex($buttonRgb['r'], $buttonRgb['g'], $buttonRgb['b']); |
| 145 |
|
| 146 |
return $palette; |
| 147 |
} |
| 148 |
|
| 149 |
} |
| 150 |
|