From b7960ee74aba34d6f03e1684d6d5b307c1e49bc3 Mon Sep 17 00:00:00 2001 From: Jannik Renfordt Date: Mon, 1 Apr 2024 00:29:07 +0200 Subject: [PATCH] Refactor Color.php for better readability and logic The Color.php file was refactored to improve readability and streamline its logic. Color calculations are now separated into distinct methods and redundant code was eliminated. The changes also include reordering class methods for consistent access modifiers. --- src/Color.php | 234 ++++++++++++++++++++++++-------------------------- 1 file changed, 112 insertions(+), 122 deletions(-) diff --git a/src/Color.php b/src/Color.php index c1e5d15..907026d 100644 --- a/src/Color.php +++ b/src/Color.php @@ -83,6 +83,40 @@ public static function RGBToHSL(int $red, int $green, int $blue): array return array(round($hue), round($saturation, 2), round($lightness, 2)); } + /** + * Calculate the components Chroma, Value, and Hue based on RGB color. + * + * @param int $red The red component of the RGB color (0-255). + * @param int $green The green component of the RGB color (0-255). + * @param int $blue The blue component of the RGB color (0-255). + * @return array An array containing the calculated values (maxRGB, minRGB, chroma, value, hue). + */ + public static function calculateCVH(int $red, int $green, int $blue): array + { + $normalizedRed = $red / 255; + $normalizedGreen = $green / 255; + $normalizedBlue = $blue / 255; + + $maxRGB = max($normalizedRed, $normalizedGreen, $normalizedBlue); + $minRGB = min($normalizedRed, $normalizedGreen, $normalizedBlue); + $chroma = $maxRGB - $minRGB; + $value = $maxRGB; // also called brightness + if ($chroma == 0) { + $hue = 0; + } elseif ($maxRGB == $normalizedRed) { + $hue = 60 * (($normalizedGreen - $normalizedBlue) / $chroma); + } elseif ($maxRGB == $normalizedGreen) { + $hue = 60 * (2 + ($normalizedBlue - $normalizedRed) / $chroma); + } else { + $hue = 60 * (4 + ($normalizedRed - $normalizedGreen) / $chroma); + } + + if ($hue < 0) { + $hue += 360; + } + return array($maxRGB, $minRGB, $chroma, $value, $hue); + } + /** * Convert RGB color to HSV color space. * @@ -117,39 +151,48 @@ public static function RGBToHSV(int $red, int $green, int $blue): array */ public static function HSVToRGB(int $hue, float $saturation, float $value): array { - if ($hue < 0 || $hue > 360 || - $saturation < 0 || $saturation > 1 || - $value < 0 || $value > 1) { - throw new InvalidArgumentException('Parameters exceed their intended ranges.'); - } + self::validateParameters($hue, $saturation, $value); $chroma = $value * $saturation; $hueNormalized = $hue / 60; $hMod2 = $hueNormalized - 2 * floor($hueNormalized / 2); $secondMax = $chroma * (1 - abs($hMod2 - 1)); + list($r, $g, $b) = self::calculateRGBRange($hueNormalized, $chroma, $secondMax); + + return self::finalizeRGBCalculation($r, $g, $b, $value, $chroma); + } + + private static function validateParameters(int $hue, float $saturation, float $value): void + { + if ($hue < 0 || $hue > 360 || + $saturation < 0 || $saturation > 1 || + $value < 0 || $value > 1) { + throw new InvalidArgumentException('Parameters exceed their intended ranges.'); + } + } + + private static function calculateRGBRange(float $hueNormalized, float $chroma, float $secondMax): array + { if (0 <= $hueNormalized && $hueNormalized < 1) { - list($r, $g, $b) = array($chroma, $secondMax, 0); + return [$chroma, $secondMax, 0]; } elseif (1 <= $hueNormalized && $hueNormalized < 2) { - list($r, $g, $b) = array($secondMax, $chroma, 0); + return [$secondMax, $chroma, 0]; } elseif (2 <= $hueNormalized && $hueNormalized < 3) { - list($r, $g, $b) = array(0, $chroma, $secondMax); + return [0, $chroma, $secondMax]; } elseif (3 <= $hueNormalized && $hueNormalized < 4) { - list($r, $g, $b) = array(0, $secondMax, $chroma); + return [0, $secondMax, $chroma]; } elseif (4 <= $hueNormalized && $hueNormalized < 5) { - list($r, $g, $b) = array($secondMax, 0, $chroma); - } elseif (5 <= $hueNormalized && $hueNormalized < 6) { - list($r, $g, $b) = array($chroma, 0, $secondMax); - } - if (!isset($r) || !isset($g) || !isset($b)) { - throw new Exception('RGB calculation not possible. Check inputs!'); + return [$secondMax, 0, $chroma]; + } else { + return [$chroma, 0, $secondMax]; } - $m = $value - $chroma; - $r = intval(round(($r + $m) * 255)); - $g = intval(round(($g + $m) * 255)); - $b = intval(round(($b + $m) * 255)); + } - return array($r, $g, $b); + private static function finalizeRGBCalculation(float $r, float $g, float $b, float $value, float $chroma): array + { + $m = $value - $chroma; + return array_map(fn($x) => intval(round(($x + $m) * 255)), [$r, $g, $b]); } /** @@ -168,40 +211,6 @@ public static function RGBToHex(int $red, int $green, int $blue): string return $hexr.$hexg.$hexb; } - /** - * Calculate the components Chroma, Value, and Hue based on RGB color. - * - * @param int $red The red component of the RGB color (0-255). - * @param int $green The green component of the RGB color (0-255). - * @param int $blue The blue component of the RGB color (0-255). - * @return array An array containing the calculated values (maxRGB, minRGB, chroma, value, hue). - */ - public static function calculateCVH(int $red, int $green, int $blue): array - { - $normalizedRed = $red / 255; - $normalizedGreen = $green / 255; - $normalizedBlue = $blue / 255; - - $maxRGB = max($normalizedRed, $normalizedGreen, $normalizedBlue); - $minRGB = min($normalizedRed, $normalizedGreen, $normalizedBlue); - $chroma = $maxRGB - $minRGB; - $value = $maxRGB; // also called brightness - if ($chroma == 0) { - $hue = 0; - } elseif ($maxRGB == $normalizedRed) { - $hue = 60 * (($normalizedGreen - $normalizedBlue) / $chroma); - } elseif ($maxRGB == $normalizedGreen) { - $hue = 60 * (2 + ($normalizedBlue - $normalizedRed) / $chroma); - } else { - $hue = 60 * (4 + ($normalizedRed - $normalizedGreen) / $chroma); - } - - if ($hue < 0) { - $hue += 360; - } - return array($maxRGB, $minRGB, $chroma, $value, $hue); - } - /** * Convert HSL color to RGB color space. * @@ -218,60 +227,19 @@ private static function HSLToRGB(int $hue, float $saturation, float $lightness): $hMod2 = $hueNormalized - 2 * floor($hueNormalized / 2); $intermediateValue = $chroma * (1 - abs($hMod2 - 1)); - if (0 <= $hueNormalized && $hueNormalized < 1) { - list($r, $g, $b) = array($chroma, $intermediateValue, 0); - } elseif (1 <= $hueNormalized && $hueNormalized < 2) { - list($r, $g, $b) = array($intermediateValue, $chroma, 0); - } elseif (2 <= $hueNormalized && $hueNormalized < 3) { - list($r, $g, $b) = array(0, $chroma, $intermediateValue); - } elseif (3 <= $hueNormalized && $hueNormalized < 4) { - list($r, $g, $b) = array(0, $intermediateValue, $chroma); - } elseif (4 <= $hueNormalized && $hueNormalized < 5) { - list($r, $g, $b) = array($intermediateValue, 0, $chroma); - } elseif (5 <= $hueNormalized && $hueNormalized < 6) { - list($r, $g, $b) = array($chroma, 0, $intermediateValue); - } - if (!isset($r) || !isset($g) || !isset($b)) { - throw new Exception('RGB calculation not possible. Check inputs!'); - } - $m = $lightness - $chroma / 2; - $r = intval(round(($r + $m) * 255)); - $g = intval(round(($g + $m) * 255)); - $b = intval(round(($b + $m) * 255)); - - return array($r, $g, $b); - } - - /** - * Set the hexadecimal color value. - * - * @param string $color The hexadecimal color value. - * @return void - */ - public function setHex(string $color): void - { - if (!preg_match("/#[0-9a-fA-F]{3}/", $color) && - !preg_match("/#[0-9a-fA-F]{6}/", $color)) { - return; - } - $color = substr($color, 1); - $this->hex = $color; + list($r, $g, $b) = self::calculateRGBRange($hueNormalized, $chroma, $intermediateValue); - $this->rgb = Color::HexToRGB($this->hex); - $this->hsl = Color::RGBToHSL($this->rgb[0], $this->rgb[1], $this->rgb[2]); + return self::finalizeRGBCalculation($r, $g, $b, $lightness, $chroma); } /** - * Set the RGB color. + * Get the HSL color values of the current object. * - * @param array $color An array containing the RGB color values (red, green, blue). - * @return void + * @return array An array containing the HSL color values (hue, saturation, lightness). */ - public function setRGB(array $color): void + public function getHSL(): array { - $this->rgb = $color; - $this->hex = Color::RGBToHex($color[0], $color[1], $color[2]); - $this->hsl = Color::RGBToHSL($color[0], $color[1], $color[2]); + return $this->hsl; } /** @@ -288,23 +256,26 @@ public function setHSL(array $color): void } /** - * Get the HSL color values of the current object. + * Get the RGB color values. * - * @return array An array containing the HSL color values (hue, saturation, lightness). + * @return array An array containing the RGB color values (red, green, blue). */ - public function getHSL(): array + public function getRGB(): array { - return $this->hsl; + return $this->rgb; } /** - * Get the RGB color values. + * Set the RGB color. * - * @return array An array containing the RGB color values (red, green, blue). + * @param array $color An array containing the RGB color values (red, green, blue). + * @return void */ - public function getRGB(): array + public function setRGB(array $color): void { - return $this->rgb; + $this->rgb = $color; + $this->hex = Color::RGBToHex($color[0], $color[1], $color[2]); + $this->hsl = Color::RGBToHSL($color[0], $color[1], $color[2]); } /** @@ -317,6 +288,25 @@ public function getHex(): string return '#'.$this->hex; } + /** + * Set the hexadecimal color value. + * + * @param string $color The hexadecimal color value. + * @return void + */ + public function setHex(string $color): void + { + if (!preg_match("/#[0-9a-fA-F]{3}/", $color) && + !preg_match("/#[0-9a-fA-F]{6}/", $color)) { + return; + } + $color = substr($color, 1); + $this->hex = $color; + + $this->rgb = Color::HexToRGB($this->hex); + $this->hsl = Color::RGBToHSL($this->rgb[0], $this->rgb[1], $this->rgb[2]); + } + /** * Get the color set based on the HSL values of the color. * @@ -350,19 +340,6 @@ public function brighten(int $amount = 10): void $this->setHSL(array($hue, $saturation, $lightness)); } - /** - * Darken the color by reducing its lightness value. - * - * @param int $amount The amount by which to darken the color (0-100). - * @return void - */ - public function darken(int $amount = 10): void - { - list($hue, $saturation, $lightness) = $this->hsl; - $lightness = self::clamp($lightness - $amount / 100, 0, 1); - $this->setHSL(array($hue, $saturation, $lightness)); - } - /** * Clamp a number between a minimum and maximum value. * @@ -381,4 +358,17 @@ private static function clamp(int|float $num, int|float $min, int|float $max): i return $num; } + /** + * Darken the color by reducing its lightness value. + * + * @param int $amount The amount by which to darken the color (0-100). + * @return void + */ + public function darken(int $amount = 10): void + { + list($hue, $saturation, $lightness) = $this->hsl; + $lightness = self::clamp($lightness - $amount / 100, 0, 1); + $this->setHSL(array($hue, $saturation, $lightness)); + } + } \ No newline at end of file