Test Failed
Push — master ( 9d3a5c...c5f273 )
by Sebastian
08:26
created

HSVColor::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 10
rs 10
cc 2
nc 2
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AppUtils;
6
7
use AppUtils\RGBAColor\ColorChannel;
8
use AppUtils\RGBAColor\ColorChannel\AlphaChannel;
9
use AppUtils\RGBAColor\ColorChannel\HueChannel;
10
use AppUtils\RGBAColor\ColorChannel\BrightnessChannel;
11
use AppUtils\RGBAColor\ColorChannel\SaturationChannel;
12
use AppUtils\RGBAColor\ColorFactory;
13
use AppUtils\RGBAColor\FormatsConverter;
14
use ArrayAccess;
15
16
/**
17
 * Handles color values based on Hue, Saturation and Brightness.
18
 *
19
 * NOTE: The array access implementation allows accessing the
20
 * color values, but since they are immutable, changing or
21
 * removing them is ignored.
22
 *
23
 * @package Application Utils
24
 * @subpackage RGBAColor
25
 * @author Sebastian Mordziol <[email protected]>
26
 *
27
 * @implements ArrayAccess<string,float> Only for accessing values - changing them is ignored.
28
 */
29
class HSVColor implements ArrayAccess
30
{
31
    private HueChannel $hue;
32
    private SaturationChannel $saturation;
33
    private BrightnessChannel $brightness;
34
    private ColorChannel $alpha;
35
36
    public function __construct(HueChannel $hue, SaturationChannel $saturation, BrightnessChannel $brightness, ?ColorChannel $alpha=null)
37
    {
38
        if($alpha === null) {
39
            $alpha = ColorChannel::alpha(0);
40
        }
41
42
        $this->hue = $hue;
43
        $this->saturation = $saturation;
44
        $this->brightness = $brightness;
45
        $this->alpha = $alpha;
46
    }
47
48
    public function getHue() : HueChannel
49
    {
50
        return $this->hue;
51
    }
52
53
    public function getBrightness() : BrightnessChannel
54
    {
55
        return $this->brightness;
56
    }
57
58
    public function getSaturation() : SaturationChannel
59
    {
60
        return $this->saturation;
61
    }
62
63
    public function getAlpha() : ColorChannel
64
    {
65
        return $this->alpha;
66
    }
67
68
    /**
69
     * Sets the color's brightness.
70
     *
71
     * @param int|float|BrightnessChannel $brightness 0-100
72
     * @return HSVColor (New instance)
73
     */
74
    public function setBrightness($brightness) : HSVColor
75
    {
76
        return new HSVColor(
77
            $this->getHue(),
78
            $this->getSaturation(),
79
            ColorChannel::brightness($brightness),
80
            $this->getAlpha()
81
        );
82
    }
83
84
    /**
85
     * Sets the color's hue.
86
     *
87
     * @param int|float|HueChannel $hue 0 to 360
88
     * @return HSVColor (New instance)
89
     */
90
    public function setHue($hue) : HSVColor
91
    {
92
        return new HSVColor(
93
            ColorChannel::hue($hue),
94
            $this->getSaturation(),
95
            $this->getBrightness(),
96
            $this->getAlpha()
97
        );
98
    }
99
100
    /**
101
     * Sets the color's saturation.
102
     *
103
     * @param int|float|SaturationChannel $saturation 0 to 100
104
     * @return HSVColor (New instance)
105
     */
106
    public function setSaturation($saturation) : HSVColor
107
    {
108
        return new HSVColor(
109
            $this->getHue(),
110
            ColorChannel::saturation($saturation),
111
            $this->getBrightness(),
112
            $this->getAlpha()
113
        );
114
    }
115
116
117
    /**
118
     * Sets the color's alpha channel.
119
     *
120
     * @param float|AlphaChannel $alpha 0.0 to 1.0
121
     * @return HSVColor (New instance)
122
     */
123
    public function setAlpha($alpha) : HSVColor
124
    {
125
        return new HSVColor(
126
            $this->getHue(),
127
            $this->getSaturation(),
128
            $this->getBrightness(),
129
            ColorChannel::alpha($alpha)
130
        );
131
    }
132
133
    // region: Conversion methods
134
135
    /**
136
     * Converts the color to an RGB value.
137
     *
138
     * @return RGBAColor
139
     */
140
    public function toRGB() : RGBAColor
141
    {
142
        $rgb = FormatsConverter::hsv2rgb(
143
            $this->getHue()->getValue(),
144
            $this->getSaturation()->getValue(),
145
            $this->getBrightness()->getValue()
146
        );
147
148
        return ColorFactory::create(
149
            ColorChannel::eightBit($rgb['red']),
150
            ColorChannel::eightBit($rgb['green']),
151
            ColorChannel::eightBit($rgb['blue']),
152
            $this->getAlpha()
153
        );
154
    }
155
156
    /**
157
     * @return array{hue:float,saturation:float,brightness:float,alpha:float}
158
     */
159
    public function toArray() : array
160
    {
161
        return array(
162
            'hue' => $this->getHue()->getValue(),
163
            'saturation' => $this->getSaturation()->getValue(),
164
            'brightness' => $this->getBrightness()->getValue(),
165
            'alpha' => $this->getAlpha()->getAlpha()
166
        );
167
    }
168
169
    // endregion
170
171
    // region: Operations
172
173
    /**
174
     * Adjusts the color's brightness by the specified percent,
175
     * based on the current value.
176
     *
177
     * NOTE: Keep in mind that increasing the brightness by 50%
178
     * on a very dark color will only increase it slightly (example:
179
     * 5% luminosity + 50% = 7.5%). In some cases, setting the
180
     * brightness directly will be more logical.
181
     *
182
     * Can be a negative value to reduce the brightness.
183
     *
184
     * @param float $percent -100 to 100
185
     * @return HSVColor (New instance)
186
     */
187
    public function adjustBrightness(float $percent) : HSVColor
188
    {
189
        $value = $this->getBrightness()->getValue();
190
        $value += $value * $percent / 100;
191
192
        return new HSVColor(
193
            $this->getHue(),
194
            $this->getSaturation(),
195
            ColorChannel::brightness($value),
196
            $this->getAlpha()
197
        );
198
    }
199
200
    // endregion
201
202
    // region: Array access
203
204
    /**
205
     * @param float $offset
206
     * @return bool
207
     */
208
    public function offsetExists($offset) : bool
209
    {
210
        $array = $this->toArray();
211
        return isset($array[$offset]);
212
    }
213
214
    /**
215
     * @param string $offset
216
     * @return float
217
     */
218
    public function offsetGet($offset) : float
219
    {
220
        $array = $this->toArray();
221
222
        return $array[$offset] ?? 0.0;
223
    }
224
225
    /**
226
     * @param string $offset
227
     * @param int|float $value
228
     * @return void
229
     */
230
    public function offsetSet($offset, $value) : void
231
    {
232
        // ignored.
233
    }
234
235
    /**
236
     * @param string $offset
237
     * @return void
238
     */
239
    public function offsetUnset($offset) : void
240
    {
241
        // ignored.
242
    }
243
244
    // endregion
245
}
246