chroma 0.0.1.alpha.3 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -0
- data/CHANGELOG.md +17 -0
- data/README.md +318 -31
- data/lib/chroma/color/modifiers.rb +4 -4
- data/lib/chroma/harmonies.rb +19 -19
- data/lib/chroma/rgb_generator/from_string.rb +2 -0
- data/lib/chroma/version.rb +1 -1
- data/spec/chroma_spec.rb +25 -0
- data/spec/color/attributes_spec.rb +49 -0
- data/spec/color/modifiers_spec.rb +81 -3
- data/spec/color/palette_spec.rb +12 -12
- data/spec/custom_matchers.rb +8 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50d3030c7ac81f4ced369d991d94ae827af946c3
|
4
|
+
data.tar.gz: 20fba6d256719e631c6f0333aeb32afcf13c0fc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95b1f6fa55a3f8fc40c35a069c94c45a47a1bf6a889382971285bc4bb052331133f45b5f5e253d1a3f69340f928b1ae2026d959ed887d07feea44759c5382257
|
7
|
+
data.tar.gz: 085c7c08e31045167d3e57832f1f518f5ad6a8309881be5bceaf1a747a402d6831d426cdeec2551825207cbbebdc045a3029a30c1671fffea28dd261d6489666
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
### v0.0.1 - 2015-01-14
|
2
|
+
|
3
|
+
**Method Changes:**
|
4
|
+
|
5
|
+
* Renamed options for analogous palette method.
|
6
|
+
* `:results` -> `:size`
|
7
|
+
* `:slices` -> `:slice_by`
|
8
|
+
* Renamed option for monochromatic palette method.
|
9
|
+
* `:results` -> `:size`
|
10
|
+
|
11
|
+
**Miscellaneous Changes:**
|
12
|
+
|
13
|
+
* Add remaining specs for public API.
|
14
|
+
* Add "transparent" as color name for `Chroma.paint`.
|
15
|
+
* Minor API doc example fixes.
|
16
|
+
* Add public API usage examples to README.
|
17
|
+
|
1
18
|
### [v0.0.1.alpha.3] - 2015-01-13
|
2
19
|
|
3
20
|
**Bug Fixes:**
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Chroma
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/chroma.svg)](http://badge.fury.io/rb/chroma)
|
4
|
+
[![Build Status](https://travis-ci.org/jfairbank/chroma.svg?branch=master)](https://travis-ci.org/jfairbank/chroma)
|
4
5
|
|
5
6
|
Chroma is a color manipulation and palette generation library. It is heavily
|
6
7
|
inspired by and a very close Ruby port of the
|
@@ -8,22 +9,16 @@ inspired by and a very close Ruby port of the
|
|
8
9
|
library. Many thanks to [Brian Grinstead](http://www.briangrinstead.com/blog/)
|
9
10
|
for his hard work on that library.
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
before a first release. Because this is currently in alpha, please be
|
15
|
-
prepared for possible API changes or bugs.
|
16
|
-
|
17
|
-
Please don't hesitate to examine the code and make issues or pull requests
|
18
|
-
where you feel it is necessary. Please refer to the
|
19
|
-
[Contributing](#contributing) section below.
|
12
|
+
Please don't hesitate to examine the code and make issues, feature requests,
|
13
|
+
or pull requests. Please refer to the [Contributing](#contributing) section
|
14
|
+
below.
|
20
15
|
|
21
16
|
## Installation
|
22
17
|
|
23
18
|
Add this line to your application's Gemfile:
|
24
19
|
|
25
20
|
```ruby
|
26
|
-
gem 'chroma'
|
21
|
+
gem 'chroma'
|
27
22
|
```
|
28
23
|
|
29
24
|
And then execute:
|
@@ -32,37 +27,329 @@ And then execute:
|
|
32
27
|
|
33
28
|
Or install it yourself as:
|
34
29
|
|
35
|
-
$ gem install chroma
|
30
|
+
$ gem install chroma
|
31
|
+
|
32
|
+
## Creating Colors
|
36
33
|
|
37
|
-
|
34
|
+
Colors are created via the `Chroma.paint` method. It expects any one of
|
35
|
+
many possible color formats as a string, including names, hexadecimal, rgb,
|
36
|
+
hsl, and hsv. As a convenience, a `String#paint` is also available for more
|
37
|
+
succinct color creation.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# With Chroma.paint
|
41
|
+
Chroma.paint 'red' # named colors
|
42
|
+
Chroma.paint '#00ff00' # 6 character hexadecimal
|
43
|
+
Chroma.paint '#00f' # 3 character hexadecimal
|
44
|
+
Chroma.paint 'rgb(255, 255, 0)' # rgb
|
45
|
+
Chroma.paint 'rgba(255, 255, 0, 0.5)' # rgba
|
46
|
+
Chroma.paint 'hsl(60, 100%, 50%)' # hsl with percentages
|
47
|
+
Chroma.paint 'hsl(60, 1, 0.5)' # hsl with decimals
|
48
|
+
Chroma.paint 'hsla(60, 100%, 50%, 0.5)' # hsla
|
49
|
+
Chroma.paint 'hsv(60, 100%, 50%)' # hsv with percentages
|
50
|
+
Chroma.paint 'hsv(60, 1, 0.5)' # hsv with decimals
|
51
|
+
Chroma.paint 'hsva(60, 100%, 50%, 0.75)' # hsva
|
38
52
|
|
39
|
-
|
40
|
-
|
41
|
-
|
53
|
+
# With String#paint
|
54
|
+
'red'.paint
|
55
|
+
'#00ff00'.paint
|
56
|
+
'#00f'.paint
|
57
|
+
'rgb(255, 255, 0)'.paint
|
58
|
+
'rgba(255, 255, 0, 0.5)'.paint
|
59
|
+
'hsl(60, 100%, 50%)'.paint
|
60
|
+
'hsla(60, 100%, 50%, 0.5)'.paint
|
61
|
+
'hsv(60, 100%, 50%)'.paint
|
62
|
+
'hsva(60, 100%, 50%. 0.5)'.paint
|
63
|
+
```
|
42
64
|
|
43
|
-
|
44
|
-
|
65
|
+
## Motivation
|
66
|
+
|
67
|
+
Chroma's major strength is manipulating colors and generating color palettes,
|
68
|
+
which allows you to easily generate dynamic colors, dynamic themes for a web
|
69
|
+
application, and more.
|
70
|
+
|
71
|
+
## Color Manipulation
|
72
|
+
|
73
|
+
#### Lighten
|
74
|
+
|
75
|
+
Lighten the color by a given amount. Defaults to 10.
|
45
76
|
|
46
77
|
```ruby
|
47
|
-
|
48
|
-
|
49
|
-
Chroma.paint '#00f' # 3 character hexadecimal
|
50
|
-
Chroma.paint 'rgb(255, 255, 0)' # rgb
|
51
|
-
Chroma.paint 'rgba(255, 255, 0, 0.5)' # rgba
|
52
|
-
Chroma.paint 'hsl(60, 100%, 50%)' # hsl with percentages
|
53
|
-
Chroma.paint 'hsl(60, 1, 0.5)' # hsl with decimals
|
54
|
-
Chroma.paint 'hsv(60, 100%, 50%)' # hsv with percentages
|
55
|
-
Chroma.paint 'hsv(60, 1, 0.5)' # hsv with decimals
|
78
|
+
'red'.paint.lighten #=> #ff3333
|
79
|
+
'red'.paint.lighten(20) #=> #ff6666
|
56
80
|
```
|
57
81
|
|
58
|
-
|
82
|
+
#### Brighten
|
83
|
+
|
84
|
+
Brighten the color by a given amount. Defaults to 10.
|
59
85
|
|
60
86
|
```ruby
|
61
|
-
'red'.paint
|
62
|
-
'
|
63
|
-
|
87
|
+
'red'.paint.brighten #=> #ff1a1a
|
88
|
+
'red'.paint.brighten(20) #=> #ff3333
|
89
|
+
```
|
90
|
+
|
91
|
+
#### Darken
|
92
|
+
|
93
|
+
Darken the color by a given amount. Defaults to 10.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
'red'.paint.darken #=> #cc0000
|
97
|
+
'red'.paint.darken(20) #=> #990000
|
98
|
+
```
|
99
|
+
|
100
|
+
#### Desaturate
|
101
|
+
|
102
|
+
Desaturate the color by a given amount. Defaults to 10.
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
'red'.paint.desaturate #=> #f20d0d
|
106
|
+
'red'.paint.desaturate(20) #=> #e61919
|
107
|
+
```
|
108
|
+
|
109
|
+
#### Saturate
|
110
|
+
|
111
|
+
Saturate the color by a given amount. Defaults to 10.
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
'#123'.paint.saturate #=> #0e2236
|
115
|
+
'#123'.paint.saturate(20) #=> #0a223a
|
116
|
+
```
|
117
|
+
|
118
|
+
#### Grayscale
|
119
|
+
|
120
|
+
Convert the color to grayscale.
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
'green'.paint.grayscale #=> #404040
|
124
|
+
|
125
|
+
# greyscale is an alias
|
126
|
+
'red'.paint.greyscale #=> #808080
|
127
|
+
```
|
128
|
+
|
129
|
+
#### Spin
|
130
|
+
|
131
|
+
Spin a given amount in degrees around the hue wheel.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
'red'.paint.spin(30) #=> #ff8000
|
135
|
+
'red'.paint.spin(60) #=> yellow
|
136
|
+
'red'.paint.spin(90) #=> #80ff00
|
137
|
+
```
|
138
|
+
|
139
|
+
## Generating Palettes
|
140
|
+
|
141
|
+
Chroma's most powerful feature is palette generation. You can use the default
|
142
|
+
palettes available or even create your own custom palettes.
|
143
|
+
|
144
|
+
Palette methods are available via `Color#palette` and by default output an
|
145
|
+
array of colors. If you want the underlying color strings, you can pass in
|
146
|
+
the desired format via the `:as` option.
|
147
|
+
|
148
|
+
#### Available Formats
|
149
|
+
|
150
|
+
* name
|
151
|
+
* rgb
|
152
|
+
* hex
|
153
|
+
* hex6 (alias for hex)
|
154
|
+
* hex3
|
155
|
+
* hex8 (includes the alpha value in the highest order byte)
|
156
|
+
* hsl
|
157
|
+
* hsv
|
158
|
+
|
159
|
+
#### Complement
|
160
|
+
|
161
|
+
Generate a complement palette.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
'red'.paint.palette.complement #=> [red, cyan]
|
165
|
+
'red'.paint.palette.complement(as: :name) #=> ['red', 'cyan']
|
166
|
+
'red'.paint.palette.complement(as: :hex) #=> ['#ff0000', '#00ffff']
|
167
|
+
```
|
168
|
+
|
169
|
+
#### Triad
|
170
|
+
|
171
|
+
Generate a triad palette.
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
'red'.paint.palette.triad #=> [red, lime, blue]
|
175
|
+
'red'.paint.palette.triad(as: :name) #=> ['red', 'lime', 'blue']
|
176
|
+
'red'.paint.palette.triad(as: :hex) #=> ['#ff0000', '#00ff00', '#0000ff']
|
177
|
+
```
|
178
|
+
|
179
|
+
#### Tetrad
|
180
|
+
|
181
|
+
Generate a tetrad palette.
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
'red'.paint.palette.tetrad
|
185
|
+
#=> [red, #80ff00, cyan, #7f00ff]
|
186
|
+
|
187
|
+
'red'.paint.palette.tetrad(as: :name)
|
188
|
+
#=> ['red', '#80ff00', 'cyan', '#7f00ff']
|
189
|
+
|
190
|
+
'red'.paint.palette.tetrad(as: :hex)
|
191
|
+
#=> ['#ff0000', '#80ff00', '#00ffff', '#7f00ff']
|
192
|
+
```
|
193
|
+
|
194
|
+
#### Split Complement
|
195
|
+
|
196
|
+
Generate a split complement palette.
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
'red'.paint.palette.split_complement
|
200
|
+
#=> [red, #ccff00, #0066ff]
|
201
|
+
|
202
|
+
'red'.paint.palette.split_complement(as: :name)
|
203
|
+
#=> ['red', '#ccff00', '#0066ff']
|
204
|
+
|
205
|
+
'red'.paint.palette.split_complement(as: :hex)
|
206
|
+
#=> ['#ff0000', '#ccff00', '#0066ff']
|
207
|
+
```
|
208
|
+
|
209
|
+
#### Analogous
|
210
|
+
|
211
|
+
Generate an analogous palette. Pass in a `:size` option to specify the size
|
212
|
+
of the palette (defaults to 6). Pass in a `:slice_by` option to specify the
|
213
|
+
angle size to slice into the hue wheel (defaults to 30 degrees).
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
'red'.paint.palette.analogous
|
217
|
+
#=> [red, #ff0066, #ff0033, red, #ff3300, #ff6600]
|
218
|
+
|
219
|
+
'red'.paint.palette.analogous(as: :hex)
|
220
|
+
#=> ['#f00', '#f06', '#f03', '#f00', '#f30', '#f60']
|
221
|
+
|
222
|
+
'red'.paint.palette.analogous(size: 3)
|
223
|
+
#=> [red, #ff001a, #ff1a00]
|
224
|
+
|
225
|
+
'red'.paint.palette.analogous(size: 3, slice_by: 60)
|
226
|
+
#=> [red, #ff000d, #ff0d00]
|
227
|
+
```
|
228
|
+
|
229
|
+
#### Monochromatic
|
230
|
+
|
231
|
+
Generate a monochromatic palette. Pass in a `:size` option to specify the size
|
232
|
+
of the palette (defaults to 6).
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
'red'.paint.palette.monochromatic
|
236
|
+
#=> [red, #2a0000, #550000, maroon, #aa0000, #d40000]
|
237
|
+
|
238
|
+
'red'.paint.palette.monochromatic(as: :hex)
|
239
|
+
#=> ['#ff0000', '#2a0000', '#550000', '#800000', '#aa0000', '#d40000']
|
240
|
+
|
241
|
+
'red'.paint.palette.monochromatic(size: 3)
|
242
|
+
#=> [red, #550000, #aa0000]
|
243
|
+
```
|
244
|
+
|
245
|
+
## Defining Custom Palettes
|
246
|
+
|
247
|
+
Chroma allows you to define your own custom palettes if the default ones aren't
|
248
|
+
all you're looking for. You can define a custom palette by calling
|
249
|
+
`Chroma.define_palette`, passing in a palette name and definition block. The
|
250
|
+
definition block uses the color manipulation methods (i.e. `lighten`, `spin`,
|
251
|
+
etc.) as its DSL. Every DSL call defines a new color that will be included
|
252
|
+
in the palette. Your seed color (i.e. the color from which you call the
|
253
|
+
palette method) will be included as the first color in your palette too.
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
red = 'red'.paint
|
257
|
+
|
258
|
+
red.palette.respond_to? :my_palette #=> false
|
259
|
+
|
260
|
+
# Define a palette with 5 colors including the seed color
|
261
|
+
Chroma.define_palette :my_palette do
|
262
|
+
spin 60
|
263
|
+
spin 180
|
264
|
+
spin(60).brighten(20) # chain calls as well
|
265
|
+
greyscale
|
266
|
+
end
|
267
|
+
|
268
|
+
red.palette.respond_to? :my_palette #=> true
|
269
|
+
|
270
|
+
red.palette.my_palette #=> [#ff0000 #ffff00 #00ffff #ffff33 #808080]
|
271
|
+
```
|
272
|
+
|
273
|
+
## Serializing Colors
|
274
|
+
|
275
|
+
Colors offer several methods to output to different string color [formats](#available-formats).
|
276
|
+
|
277
|
+
| Method | Description |
|
278
|
+
| --------- | ---------------------------------------------------------------------------------------------------------------- |
|
279
|
+
| `to_hsv` | output to hsv string, outputs hsva if alpha < 1 |
|
280
|
+
| `to_hsl` | output to hsl string, outputs hsla if alpha < 1 |
|
281
|
+
| `to_hex` | output to hex string, optional argument allows 3-character hex output if possible |
|
282
|
+
| `to_hex8` | output to 8-character hex string with alpha value in the highest order byte |
|
283
|
+
| `to_rgb` | output to rgb string, outputs rgba if alpha < 1 |
|
284
|
+
| `to_name` | output to color name string if available, otherwise `'<unknown>'` or `to_hex` output based on optional arg value |
|
285
|
+
| `to_s` | output to the appropriate string format based on how the color was created, optional arg forces the format |
|
286
|
+
|
287
|
+
```ruby
|
288
|
+
# to_hsv
|
289
|
+
'red'.paint.to_hsv #=> 'hsv(0, 100%, 100%)'
|
290
|
+
'rgba(255, 0, 0, 0.5)'.paint.to_hsv #=> 'hsva(0, 100%, 100%, 0.5)'
|
291
|
+
|
292
|
+
# to_hsl
|
293
|
+
'red'.paint.to_hsl #=> 'hsl(0, 100%, 50%)'
|
294
|
+
'rgba(255, 0, 0, 0.5)'.paint.to_hsl #=> 'hsla(0, 100%, 50%, 0.5)'
|
295
|
+
|
296
|
+
# to_hex
|
297
|
+
'red'.paint.to_hex #=> '#ff0000'
|
298
|
+
'red'.paint.to_hex(true) #=> '#f00'
|
299
|
+
'rgba(255, 0, 0, 0.5)'.paint.to_hex #=> '#ff0000'
|
300
|
+
'red'.paint.to_hex #=> '#ffff0000'
|
301
|
+
'rgba(255, 0, 0, 0.5)'.paint.to_hex #=> '#80ff0000'
|
302
|
+
|
303
|
+
# to_rgb
|
304
|
+
'red'.paint.to_rgb #=> 'rgb(255, 0, 0)'
|
305
|
+
'rgba(255, 0, 0, 0.5)'.paint.to_rgb #=> 'rgb(255, 0, 0, 0.5)'
|
306
|
+
|
307
|
+
# to_name
|
308
|
+
'red'.paint.to_name #=> 'red'
|
309
|
+
'#00f'.paint.to_name #=> 'blue'
|
310
|
+
'rgba(255, 0, 0, 0.5)'.paint.to_name #=> '<unknown>'
|
311
|
+
'#123'.paint.to_name(true) #=> '#112233'
|
312
|
+
|
313
|
+
# to_s
|
314
|
+
'red'.paint.to_s #=> 'red'
|
315
|
+
'rgb(255, 0, 0)'.paint.to_s #=> 'rgb(255, 0, 0)'
|
316
|
+
'#f00'.paint.to_s #=> '#f00'
|
317
|
+
'#80ff0000'.paint.to_s(:rgb) #=> 'rgba(255, 0, 0, 0.5)'
|
318
|
+
```
|
319
|
+
|
320
|
+
## Other Methods
|
321
|
+
|
322
|
+
Colors also have a few other helper methods:
|
323
|
+
|
324
|
+
| Method | Description |
|
325
|
+
| ------------ | ------------------------------------------------------ |
|
326
|
+
| `dark?` | is the color dark? |
|
327
|
+
| `light?` | is the color light? |
|
328
|
+
| `alpha` | retrieve the alpha value |
|
329
|
+
| `brightness` | calculate the brightness as a number between 0 and 255 |
|
330
|
+
| `complement` | return the complementary color |
|
331
|
+
|
332
|
+
```ruby
|
333
|
+
# dark?
|
334
|
+
'red'.paint.dark? #=> true
|
335
|
+
'yellow'.paint.dark? #=> false
|
336
|
+
|
337
|
+
# light?
|
338
|
+
'red'.paint.light? #=> false
|
339
|
+
'yellow'.paint.light? #=> true
|
340
|
+
|
341
|
+
# alpha
|
342
|
+
'red'.paint.alpha #=> 1.0
|
343
|
+
'rgba(0, 0, 0, 0.5)'.paint.alpha #=> 0.5
|
344
|
+
|
345
|
+
# brightness
|
346
|
+
'red'.paint.brightness #=> 76.245
|
347
|
+
'yellow'.paint.brightness #=> 225.93
|
348
|
+
'white'.paint.brightness #=> 255.0
|
349
|
+
'black'.paint.brightness #=> 0.0
|
64
350
|
|
65
|
-
#
|
351
|
+
# complement
|
352
|
+
'red'.paint.complement #=> cyan
|
66
353
|
```
|
67
354
|
|
68
355
|
## Contributing
|
@@ -19,14 +19,14 @@ module Chroma
|
|
19
19
|
# Brightens the color by the given `amount`.
|
20
20
|
#
|
21
21
|
# @example
|
22
|
-
# 'red'.paint.brighten #=> #
|
22
|
+
# 'red'.paint.brighten #=> #ff1a1a
|
23
23
|
# 'red'.paint.brighten(20) #=> #ff3333
|
24
24
|
#
|
25
25
|
# @param amount [Fixnum]
|
26
26
|
# @return [Color]
|
27
27
|
def brighten(amount = 10)
|
28
28
|
# Don't include alpha
|
29
|
-
rgb = @rgb.to_a[0..2]
|
29
|
+
rgb = @rgb.to_a[0..2]
|
30
30
|
amount = (255 * (-amount / 100.0)).round
|
31
31
|
|
32
32
|
rgb.map! do |n|
|
@@ -81,7 +81,7 @@ module Chroma
|
|
81
81
|
# Converts the color to grayscale.
|
82
82
|
#
|
83
83
|
# @example
|
84
|
-
# 'green'.paint.
|
84
|
+
# 'green'.paint.grayscale #=> #404040
|
85
85
|
#
|
86
86
|
# @return [Color]
|
87
87
|
def grayscale
|
@@ -93,7 +93,7 @@ module Chroma
|
|
93
93
|
# Spins around the hue color wheel by `amount` in degrees.
|
94
94
|
#
|
95
95
|
# @example
|
96
|
-
# 'red'.paint.spin(30) #=> #
|
96
|
+
# 'red'.paint.spin(30) #=> #ff8000
|
97
97
|
# 'red'.paint.spin(60) #=> yellow
|
98
98
|
# 'red'.paint.spin(90) #=> #80ff00
|
99
99
|
#
|
data/lib/chroma/harmonies.rb
CHANGED
@@ -65,26 +65,26 @@ module Chroma
|
|
65
65
|
# Generate an analogous palette.
|
66
66
|
#
|
67
67
|
# @example
|
68
|
-
# 'red'.paint.palette.analogous
|
69
|
-
# 'red'.paint.palette.analogous(as: :hex)
|
70
|
-
# 'red'.paint.palette.analogous(
|
71
|
-
# 'red'.paint.palette.analogous(
|
68
|
+
# 'red'.paint.palette.analogous #=> [red, #ff0066, #ff0033, red, #ff3300, #ff6600]
|
69
|
+
# 'red'.paint.palette.analogous(as: :hex) #=> ['#f00', '#f06', '#f03', '#f00', '#f30', '#f60']
|
70
|
+
# 'red'.paint.palette.analogous(size: 3) #=> [red, #ff001a, #ff1a00]
|
71
|
+
# 'red'.paint.palette.analogous(size: 3, slice_by: 60) #=> [red, #ff000d, #ff0d00]
|
72
72
|
#
|
73
73
|
# @param options [Hash]
|
74
|
-
# @option options :
|
75
|
-
# @option options :
|
74
|
+
# @option options :size [Symbol] (6) number of results to return
|
75
|
+
# @option options :slice_by [Symbol] (30)
|
76
76
|
# the angle in degrees to slice the hue circle per color
|
77
|
-
# @option options :as
|
77
|
+
# @option options :as [Symbol] (nil) optional format to output colors as strings
|
78
78
|
# @return [Array<Color>, Array<String>] depending on presence of `options[:as]`
|
79
79
|
def analogous(options = {})
|
80
|
-
|
81
|
-
slices = options[:
|
80
|
+
size = options[:size] || 6
|
81
|
+
slices = options[:slice_by] || 30
|
82
82
|
|
83
83
|
hsl = @color.hsl
|
84
84
|
part = 360 / slices
|
85
|
-
hsl.h = ((hsl.h - (part *
|
85
|
+
hsl.h = ((hsl.h - (part * size >> 1)) + 720) % 360
|
86
86
|
|
87
|
-
palette = (
|
87
|
+
palette = (size - 1).times.reduce([@color]) do |arr, n|
|
88
88
|
hsl.h = (hsl.h + part) % 360
|
89
89
|
arr << Color.new(hsl, @color.format)
|
90
90
|
end
|
@@ -95,21 +95,21 @@ module Chroma
|
|
95
95
|
# Generate a monochromatic palette.
|
96
96
|
#
|
97
97
|
# @example
|
98
|
-
# 'red'.paint.palette.monochromatic
|
99
|
-
# 'red'.paint.palette.monochromatic(as: :hex)
|
100
|
-
# 'red'.paint.palette.monochromatic(
|
98
|
+
# 'red'.paint.palette.monochromatic #=> [red, #2a0000, #550000, maroon, #aa0000, #d40000]
|
99
|
+
# 'red'.paint.palette.monochromatic(as: :hex) #=> ['#ff0000', '#2a0000', '#550000', '#800000', '#aa0000', '#d40000']
|
100
|
+
# 'red'.paint.palette.monochromatic(size: 3) #=> [red, #550000, #aa0000]
|
101
101
|
#
|
102
102
|
# @param options [Hash]
|
103
|
-
# @option options :
|
104
|
-
# @option options :as
|
103
|
+
# @option options :size [Symbol] (6) number of results to return
|
104
|
+
# @option options :as [Symbol] (nil) optional format to output colors as strings
|
105
105
|
# @return [Array<Color>, Array<String>] depending on presence of `options[:as]`
|
106
106
|
def monochromatic(options = {})
|
107
|
-
|
107
|
+
size = options[:size] || 6
|
108
108
|
|
109
109
|
h, s, v = @color.hsv
|
110
|
-
modification = 1.0 /
|
110
|
+
modification = 1.0 / size
|
111
111
|
|
112
|
-
palette =
|
112
|
+
palette = size.times.map do
|
113
113
|
Color.new(ColorModes::Hsv.new(h, s, v), @color.format).tap do
|
114
114
|
v = (v + modification) % 1
|
115
115
|
end
|
data/lib/chroma/version.rb
CHANGED
data/spec/chroma_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
describe Chroma do
|
2
|
+
describe '.hex_from_name' do
|
3
|
+
it 'returns the hex representation for a color name' do
|
4
|
+
Chroma.send(:named_colors_map).each do |name, hex|
|
5
|
+
expect(Chroma.hex_from_name(name)).to eq hex
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'returns nil for unknown colors names' do
|
10
|
+
expect(Chroma.hex_from_name('foo')).to be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.name_from_hex' do
|
15
|
+
it 'returns a color name for a hex representation' do
|
16
|
+
Chroma.send(:named_colors_map).each do |name, hex|
|
17
|
+
expect(Chroma.name_from_hex(hex)).to be
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns nil for hex values without a corresponding color name' do
|
22
|
+
expect(Chroma.name_from_hex('#123123')).to be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe Chroma::Color do
|
2
|
+
let(:red) { 'red'.paint }
|
3
|
+
let(:black) { 'black'.paint }
|
4
|
+
let(:white) { 'white'.paint }
|
5
|
+
let(:yellow) { 'yellow'.paint }
|
6
|
+
|
7
|
+
describe '#dark?' do
|
8
|
+
it 'returns true for dark colors' do
|
9
|
+
expect(red).to be_dark
|
10
|
+
expect(black).to be_dark
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns false for light colors' do
|
14
|
+
expect(white).to_not be_dark
|
15
|
+
expect(yellow).to_not be_dark
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#light?' do
|
20
|
+
it 'returns false for dark colors' do
|
21
|
+
expect(red).to_not be_light
|
22
|
+
expect(black).to_not be_light
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns true for light colors' do
|
26
|
+
expect(white).to be_light
|
27
|
+
expect(yellow).to be_light
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#alpha' do
|
32
|
+
it 'returns the correct alpha value' do
|
33
|
+
expect('rgba(255, 0, 0, 0.75)'.paint.alpha).to eq 0.75
|
34
|
+
expect('#80ff0000'.paint.alpha).to be_within(0.01).of(0.5)
|
35
|
+
expect('transparent'.paint.alpha).to eq 0
|
36
|
+
expect('hsla(0, 100%, 50%, 0'.paint.alpha).to eq 0
|
37
|
+
expect(red.alpha).to eq 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#brightness' do
|
42
|
+
it 'returns the correct brightness' do
|
43
|
+
expect(red.brightness).to eq 76.245
|
44
|
+
expect(black.brightness).to eq 0
|
45
|
+
expect(white.brightness).to eq 255
|
46
|
+
expect(yellow.brightness).to eq 225.93
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,9 +1,87 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe Chroma::Color do
|
2
|
+
let(:red) { 'red'.paint }
|
3
|
+
let(:yellow) { 'yellow'.paint }
|
4
|
+
|
5
|
+
describe '#lighten' do
|
6
|
+
context 'with default amount' do
|
7
|
+
it 'generates the correct color' do
|
8
|
+
expect(red.lighten).to eq '#ff3333'.paint
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'with supplied amount' do
|
13
|
+
it 'generates the correct color' do
|
14
|
+
expect(red.lighten(20)).to eq '#ff6666'.paint
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#brighten' do
|
20
|
+
context 'with default amount' do
|
21
|
+
it 'generates the correct color' do
|
22
|
+
expect(red.brighten).to eq '#ff1a1a'.paint
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with supplied amount' do
|
27
|
+
it 'generates the correct color' do
|
28
|
+
expect(red.brighten(20)).to eq '#ff3333'.paint
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#darken' do
|
34
|
+
context 'with default amount' do
|
35
|
+
it 'generates the correct color' do
|
36
|
+
expect(red.darken).to eq '#cc0000'.paint
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with supplied amount' do
|
41
|
+
it 'generates the correct color' do
|
42
|
+
expect(red.darken(20)).to eq '#990000'.paint
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#desaturate' do
|
48
|
+
context 'with default amount' do
|
49
|
+
it 'generates the correct color' do
|
50
|
+
expect(red.desaturate).to eq '#f20d0d'.paint
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with supplied amount' do
|
55
|
+
it 'generates the correct color' do
|
56
|
+
expect(red.desaturate(20)).to eq '#e61919'.paint
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#saturate' do
|
62
|
+
context 'with default amount' do
|
63
|
+
it 'generates the correct color' do
|
64
|
+
expect('#123'.paint.saturate).to eq '#0e2236'.paint
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'with supplied amount' do
|
69
|
+
it 'generates the correct color' do
|
70
|
+
expect('#123'.paint.saturate(20)).to eq '#0a223a'.paint
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#grayscale' do
|
76
|
+
it 'generates the correct color' do
|
77
|
+
expect(red.grayscale).to eq 'gray'.paint
|
78
|
+
expect('green'.paint.grayscale).to eq '#404040'.paint
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
4
82
|
describe '#spin' do
|
5
83
|
it 'generates the correct color' do
|
6
|
-
expect(
|
84
|
+
expect(red.spin(60)).to eq yellow
|
7
85
|
end
|
8
86
|
end
|
9
87
|
end
|
data/spec/color/palette_spec.rb
CHANGED
@@ -96,37 +96,37 @@ describe Chroma::Color, '#palette' do
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
context 'with `
|
99
|
+
context 'with `size` argument' do
|
100
100
|
it 'returns the analogous palette' do
|
101
|
-
expect(red.palette.analogous(
|
101
|
+
expect(red.palette.analogous(size: 3)).
|
102
102
|
to generate_palette %w(#f00 #ff001a #ff1a00)
|
103
103
|
end
|
104
104
|
|
105
105
|
it 'keeps the same format' do
|
106
|
-
expect(red.palette.analogous(
|
106
|
+
expect(red.palette.analogous(size: 3)).to all have_format :name
|
107
107
|
end
|
108
108
|
|
109
109
|
context 'with option :as' do
|
110
110
|
it 'outputs the palette as an array of the string format' do
|
111
|
-
expect(red.palette.analogous(
|
111
|
+
expect(red.palette.analogous(size: 3, as: :hex)).
|
112
112
|
to eq %w(#ff0000 #ff001a #ff1a00)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
context 'with `
|
117
|
+
context 'with `size` and `slice_by` arguments' do
|
118
118
|
it 'returns the analogous palette' do
|
119
|
-
expect(red.palette.analogous(
|
119
|
+
expect(red.palette.analogous(size: 3, slice_by: 10)).
|
120
120
|
to generate_palette %w(#f00 #ff004c #ff4d00)
|
121
121
|
end
|
122
122
|
|
123
123
|
it 'keeps the same format' do
|
124
|
-
expect(red.palette.analogous(
|
124
|
+
expect(red.palette.analogous(size: 3, slice_by: 10)).to all have_format :name
|
125
125
|
end
|
126
126
|
|
127
127
|
context 'with option :as' do
|
128
128
|
it 'outputs the palette as an array of the string format' do
|
129
|
-
expect(red.palette.analogous(
|
129
|
+
expect(red.palette.analogous(size: 3, slice_by: 10, as: :hex)).
|
130
130
|
to eq %w(#ff0000 #ff004c #ff4d00)
|
131
131
|
end
|
132
132
|
end
|
@@ -152,19 +152,19 @@ describe Chroma::Color, '#palette' do
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
-
context 'with `
|
155
|
+
context 'with `size` argument' do
|
156
156
|
it 'returns the monochromatic palette' do
|
157
|
-
expect(red.palette.monochromatic(
|
157
|
+
expect(red.palette.monochromatic(size: 3)).
|
158
158
|
to generate_palette %w(#f00 #500 #a00)
|
159
159
|
end
|
160
160
|
|
161
161
|
it 'keeps the same format' do
|
162
|
-
expect(red.palette.monochromatic(
|
162
|
+
expect(red.palette.monochromatic(size: 3)).to all have_format :name
|
163
163
|
end
|
164
164
|
|
165
165
|
context 'with option :as' do
|
166
166
|
it 'outputs the palette as an array of the string format' do
|
167
|
-
expect(red.palette.monochromatic(
|
167
|
+
expect(red.palette.monochromatic(size: 3, as: :hex)).
|
168
168
|
to eq %w(#ff0000 #550000 #aa0000)
|
169
169
|
end
|
170
170
|
end
|
data/spec/custom_matchers.rb
CHANGED
@@ -11,3 +11,11 @@ RSpec::Matchers.define :have_format do |expected|
|
|
11
11
|
actual.format == expected
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
RSpec::Matchers.define :be_dark do
|
16
|
+
match { |value| value.dark? }
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec::Matchers.define :be_light do
|
20
|
+
match { |value| value.light? }
|
21
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chroma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Fairbank
|
@@ -61,6 +61,7 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- ".gitignore"
|
63
63
|
- ".rspec"
|
64
|
+
- ".travis.yml"
|
64
65
|
- ".yardopts"
|
65
66
|
- CHANGELOG.md
|
66
67
|
- Gemfile
|
@@ -97,6 +98,8 @@ files:
|
|
97
98
|
- lib/support/named_colors.yml
|
98
99
|
- spec/chroma/define_palette_spec.rb
|
99
100
|
- spec/chroma/paint_spec.rb
|
101
|
+
- spec/chroma_spec.rb
|
102
|
+
- spec/color/attributes_spec.rb
|
100
103
|
- spec/color/modifiers_spec.rb
|
101
104
|
- spec/color/palette_spec.rb
|
102
105
|
- spec/color/serializers_spec.rb
|
@@ -118,9 +121,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
121
|
version: '0'
|
119
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
123
|
requirements:
|
121
|
-
- - "
|
124
|
+
- - ">="
|
122
125
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
126
|
+
version: '0'
|
124
127
|
requirements: []
|
125
128
|
rubyforge_project:
|
126
129
|
rubygems_version: 2.4.5
|
@@ -130,6 +133,8 @@ summary: Color manipulation and palette generation.
|
|
130
133
|
test_files:
|
131
134
|
- spec/chroma/define_palette_spec.rb
|
132
135
|
- spec/chroma/paint_spec.rb
|
136
|
+
- spec/chroma_spec.rb
|
137
|
+
- spec/color/attributes_spec.rb
|
133
138
|
- spec/color/modifiers_spec.rb
|
134
139
|
- spec/color/palette_spec.rb
|
135
140
|
- spec/color/serializers_spec.rb
|