Color Coordinates class udpates

move creation into the main constructor and do not rely on "::create" or
any other pass through creation.

Make all constructors equal with options array so we can create an Interface

Remove all outsite setters. Once a color is set this color stays
This commit is contained in:
Clemens Schwaighofer
2024-11-14 14:51:31 +09:00
parent 32c192a362
commit 3845bc7ff5
11 changed files with 351 additions and 150 deletions

View File

@@ -83,7 +83,7 @@ class CieXyz
}
/**
* Undocumented function
* Convert from oklab to cie lab
*
* @param Lab $lab
* @return Lab
@@ -98,7 +98,7 @@ class CieXyz
}
/**
* Undocumented function
* Convert from cie lab to oklab
*
* @param Lab $lab
* @return Lab
@@ -122,14 +122,14 @@ class CieXyz
*/
private static function xyzD65ToXyzD50(XYZ $xyz): XYZ
{
return XYZ::__constructFromArray(Math::multiplyMatrices(
return new XYZ(Math::multiplyMatrices(
a: [
[1.0479298208405488, 0.022946793341019088, -0.05019222954313557],
[0.029627815688159344, 0.990434484573249, -0.01707382502938514],
[-0.009243058152591178, 0.015055144896577895, 0.7518742899580008],
],
b: $xyz->returnAsArray(),
), whitepoint: 'D50');
), options: ["whitepoint" => 'D50']);
}
/**
@@ -140,14 +140,14 @@ class CieXyz
*/
private static function xyzD50ToXyxD65(XYZ $xyz): XYZ
{
return XYZ::__constructFromArray(Math::multiplyMatrices(
return new XYZ(Math::multiplyMatrices(
a: [
[0.9554734527042182, -0.023098536874261423, 0.0632593086610217],
[-0.028369706963208136, 1.0099954580058226, 0.021041398966943008],
[0.012314001688319899, -0.020507696433477912, 1.3303659366080753],
],
b: $xyz->returnAsArray()
), whitepoint: 'D65');
), options: ["whitepoint" => 'D65']);
}
// MARK: xyzD50 <-> Lab
@@ -184,7 +184,7 @@ class CieXyz
$_xyz,
);
return Lab::__constructFromArray([
return new Lab([
(116 * $f[1]) - 16,
500 * ($f[0] - $f[1]),
200 * ($f[1] - $f[2]),
@@ -227,13 +227,13 @@ class CieXyz
(1.0 - 0.3457 - 0.3585) / 0.3585,
];
return XYZ::__constructFromArray(
return new XYZ(
array_map(
fn ($k, $v) => $v * $d50[$k],
array_keys($xyz),
array_values($xyz),
),
whitepoint: 'D50'
options: ["whitepoint" => 'D50']
);
}
@@ -252,14 +252,14 @@ class CieXyz
if (!$rgb->linear) {
$rgb->toLinear();
}
return XYZ::__constructFromArray(Math::multiplyMatrices(
return new XYZ(Math::multiplyMatrices(
[
[0.41239079926595934, 0.357584339383878, 0.1804807884018343],
[0.21263900587151027, 0.715168678767756, 0.07219231536073371],
[0.01933081871559182, 0.11919477979462598, 0.9505321522496607],
],
$rgb->returnAsArray()
), whitepoint: 'D65');
), options: ["whitepoint" => 'D65']);
}
/**
@@ -271,14 +271,14 @@ class CieXyz
private static function xyzD65ToLinRgb(XYZ $xyz): RGB
{
// xyz D65 to linrgb
return RGB::__constructFromArray(Math::multiplyMatrices(
return new RGB(Math::multiplyMatrices(
a : [
[ 3.2409699419045226, -1.537383177570094, -0.4986107602930034 ],
[ -0.9692436362808796, 1.8759675015077202, 0.04155505740717559 ],
[ 0.05563007969699366, -0.20397695888897652, 1.0569715142428786 ],
],
b : $xyz->returnAsArray()
), linear: true);
), options: ["linear" => true]);
}
// MARK: xyzD65 <-> OkLab
@@ -291,7 +291,7 @@ class CieXyz
*/
private static function xyzD65ToOkLab(XYZ $xyz): Lab
{
return Lab::__constructFromArray(Math::multiplyMatrices(
return new Lab(Math::multiplyMatrices(
[
[0.2104542553, 0.7936177850, -0.0040720468],
[1.9779984951, -2.4285922050, 0.4505937099],
@@ -319,7 +319,7 @@ class CieXyz
*/
private static function okLabToXyzD65(Lab $lab): XYZ
{
return XYZ::__constructFromArray(Math::multiplyMatrices(
return new XYZ(Math::multiplyMatrices(
a: [
[1.2268798733741557, -0.5578149965554813, 0.28139105017721583],
[-0.04057576262431372, 1.1122868293970594, -0.07171106666151701],
@@ -337,7 +337,7 @@ class CieXyz
b: $lab->returnAsArray(),
),
),
), whitepoint: 'D65');
), options: ["whitepoint" => 'D65']);
}
}

View File

@@ -109,7 +109,7 @@ class Color
// achromatic
if ($chroma == 0) {
// H, S, L
return HSL::__constructFromArray([
return new HSL([
0.0,
0.0,
$lum * 100,
@@ -128,7 +128,7 @@ class Color
}
$hue = $hue * 60;
// $sat = 1 - abs(2 * $lum - 1);
return HSL::__constructFromArray([
return new HSL([
$hue,
$sat * 100,
$lum * 100,
@@ -158,7 +158,7 @@ class Color
// if saturation is 0
if ($sat == 0) {
$lum = round($lum * 255);
return RGB::__constructFromArray([$lum, $lum, $lum]);
return new RGB([$lum, $lum, $lum]);
} else {
$m2 = $lum < 0.5 ? $lum * ($sat + 1) : ($lum + $sat) - ($lum * $sat);
$m1 = $lum * 2 - $m2;
@@ -180,7 +180,7 @@ class Color
return $m1;
};
return RGB::__constructFromArray([
return new RGB([
255 * $hueue($hue + (1 / 3)),
255 * $hueue($hue),
255 * $hueue($hue - (1 / 3)),
@@ -212,7 +212,7 @@ class Color
// achromatic
if ($MAX == $MIN) {
return HSB::__constructFromArray([0, 0, $MAX * 100]);
return new HSB([0, 0, $MAX * 100]);
}
if ($red == $MAX) {
$HUE = fmod(($green - $blue) / $DELTA, 6);
@@ -227,7 +227,7 @@ class Color
$HUE += 360;
}
return HSB::__constructFromArray([
return new HSB([
$HUE, // Hue
($DELTA / $MAX) * 100, // Saturation
$MAX * 100, // Brightness
@@ -255,7 +255,7 @@ class Color
if ($S == 0) {
$V = $V * 255;
return RGB::__constructFromArray([$V, $V, $V]);
return new RGB([$V, $V, $V]);
}
$Hi = floor($H / 60);
@@ -301,7 +301,7 @@ class Color
$blue = 0;
}
return RGB::__constructFromArray([
return new RGB([
$red * 255,
$green * 255,
$blue * 255,
@@ -365,7 +365,7 @@ class Color
0 :
200 * (1 - $lightness / $value);
$value *= 100;
return HSB::__constructFromArray([
return new HSB([
$hsl->H,
$saturation,
$value,
@@ -392,7 +392,7 @@ class Color
100 * ($value - $lightness) / min($lightness, 1 - $lightness)
;
return HSL::__constructFromArray([
return new HSL([
$hue,
$saturation,
$lightness * 100,
@@ -442,7 +442,7 @@ class Color
public static function hsbToHwb(HSB $hsb): HWB
{
// hsv\Hwb
return HWB::__constructFromArray([
return new HWB([
$hsb->H, // hue,
$hsb->B * (100 - $hsb->S) / 100, // 2: brightness, 1: saturation
100 - $hsb->B,
@@ -473,7 +473,7 @@ class Color
$value *= 100;
}
return HSB::__constructFromArray([
return new HSB([
$hue,
$saturation,
$value,
@@ -491,7 +491,7 @@ class Color
public static function labToLch(Lab $lab): LCH
{
// cieLab to cieLch
return LCH::__constructFromArray(self::__labToLch($lab), colorspace: 'CIELab');
return new LCH(self::__labToLch($lab), colorspace: 'CIELab');
}
/**
@@ -502,7 +502,7 @@ class Color
*/
public static function lchToLab(LCH $lch): Lab
{
return Lab::__constructFromArray(self::__lchToLab($lch), colorspace: 'CIELab');
return new Lab(self::__lchToLab($lch), colorspace: 'CIELab');
}
// MARK: OkLch <-> OkLab
@@ -516,7 +516,7 @@ class Color
public static function okLabToOkLch(Lab $lab): LCH
{
// okLab\toOkLch
return LCH::__constructFromArray(self::__labToLch($lab), colorspace: 'OkLab');
return new LCH(self::__labToLch($lab), colorspace: 'OkLab');
}
/**
@@ -529,7 +529,7 @@ class Color
{
// oklch/toOkLab
// oklch to oklab
return Lab::__constructFromArray(self::__lchToLab($lch), colorspace: 'OkLab');
return new Lab(self::__lchToLab($lch), colorspace: 'OkLab');
}
// MARK: rgb <-> oklab

View File

@@ -11,7 +11,7 @@ declare(strict_types=1);
namespace CoreLibs\Convert\Color\Coordinates;
class HSB
class HSB implements Interface\CoordinatesInterface
{
/** @var array<string> allowed colorspaces */
private const COLORSPACES = ['sRGB'];
@@ -29,22 +29,43 @@ class HSB
/**
* HSB (HSV) color coordinates
* Hue/Saturation/Brightness or Value
*
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=sRGB]
* @param array<string,string> $options [default=[]]
* @throws \InvalidArgumentException only array colors allowed
*/
public function __construct()
public function __construct(string|array $colors, string $colorspace = 'sRGB', array $options = [])
{
if (!is_array($colors)) {
throw new \InvalidArgumentException('Only array colors allowed', 0);
}
$this->setColorspace($colorspace)->parseOptions($options)->setFromArray($colors);
}
/**
* set from array
* where 0: Hue, 1: Saturation, 2: Brightness
*
* @param array{0:float,1:float,2:float} $colors
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=sRGB]
* @param array<string,string> $options [default=[]]
* @return self
*/
public static function __constructFromArray(array $colors, string $colorspace = 'sRGB'): self
public static function create(string|array $colors, string $colorspace = 'sRGB', array $options = []): self
{
return (new HSB())->setColorspace($colorspace)->setFromArray($colors);
return new HSB($colors, $colorspace, $options);
}
/**
* parse options
*
* @param array<string,string> $options
* @return self
*/
private function parseOptions(array $options): self
{
return $this;
}
/**
@@ -54,7 +75,7 @@ class HSB
* @param float $value
* @return void
*/
public function __set(string $name, float $value): void
private function set(string $name, float $value): void
{
$name = strtoupper($name);
if (!property_exists($this, $name)) {
@@ -65,9 +86,9 @@ class HSB
if ((int)$value == 360) {
$value = 0;
}
if ((int)$value < 0 || (int)$value > 359) {
if ((int)$value < 0 || (int)$value > 360) {
throw new \LengthException(
'Argument value ' . $value . ' for hue is not in the range of 0 to 359',
'Argument value ' . $value . ' for hue is not in the range of 0 to 360',
1
);
}
@@ -98,7 +119,7 @@ class HSB
* @param string $name
* @return float
*/
public function __get(string $name): float
public function __get(string $name): float|string|bool
{
$name = strtoupper($name);
if (!property_exists($this, $name)) {
@@ -140,11 +161,11 @@ class HSB
* @param array{0:float,1:float,2:float} $colors
* @return self
*/
public function setFromArray(array $colors): self
private function setFromArray(array $colors): self
{
$this->__set('H', $colors[0]);
$this->__set('S', $colors[1]);
$this->__set('B', $colors[2]);
$this->set('H', $colors[0]);
$this->set('S', $colors[1]);
$this->set('B', $colors[2]);
return $this;
}

View File

@@ -13,7 +13,7 @@ namespace CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Convert\Color\Stringify;
class HSL
class HSL implements Interface\CoordinatesInterface
{
/** @var array<string> allowed colorspaces */
private const COLORSPACES = ['sRGB'];
@@ -31,22 +31,43 @@ class HSL
/**
* Color Coordinate HSL
* Hue/Saturation/Lightness
*
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=sRGB]
* @param array<string,string> $options [default=[]]
* @throws \InvalidArgumentException only array colors allowed
*/
public function __construct()
public function __construct(string|array $colors, string $colorspace = 'sRGB', array $options = [])
{
if (!is_array($colors)) {
throw new \InvalidArgumentException('Only array colors allowed', 0);
}
$this->setColorspace($colorspace)->parseOptions($options)->setFromArray($colors);
}
/**
* set from array
* where 0: Hue, 1: Saturation, 2: Lightness
*
* @param array{0:float,1:float,2:float} $colors
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=sRGB]
* @param array<string,string> $options [default=[]]
* @return self
*/
public static function __constructFromArray(array $colors, string $colorspace = 'sRGB'): self
public static function create(string|array $colors, string $colorspace = 'sRGB', array $options = []): self
{
return (new HSL())->setColorspace($colorspace)->setFromArray($colors);
return new HSL($colors, $colorspace, $options);
}
/**
* parse options
*
* @param array<string,string> $options
* @return self
*/
private function parseOptions(array $options): self
{
return $this;
}
/**
@@ -56,7 +77,7 @@ class HSL
* @param float $value
* @return void
*/
public function __set(string $name, float $value): void
private function set(string $name, float $value): void
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -66,9 +87,9 @@ class HSL
if ((int)$value == 360) {
$value = 0;
}
if ((int)$value < 0 || (int)$value > 359) {
if ((int)$value < 0 || (int)$value > 360) {
throw new \LengthException(
'Argument value ' . $value . ' for hue is not in the range of 0 to 359',
'Argument value ' . $value . ' for hue is not in the range of 0 to 360',
1
);
}
@@ -84,7 +105,7 @@ class HSL
case 'L':
if ((int)$value < 0 || (int)$value > 100) {
throw new \LengthException(
'Argument value ' . $value . ' for luminance is not in the range of 0 to 100',
'Argument value ' . $value . ' for lightness is not in the range of 0 to 100',
3
);
}
@@ -99,7 +120,7 @@ class HSL
* @param string $name
* @return float
*/
public function __get(string $name): float
public function __get(string $name): float|string|bool
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -140,11 +161,11 @@ class HSL
* @param array{0:float,1:float,2:float} $colors
* @return self
*/
public function setFromArray(array $colors): self
private function setFromArray(array $colors): self
{
$this->__set('H', $colors[0]);
$this->__set('S', $colors[1]);
$this->__set('L', $colors[2]);
$this->set('H', $colors[0]);
$this->set('S', $colors[1]);
$this->set('L', $colors[2]);
return $this;
}

View File

@@ -13,7 +13,7 @@ namespace CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Convert\Color\Stringify;
class HWB
class HWB implements Interface\CoordinatesInterface
{
/** @var array<string> allowed colorspaces */
private const COLORSPACES = ['sRGB'];
@@ -31,22 +31,43 @@ class HWB
/**
* Color Coordinate: HWB
* Hue/Whiteness/Blackness
*
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=sRGB]
* @param array<string,string> $options [default=[]]
* @throws \InvalidArgumentException only array colors allowed
*/
public function __construct()
public function __construct(string|array $colors, string $colorspace = 'sRGB', array $options = [])
{
if (!is_array($colors)) {
throw new \InvalidArgumentException('Only array colors allowed', 0);
}
$this->setColorspace($colorspace)->parseOptions($options)->setFromArray($colors);
}
/**
* set from array
* where 0: Hue, 1: Whiteness, 2: Blackness
*
* @param array{0:float,1:float,2:float} $colors
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=sRGB]
* @param array<string,string> $options [default=[]]
* @return self
*/
public static function __constructFromArray(array $colors, string $colorspace = 'sRGB'): self
public static function create(string|array $colors, string $colorspace = 'sRGB', array $options = []): self
{
return (new HWB())->setColorspace($colorspace)->setFromArray($colors);
return new HWB($colors, $colorspace, $options);
}
/**
* parse options
*
* @param array<string,string> $options
* @return self
*/
private function parseOptions(array $options): self
{
return $this;
}
/**
@@ -56,7 +77,7 @@ class HWB
* @param float $value
* @return void
*/
public function __set(string $name, float $value): void
private function set(string $name, float $value): void
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -76,7 +97,7 @@ class HWB
case 'W':
if ((int)$value < 0 || (int)$value > 100) {
throw new \LengthException(
'Argument value ' . $value . ' for saturation is not in the range of 0 to 100',
'Argument value ' . $value . ' for whiteness is not in the range of 0 to 100',
2
);
}
@@ -84,7 +105,7 @@ class HWB
case 'B':
if ((int)$value < 0 || (int)$value > 100) {
throw new \LengthException(
'Argument value ' . $value . ' for luminance is not in the range of 0 to 100',
'Argument value ' . $value . ' for blackness is not in the range of 0 to 100',
3
);
}
@@ -99,7 +120,7 @@ class HWB
* @param string $name
* @return float
*/
public function __get(string $name): float
public function __get(string $name): float|string|bool
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -140,11 +161,11 @@ class HWB
* @param array{0:float,1:float,2:float} $colors
* @return self
*/
public function setFromArray(array $colors): self
private function setFromArray(array $colors): self
{
$this->__set('H', $colors[0]);
$this->__set('W', $colors[1]);
$this->__set('B', $colors[2]);
$this->set('H', $colors[0]);
$this->set('W', $colors[1]);
$this->set('B', $colors[2]);
return $this;
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* AUTHOR: Clemens Schwaighofer
* CREATED: Ymd
* DESCRIPTION:
* DescriptionHere
*/
declare(strict_types=1);
namespace CoreLibs\Convert\Color\Coordinates\Interface;
interface CoordinatesInterface
{
/**
* create class via "Class::create()" call
* was used for multiple create interfaces
* no longer needed, use "new Class()" instead
*
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default='']
* @param array<string,string|bool|int> $options [default=[]]
* @return self
*/
public static function create(string|array $colors, string $colorspace = '', array $options = []): self;
/**
* get color
*
* @param string $name
* @return float
*/
public function __get(string $name): float|string|bool;
/**
* Returns the color as array
* where 0: Lightness, 1: a, 2: b
*
* @return array{0:float,1:float,2:float}
*/
public function returnAsArray(): array;
/**
* Convert into css string with optional opacity
*
* @param null|float|string|null $opacity
* @return string
*/
public function toCssString(null|float|string $opacity = null): string;
}
// __END__

View File

@@ -14,7 +14,7 @@ namespace CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Convert\Color\Stringify;
class LCH
class LCH implements Interface\CoordinatesInterface
{
/** @var array<string> allowed colorspaces */
private const COLORSPACES = ['OkLab', 'CIELab'];
@@ -42,22 +42,43 @@ class LCH
/**
* Color Coordinate Lch
* for oklch
*
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default='']
* @param array<string,string> $options [default=[]]
* @throws \InvalidArgumentException only array colors allowed
*/
public function __construct()
public function __construct(string|array $colors, string $colorspace = '', array $options = [])
{
if (!is_array($colors)) {
throw new \InvalidArgumentException('Only array colors allowed', 0);
}
$this->setColorspace($colorspace)->parseOptions($options)->setFromArray($colors);
}
/**
* set from array
* where 0: Lightness, 1: Chroma, 2: Hue
*
* @param array{0:float,1:float,2:float} $colors
* @param string $colorspace
* @param string|{0:float,1:float,2:float} $colors
* @param string $colorspace [default='']
* @param array<string,string> $options [default=[]]
* @return self
*/
public static function __constructFromArray(array $colors, string $colorspace): self
public static function create(string|array $colors, string $colorspace = '', array $options = []): self
{
return (new LCH())->setColorspace($colorspace)->setFromArray($colors);
return new LCH($colors, $colorspace, $options);
}
/**
* parse options
*
* @param array<string,string> $options
* @return self
*/
private function parseOptions(array $options): self
{
return $this;
}
/**
@@ -67,7 +88,7 @@ class LCH
* @param float $value
* @return void
*/
public function __set(string $name, float $value): void
private function set(string $name, float $value): void
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -124,7 +145,7 @@ class LCH
* @param string $name
* @return float
*/
public function __get(string $name): float
public function __get(string $name): float|string|bool
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -165,11 +186,11 @@ class LCH
* @param array{0:float,1:float,2:float} $colors
* @return self
*/
public function setFromArray(array $colors): self
private function setFromArray(array $colors): self
{
$this->__set('L', $colors[0]);
$this->__set('C', $colors[1]);
$this->__set('H', $colors[2]);
$this->set('L', $colors[0]);
$this->set('C', $colors[1]);
$this->set('H', $colors[2]);
return $this;
}

View File

@@ -14,7 +14,7 @@ namespace CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Convert\Color\Stringify;
class Lab
class Lab implements Interface\CoordinatesInterface
{
/** @var array<string> allowed colorspaces */
private const COLORSPACES = ['OkLab', 'CIELab'];
@@ -44,22 +44,43 @@ class Lab
/**
* Color Coordinate: Lab
* for oklab or cie
*
* @param string|array{0:float,1:float,2:float} $rgb
* @param string $colorspace [default='']
* @param array<string,string> $options [default=[]]
* @throws \InvalidArgumentException only array colors allowed
*/
public function __construct()
public function __construct(string|array $colors, string $colorspace = '', array $options = [])
{
if (!is_array($colors)) {
throw new \InvalidArgumentException('Only array colors allowed', 0);
}
$this->setColorspace($colorspace)->parseOptions($options)->setFromArray($colors);
}
/**
* set from array
* where 0: Lightness, 1: a, 2: b
*
* @param array{0:float,1:float,2:float} $rgb
* @param string $colorspace
* @param array{0:float,1:float,2:float} $rgb
* @param string $colorspace [default='']
* @param array<string,string> $options [default=[]]
* @return self
*/
public static function __constructFromArray(array $colors, string $colorspace): self
public static function create(string|array $colors, string $colorspace = '', array $options = []): self
{
return (new Lab())->setColorspace($colorspace)->setFromArray($colors);
return new Lab($colors, $colorspace, $options);
}
/**
* parse options
*
* @param array<string,string> $options
* @return self
*/
private function parseOptions(array $options): self
{
return $this;
}
/**
@@ -69,7 +90,7 @@ class Lab
* @param float $value
* @return void
*/
public function __set(string $name, float $value): void
private function set(string $name, float $value): void
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -112,7 +133,7 @@ class Lab
* @param string $name
* @return float
*/
public function __get(string $name): float
public function __get(string $name): float|string|bool
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -153,11 +174,11 @@ class Lab
* @param array{0:float,1:float,2:float} $colors
* @return self
*/
public function setFromArray(array $colors): self
private function setFromArray(array $colors): self
{
$this->__set('L', $colors[0]);
$this->__set('a', $colors[1]);
$this->__set('b', $colors[2]);
$this->set('L', $colors[0]);
$this->set('a', $colors[1]);
$this->set('b', $colors[2]);
return $this;
}

View File

@@ -13,7 +13,7 @@ namespace CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Convert\Color\Stringify;
class RGB
class RGB implements Interface\CoordinatesInterface
{
/** @var array<string> allowed colorspaces */
private const COLORSPACES = ['sRGB'];
@@ -33,41 +33,48 @@ class RGB
/**
* Color Coordinate RGB
* @param array{0:float,1:float,2:float}|string $colors RGB color array or hex string
* @param string $colorspace [default=sRGB]
* @param array<string,bool> $options [default=[]] only "linear" allowed at the moment
*/
public function __construct()
public function __construct(string|array $colors, string $colorspace = 'sRGB', array $options = [])
{
$this->setColorspace($colorspace)->parseOptions($options);
if (is_array($colors)) {
$this->setFromArray($colors);
} else {
$this->setFromHex($colors);
}
}
/**
* set from array
* set from array or string
* where 0: Red, 1: Green, 2: Blue
* OR #ffffff or ffffff
*
* @param array{0:float,1:float,2:float} $colors
* @param array{0:float,1:float,2:float}|string $colors RGB color array or hex string
* @param string $colorspace [default=sRGB]
* @param bool $linear [default=false]
* @param array<string,bool> $options [default=[]] only "linear" allowed at the moment
* @return self
*/
public static function __constructFromArray(array $colors, string $colorspace = 'sRGB', bool $linear = false): self
public static function create(string|array $colors, string $colorspace = 'sRGB', array $options = []): self
{
return (new RGB())->setColorspace($colorspace)->flagLinear($linear)->setFromArray($colors);
return new RGB($colors, $colorspace, $options);
}
/**
* Undocumented function
* parse options
*
* @param string $hex_string
* @param string $colorspace
* @param bool $linear
* @param array<string,bool> $options
* @return self
*/
public static function __constructFromHexString(
string $hex_string,
string $colorspace = 'sRGB',
bool $linear = false
): self {
return (new RGB())->setColorspace($colorspace)->flagLinear($linear)->setFromHex($hex_string);
private function parseOptions(array $options): self
{
$this->flagLinear($options['linear'] ?? false);
return $this;
}
/**
* set color
*
@@ -75,7 +82,7 @@ class RGB
* @param float $value
* @return void
*/
public function __set(string $name, float $value): void
private function set(string $name, float $value): void
{
// do not allow setting linear from outside
if ($name == 'linear') {
@@ -90,7 +97,7 @@ class RGB
. ' is not in the range of 0 to 255', 1);
} elseif ($this->linear && ((int)$value < 0 || (int)$value > 1)) {
throw new \LengthException('Argument value ' . $value . ' for color ' . $name
. ' is not in the range of 0 to 1 for linear rgb', 1);
. ' is not in the range of 0 to 1 for linear rgb', 2);
}
$this->$name = $value;
}
@@ -101,7 +108,7 @@ class RGB
* @param string $name
* @return float|bool
*/
public function __get(string $name): float|bool
public function __get(string $name): float|string|bool
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -142,11 +149,11 @@ class RGB
* @param array{0:float,1:float,2:float} $colors
* @return self
*/
public function setFromArray(array $colors): self
private function setFromArray(array $colors): self
{
$this->__set('R', $colors[0]);
$this->__set('G', $colors[1]);
$this->__set('B', $colors[2]);
$this->set('R', $colors[0]);
$this->set('G', $colors[1]);
$this->set('B', $colors[2]);
return $this;
}
@@ -179,11 +186,11 @@ class RGB
* @param string $hex_string
* @return self
*/
public function setFromHex(string $hex_string): self
private function setFromHex(string $hex_string): self
{
$hex_string = preg_replace("/[^0-9A-Fa-f]/", '', $hex_string); // Gets a proper hex string
if (!is_string($hex_string)) {
throw new \InvalidArgumentException('hex_string argument cannot be empty', 1);
if (empty($hex_string) || !is_string($hex_string)) {
throw new \InvalidArgumentException('hex_string argument cannot be empty', 3);
}
$rgbArray = [];
if (strlen($hex_string) == 6) {
@@ -204,7 +211,7 @@ class RGB
];
} else {
// Invalid hex color code
throw new \UnexpectedValueException('Invalid hex_string: ' . $hex_string, 2);
throw new \UnexpectedValueException('Invalid hex_string: ' . $hex_string, 4);
}
return $this->setFromArray($rgbArray);
}

View File

@@ -15,7 +15,7 @@ declare(strict_types=1);
namespace CoreLibs\Convert\Color\Coordinates;
class XYZ
class XYZ implements Interface\CoordinatesInterface
{
/** @var array<string> allowed colorspaces */
private const COLORSPACES = ['CIEXYZ'];
@@ -35,34 +35,58 @@ class XYZ
/** @var string color space: either ok or cie */
private string $colorspace = '';
/** @var string illuminat white point: only D50 and D65 are allowed */
private string $whitepoint = '';
/**
* Color Coordinate Lch
* for oklch
* for oklch conversion
*
* @param string|array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=CIEXYZ]
* @param array<string,string> $options [default=[]] Only "whitepoint" option allowed
* @throws \InvalidArgumentException only array colors allowed
*/
public function __construct()
{
public function __construct(
string|array $colors,
string $colorspace = 'CIEXYZ',
array $options = [],
) {
if (!is_array($colors)) {
throw new \InvalidArgumentException('Only array colors allowed', 0);
}
$this->setColorspace($colorspace)
->parseOptions($options)
->setFromArray($colors);
}
/**
* set from array
* where 0: X, 1: Y, 2: Z
*
* @param array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=CIEXYZ]
* @param string $whitepoint [default=''] only D65 or D50 allowed
* @param array{0:float,1:float,2:float} $colors
* @param string $colorspace [default=CIEXYZ]
* @param array<string,string> $options [default=[]] Only "whitepoint" option allowed
* @return self
*/
public static function __constructFromArray(
array $colors,
public static function create(
string|array $colors,
string $colorspace = 'CIEXYZ',
string $whitepoint = ''
array $options = [],
): self {
return (new XYZ())
->setColorspace($colorspace)
->setWhitepoint($whitepoint)
->setFromArray($colors);
return new XYZ($colors, $colorspace, $options);
}
/**
* parse options
*
* @param array<string,bool> $options
* @return self
*/
private function parseOptions(array $options): self
{
$this->setWhitepoint($options['whitepoint'] ?? '');
return $this;
}
/**
@@ -72,7 +96,7 @@ class XYZ
* @param float $value
* @return void
*/
public function __set(string $name, float $value): void
private function set(string $name, float $value): void
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -90,7 +114,7 @@ class XYZ
* @param string $name
* @return float
*/
public function __get(string $name): float
public function __get(string $name): float|string|bool
{
if (!property_exists($this, $name)) {
throw new \ErrorException('Creation of dynamic property is not allowed', 0);
@@ -150,13 +174,25 @@ class XYZ
* @param array{0:float,1:float,2:float} $colors
* @return self
*/
public function setFromArray(array $colors): self
private function setFromArray(array $colors): self
{
$this->__set('X', $colors[0]);
$this->__set('Y', $colors[1]);
$this->__set('Z', $colors[2]);
$this->set('X', $colors[0]);
$this->set('Y', $colors[1]);
$this->set('Z', $colors[2]);
return $this;
}
/**
* no hsb in css
*
* @param float|string|null $opacity
* @return string
* @throws \ErrorException
*/
public function toCssString(null|float|string $opacity = null): string
{
throw new \ErrorException('XYZ is not available as CSS color string', 0);
}
}
// __END__

View File

@@ -40,7 +40,7 @@ class Colors
int $blue,
bool $hex_prefix = true
): string {
return Coordinates\RGB::__constructFromArray([$red, $green, $blue])->returnAsHex($hex_prefix);
return (new Coordinates\RGB([$red, $green, $blue]))->returnAsHex($hex_prefix);
}
/**
@@ -61,7 +61,7 @@ class Colors
): string|array {
$rgbArray = [];
// rewrite to previous r/g/b key output
foreach (Coordinates\RGB::__constructFromHexString($hex_string)->returnAsArray() as $p => $el) {
foreach ((new Coordinates\RGB($hex_string))->returnAsArray() as $p => $el) {
switch ($p) {
case 0:
$k = 'r';
@@ -96,7 +96,7 @@ class Colors
return array_map(
fn ($v) => (int)round($v),
Color::rgbToHsb(
Coordinates\RGB::__constructFromArray([$red, $green, $blue])
new Coordinates\RGB([$red, $green, $blue])
)->returnAsArray()
);
}
@@ -117,7 +117,7 @@ class Colors
return array_map(
fn ($v) => (int)round($v),
Color::hsbToRgb(
Coordinates\HSB::__constructFromArray([$H, $S, $V])
new Coordinates\HSB([$H, $S, $V])
)->returnAsArray()
);
}
@@ -138,7 +138,7 @@ class Colors
return array_map(
fn ($v) => round($v, 1),
Color::rgbToHsl(
Coordinates\RGB::__constructFromArray([$red, $green, $blue])
new Coordinates\RGB([$red, $green, $blue])
)->returnAsArray()
);
}
@@ -158,7 +158,7 @@ class Colors
return array_map(
fn ($v) => round($v),
Color::hslToRgb(
Coordinates\HSL::__constructFromArray([$hue, $sat, $lum])
new Coordinates\HSL([$hue, $sat, $lum])
)->returnAsArray()
);
}