1<?php
2
3namespace LesserPHP\Functions;
4
5use Exception;
6use LesserPHP\Utils\Asserts;
7use LesserPHP\Utils\Color;
8
9/**
10 * Implementation of the Color Channel functions for LESS
11 *
12 * @link https://lesscss.org/functions/#color-channels
13 */
14class ColorChannels extends AbstractFunctionCollection
15{
16    /** @inheritdoc */
17    public function getFunctions(): array
18    {
19        return [
20            'hue' => [$this, 'hue'],
21            'saturation' => [$this, 'saturation'],
22            'lightness' => [$this, 'lightness'],
23            //'hsvhue' => [$this, 'hsvhue'],
24            //'hsvsaturation' => [$this, 'hsvsaturation'],
25            //'hsvvalue' => [$this, 'hsvvalue'],
26            'red' => [$this, 'red'],
27            'green' => [$this, 'green'],
28            'blue' => [$this, 'blue'],
29            'alpha' => [$this, 'alpha'],
30            'luma' => [$this, 'luma'],
31            //'luminance' => [$this, 'luminance'],
32        ];
33    }
34
35    /**
36     * Extracts the hue channel of a color object in the HSL color space
37     *
38     * @link https://lesscss.org/functions/#color-channel-hue
39     * @throws Exception
40     */
41    public function hue(array $color): int
42    {
43        $hsl = Color::toHSL(Asserts::assertColor($color));
44        return round($hsl[1]);
45    }
46
47    /**
48     * Extracts the saturation channel of a color object in the HSL color space
49     *
50     * @link https://lesscss.org/functions/#color-channel-saturation
51     * @throws Exception
52     */
53    public function saturation(array $color): int
54    {
55        $hsl = Color::toHSL(Asserts::assertColor($color));
56        return round($hsl[2]);
57    }
58
59    /**
60     * Extracts the lightness channel of a color object in the HSL color space
61     *
62     * @link https://lesscss.org/functions/#color-channel-lightness
63     * @throws Exception
64     */
65    public function lightness(array $color): int
66    {
67        $hsl = Color::toHSL(Asserts::assertColor($color));
68        return round($hsl[3]);
69    }
70
71    // hsvhue is missing
72
73    // hsvsaturation is missing
74
75    // hsvvalue is missing
76
77    /**
78     * @throws Exception
79     */
80    public function red($color)
81    {
82        $color = Asserts::assertColor($color);
83        return $color[1];
84    }
85
86    /**
87     * @throws Exception
88     */
89    public function green($color)
90    {
91        $color = Asserts::assertColor($color);
92        return $color[2];
93    }
94
95    /**
96     * @throws Exception
97     */
98    public function blue($color)
99    {
100        $color = Asserts::assertColor($color);
101        return $color[3];
102    }
103
104    /**
105     * Extracts the alpha channel of a color object
106     *
107     * defaults to 1 for colors without an alpha
108     * @fixme non-colors return null - should they?
109     * @link https://lesscss.org/functions/#color-channel-alpha
110     */
111    public function alpha(array $value): ?float
112    {
113        if (!is_null($color = Color::coerceColor($value))) {
114            return $color[4] ?? 1;
115        }
116        return null;
117    }
118
119    /**
120     * Calculates the luma (perceptual brightness) of a color object
121     *
122     * @link https://lesscss.org/functions/#color-channel-luma
123     * @throws Exception
124     */
125    public function luma(array $color): array
126    {
127        $color = Asserts::assertColor($color);
128        return ['number', round(Color::toLuma($color) * 100, 8), '%'];
129    }
130
131    // luminance is missing
132}
133