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:
@@ -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']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user