Completed
Push — master ( 0a5492...eb6f0f )
by Nicholas
05:51
created

scheme::tetrad()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 10
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 10
loc 10
ccs 0
cts 7
cp 0
rs 9.4285
cc 1
eloc 8
nc 1
nop 4
crap 2
1
<?php
2
3
4
namespace projectcleverweb\color;
5
6
/**
7
 * Scheme Class
8
 * 
9
 * This class has all the predefined HSL scheme algorithms.
10
 */
11
class scheme {
12
	
13
	/**
14
	 * These colors are all close to each other on a color wheel.
15
	 * 
16
	 * @param  float|integer $h       The base color hue degree (0 - 359)
17
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
18
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
19
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
20
	 * @return array                  An array of 5 analogous colors where the first offset is the original input.
21
	 */
22
	public static function analogous (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
23
		static::is_dark($is_dark, $h, $s, $l);
24
		// No inverting saturation
25
		$delta = FALSE;
26
		if ($s < 50) {
27
			$delta = TRUE;
28
		}
29
		return [
30
			[$h, $s, $l],
31
			[static::mod($h, -36, TRUE, 360), $s, $l],
32
			[static::mod($h, -18, TRUE, 360), static::mod($s, 6, $delta), static::mod($l, 6, $is_dark)],
33
			[static::mod($h, 18, TRUE, 360), static::mod($s, 6, $delta), static::mod($l, 6, $is_dark)],
34
			[static::mod($h, 36, TRUE, 360), $s, $l]
35
		];
36
	}
37
	
38
	/**
39
	 * 2 of these colors are a different shade of the base color. The other 2 are
40
	 * a weighted opposite of the base color.
41
	 * 
42
	 * @param  float|integer $h       The base color hue degree (0 - 359)
43
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
44
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
45
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
46
	 * @return array                  An array of 5 complementary colors where the first offset is the original input.
47
	 */
48 View Code Duplication
	public static function complementary (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
		static::is_dark($is_dark, $h, $s, $l);
50
		return [
51
			[$h, $s, $l],
52
			[$h, $s, static::mod($l, 20, $is_dark)],
53
			[$h, $s, static::mod($l, 10, $is_dark)],
54
			[static::mod($h, 185, TRUE, 360), $s, $l],
55
			[static::mod($h, 185, TRUE, 360), $s, static::mod($l, 10, $is_dark)]
56
		];
57
	}
58
	
59
	/**
60
	 * These colors use mathematical offsets that usually complement each other
61
	 * well, and can highlight the base color.
62
	 * 
63
	 * @param  float|integer $h       The base color hue degree (0 - 359)
64
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
65
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
66
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
67
	 * @return array                  An array of 5 compounding colors where the first offset is the original input.
68
	 */
69
	public static function compound (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
70
		static::is_dark($is_dark, $h, $s, $l);
71
		// No inverting saturation
72
		$delta = FALSE;
73
		if ($s < 50) {
74
			$delta = TRUE;
75
		}
76
		return [
77
			[$h, $s, $l],
78
			[static::mod($h, 40, TRUE, 360), static::mod($s, 12, $delta), static::mod($l, 24, $is_dark)],
79
			[static::mod($h, 40, TRUE, 360), static::mod($s, 12, $delta), static::mod($l, 16, $is_dark)],
80
			[static::mod($h, 135, TRUE, 360), static::mod($s, 12, $delta), static::mod($l, 16, $is_dark)],
81
			[static::mod($h, 160, TRUE, 360), static::mod($s, 12, $delta), static::mod($l, 24, $is_dark)]
82
		];
83
	}
84
	
85
	/**
86
	 * 5 complementary shades of one color.
87
	 * 
88
	 * @param  float|integer $h       The base color hue degree (0 - 359)
89
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
90
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
91
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
92
	 * @return array                  An array of 5 complementary shades of colors where the first offset is the original input.
93
	 */
94
	public static function monochromatic (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
95
		static::is_dark($is_dark, $h, $s, $l);
96
		// Avoid black & white
97
		$delta = 0;
98
		if ($l > 40 && $l < 60) {
99
			$delta = 30;
100
		}
101
		return [
102
			[$h, $s, $l],
103
			[$h, $s, static::mod($l, -8, $is_dark)],
104
			[$h, $s, static::mod($l, 8, $is_dark)],
105
			[$h, $s, static::mod($l, 55 + $delta, $is_dark)],
106
			[$h, $s, static::mod($l, 45 + $delta, $is_dark)]
107
		];
108
	}
109
	
110
	/**
111
	 * 5 different shades of one color.
112
	 * 
113
	 * @param  float|integer $h       The base color hue degree (0 - 359)
114
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
115
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
116
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
117
	 * @return array                  An array of 5 shades of a color where the first offset is the original input.
118
	 */
119
	public static function shades (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
120
		static::is_dark($is_dark, $h, $s, $l);
121
		// Avoid black & white
122
		$delta = 0;
123
		if ($l <= 10 && $l >= 90) {
124
			$delta = 50;
125
		}
126
		return [
127
			[$h, $s, $l],
128
			[$h, $s, max(min(static::mod($l, -20 - $delta, $is_dark), 97), 5)],
129
			[$h, $s, max(min(static::mod($l, -10 - $delta, $is_dark), 97), 5)],
130
			[$h, $s, max(min(static::mod($l, 8 + $delta, $is_dark), 97), 5)],
131
			[$h, $s, max(min(static::mod($l, 16 + $delta, $is_dark), 97), 5)]
132
		];
133
	}
134
	
135
	/**
136
	 * 3 of these colors are all equally distanced from each other on a color
137
	 * wheel, plus 1 alternated shade for the base color and the 1 color that is
138
	 * opposite of the base color.
139
	 * 
140
	 * @param  float|integer $h       The base color hue degree (0 - 359)
141
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
142
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
143
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
144
	 * @return array                  An array of 5 triangular colors where the first offset is the original input.
145
	 */
146 View Code Duplication
	public static function tetrad (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
		static::is_dark($is_dark, $h, $s, $l);
148
		return [
149
			[$h, $s, $l],
150
			[static::mod($h, 180, TRUE, 360), $s, $l],
151
			[static::mod($h, 120, TRUE, 360), $s, $l],
152
			[$h, $s, static::mod($l, 18, $is_dark)],
153
			[static::mod($h, -120, TRUE, 360), $s, $l]
154
		];
155
	}
156
	
157
	/**
158
	 * 3 of these colors are all similarly distanced from each other on a color
159
	 * wheel, the base color has an alternate shade, and there is a weighted
160
	 * opposite color. These colors are all slightly closer to the base color
161
	 * than in a normal tetrad.
162
	 * 
163
	 * @param  float|integer $h       The base color hue degree (0 - 359)
164
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
165
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
166
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
167
	 * @return array                  An array of 5 triangular colors where the first offset is the original input.
168
	 */
169 View Code Duplication
	public static function weighted_tetrad (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
170
		static::is_dark($is_dark, $h, $s, $l);
171
		return [
172
			[$h, $s, $l],
173
			[static::mod($h, 160, TRUE, 360), $s, $l],
174
			[static::mod($h, 80, TRUE, 360), $s, $l],
175
			[$h, $s, static::mod($l, 18, $is_dark)],
176
			[static::mod($h, -80, TRUE, 360), $s, $l]
177
		];
178
	}
179
	
180
	/**
181
	 * These colors are all equally distanced from each other on a color wheel,
182
	 * 2 of which have an alternate shade.
183
	 * 
184
	 * @param  float|integer $h       The base color hue degree (0 - 359)
185
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
186
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
187
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
188
	 * @return array                  An array of 5 triangular colors where the first offset is the original input.
189
	 */
190 View Code Duplication
	public static function triad (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
191
		static::is_dark($is_dark, $h, $s, $l);
192
		return [
193
			[$h, $s, $l],
194
			[static::mod($h, 120, TRUE, 360), $s, $l],
195
			[$h, $s, static::mod($l, 18, $is_dark)],
196
			[static::mod($h, -120, TRUE, 360), $s, $l],
197
			[static::mod($h, -120, TRUE, 360), $s, static::mod($l, 18, $is_dark)]
198
		];
199
	}
200
	
201
	/**
202
	 * These colors are all similarly distanced from each other on a color wheel,
203
	 * 2 of which have an alternate shade. These colors are all slightly closer to
204
	 * the base color than in a normal triad.
205
	 * 
206
	 * @param  float|integer $h       The base color hue degree (0 - 359)
207
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
208
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
209
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
210
	 * @return array                  An array of 5 weighted triangular colors where the first offset is the original input.
211
	 */
212 View Code Duplication
	public static function weighted_triad (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
213
		static::is_dark($is_dark, $h, $s, $l);
214
		return [
215
			[$h, $s, $l],
216
			[static::mod($h, 80, TRUE, 360), $s, $l],
217
			[$h, $s, static::mod($l, 18, $is_dark)],
218
			[static::mod($h, -80, TRUE, 360), $s, $l],
219
			[static::mod($h, -80, TRUE, 360), $s, static::mod($l, 18, $is_dark)]
220
		];
221
	}
222
	
223
	/**
224
	 * 3 of these colors are all equally distanced from each other on a color
225
	 * wheel, plus 1 alternated shade for the base color and the 1 color that is
226
	 * opposite of the base color.
227
	 * 
228
	 * @param  float|integer $h       The base color hue degree (0 - 359)
229
	 * @param  float|integer $s       The base color saturation percentage (0 - 100)
230
	 * @param  float|integer $l       The base color lighting percentage (0 - 100)
231
	 * @param  bool|null     $is_dark Whether or not to treat the base color as a dark color. Leave as null to dynamically generate this.
232
	 * @return array                  An array of 5 triangular colors where the first offset is the original input.
233
	 */
234
	public static function rectangular (float $h = 0, float $s = 0, float $l = 0, $is_dark = NULL) :array {
235
		static::is_dark($is_dark, $h, $s, $l);
236
		return [
237
			[$h, $s, $l],
238
			[static::mod($h, 270, TRUE, 360), $s, $l],
239
			[static::mod($h, 180, TRUE, 360), $s, $l],
240
			[$h, $s, static::mod($l, 18, $is_dark)],
241
			[static::mod($h, 90, TRUE, 360), $s, $l]
242
		];
243
	}
244
	
245
	/**
246
	 * This allows easy modification of a number while forcing it to fall into a valid range.
247
	 * 
248
	 * @param  float   $number     The number to modify
249
	 * @param  float   $adjustment The amount of change to make to the $number
250
	 * @param  boolean $add        TRUE to add $adjustment to $number, FALSE to subtract $adjustment from $number
251
	 * @param  integer $max        The maximum value to allow. (Minimum is assumed to be 0)
252
	 * @return float               The resulting number.
253
	 */
254
	protected static function mod(float $number, float $adjustment, $add = TRUE, $max = 100) :float {
255
		if ($add) {
256
			return abs($number + $max + $adjustment) % $max;
257
		}
258
		return abs($number + $max - $adjustment) % $max;
259
	}
260
	
261
	/**
262
	 * Check if an HSL color is dark (YIQ)
263
	 * 
264
	 * @param  float|integer $h The hue degree (0 - 359)
265
	 * @param  float|integer $s The saturation percentage (0 - 100)
266
	 * @param  float|integer $l The lighting percentage (0 - 100)
267
	 * @return boolean          TRUE if the color is dark, FALSE otherwise.
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
268
	 */
269
	protected static function is_dark(&$is_dark, float $h = 0, float $s = 0, float $l = 0) {
270
		if (is_null($is_dark)) {
271
			$rgb = generate::hsl_to_rgb($h, $s, $l);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
272
			$is_dark = check::is_dark($rgb['r'], $rgb['g'], $rgb['b']);
273
		}
274
	}
275
}
276