kodachroma 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 98d99d23181a6e8fb5b66b9cc689fff97881ab9cc9bf2ae455da8b85c915f6bb
4
+ data.tar.gz: 05f09a107f88e5938173309b7a84d81b8930940419729cd152e97c11fb5b093f
5
+ SHA512:
6
+ metadata.gz: 88ab6243470b9a773de8b37f12b067863cdf7cc0aa48f47e85b69f928280ab9a2394709ae28286ffd9eeb6b262407c75c724faeca4ffb6cf27efc0aa2927f1d1
7
+ data.tar.gz: 4df903a5512b146f9da7f564db65b5f5d441bb891a664734701027a437eda3cd3b1efbaf8e86e2deb97805935e7c04c22ad49c59c7ab36ed20a2092473119fff
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2021 Jeremy Fairbank and Evan Lecklider
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the “Software”), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.org ADDED
@@ -0,0 +1,401 @@
1
+ * Kodachroma
2
+
3
+ [[https://badge.fury.io/rb/kodachroma][https://badge.fury.io/rb/kodachroma.svg]]
4
+
5
+ Kodachroma is a color manipulation and palette generation library. It aims to be
6
+ a maintained fork of the excellent [[https://github.com/jfairbank/chroma][Chroma]]. Many thanks to [[https://github.com/jfairbank][Jeremy Fairbank]] for
7
+ developing Chroma.
8
+
9
+ From Chroma's own [[https://github.com/jfairbank/chroma/blob/master/README.md][README]]:
10
+
11
+ #+begin_quote
12
+ It is heavily inspired by and a very close Ruby port of the [[https://bgrins.github.io/TinyColor/][tinycolor.js]]
13
+ library. Many thanks to [[http://www.briangrinstead.com/blog/][Brian Grinstead]] for his hard work on that library.
14
+ #+end_quote
15
+
16
+ ** Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ #+BEGIN_SRC ruby
21
+ gem 'kodachroma'
22
+ #+END_SRC
23
+
24
+ And then execute:
25
+
26
+ #+begin_src sh
27
+ bundle
28
+ #+end_src
29
+
30
+ Or install it yourself as:
31
+
32
+ #+begin_src sh
33
+ gem install kodachroma
34
+ #+end_src
35
+
36
+ ** Differences from Chroma
37
+
38
+ The string extension that defined =String#paint= has been removed. If you would
39
+ like to replicate that behavior using Kodachroma, the following should do the
40
+ trick.
41
+
42
+ #+begin_src ruby
43
+ class String
44
+ # Creates {Kodachroma::Color} directly from a string representing a color.
45
+ #
46
+ # @example
47
+ # 'red'.paint
48
+ # '#f00'.paint
49
+ # '#ff0000'.paint
50
+ # 'rgb(255, 0, 0)'.paint
51
+ # 'hsl(0, 100%, 50%)'.paint
52
+ # 'hsv(0, 100%, 100%)'.paint
53
+ #
54
+ # @return [Kodachroma::Color]
55
+ def paint
56
+ Kodachroma.paint(self)
57
+ end
58
+ end
59
+ #+end_src
60
+
61
+ ** Creating Colors
62
+
63
+ Colors are created via the =Kodachroma.paint= method. It expects any one of
64
+ many possible color formats as a string, including names, hexadecimal,
65
+ rgb, hsl, and hsv.
66
+
67
+ #+BEGIN_SRC ruby
68
+ Kodachroma.paint 'red' # named colors
69
+ Kodachroma.paint '#00ff00' # 6 character hexadecimal
70
+ Kodachroma.paint '#00f' # 3 character hexadecimal
71
+ Kodachroma.paint 'rgb(255, 255, 0)' # rgb
72
+ Kodachroma.paint 'rgba(255, 255, 0, 0.5)' # rgba
73
+ Kodachroma.paint 'hsl(60, 100%, 50%)' # hsl with percentages
74
+ Kodachroma.paint 'hsl(60, 1, 0.5)' # hsl with decimals
75
+ Kodachroma.paint 'hsla(60, 100%, 50%, 0.5)' # hsla
76
+ Kodachroma.paint 'hsv(60, 100%, 50%)' # hsv with percentages
77
+ Kodachroma.paint 'hsv(60, 1, 0.5)' # hsv with decimals
78
+ Kodachroma.paint 'hsva(60, 100%, 50%, 0.75)' # hsva
79
+ #+END_SRC
80
+
81
+ ** Motivation
82
+
83
+ Kodachroma's major strength is manipulating colors and generating color
84
+ palettes, which allows you to easily generate dynamic colors, dynamic
85
+ themes for a web application, and more.
86
+
87
+ ** Color manipulation
88
+
89
+ *** Lighten
90
+
91
+ Lighten the color by a given amount. Defaults to 10.
92
+
93
+ #+BEGIN_SRC ruby
94
+ Kodachroma.paint('red').lighten #=> #ff3333
95
+ Kodachroma.paint('red').lighten(20) #=> #ff6666
96
+ #+END_SRC
97
+
98
+ *** Brighten
99
+
100
+ Brighten the color by a given amount. Defaults to 10.
101
+
102
+ #+BEGIN_SRC ruby
103
+ Kodachroma.paint('red').brighten #=> #ff1a1a
104
+ Kodachroma.paint('red').brighten(20) #=> #ff3333
105
+ #+END_SRC
106
+
107
+ *** Darken
108
+
109
+ Darken the color by a given amount. Defaults to 10.
110
+
111
+ #+BEGIN_SRC ruby
112
+ Kodachroma.paint('red').darken #=> #cc0000
113
+ Kodachroma.paint('red').darken(20) #=> #990000
114
+ #+END_SRC
115
+
116
+ *** Desaturate
117
+
118
+ Desaturate the color by a given amount. Defaults to 10.
119
+
120
+ #+BEGIN_SRC ruby
121
+ Kodachroma.paint('red').desaturate #=> #f20d0d
122
+ Kodachroma.paint('red').desaturate(20) #=> #e61919
123
+ #+END_SRC
124
+
125
+ *** Saturate
126
+
127
+ Saturate the color by a given amount. Defaults to 10.
128
+
129
+ #+BEGIN_SRC ruby
130
+ Kodachroma.paint('#123').saturate #=> #0e2236
131
+ Kodachroma.paint('#123').saturate(20) #=> #0a223a
132
+ #+END_SRC
133
+
134
+ *** Grayscale
135
+
136
+ Convert the color to grayscale.
137
+
138
+ #+BEGIN_SRC ruby
139
+ Kodachroma.paint('green').grayscale #=> #404040
140
+
141
+ # greyscale is an alias
142
+ Kodachroma.paint('red').greyscale #=> #808080
143
+ #+END_SRC
144
+
145
+ *** Opacity
146
+
147
+ Set the opacity of the color to a given amount.
148
+
149
+ #+BEGIN_SRC ruby
150
+ Kodachroma.paint('red').opacity(0.3) #=> #ff0000
151
+ Kodachroma.paint('red').opacity(0.3).to_rgb #=> 'rgba(255, 0, 0, 0.3)'
152
+ #+END_SRC
153
+
154
+ *** Spin
155
+
156
+ Spin a given amount in degrees around the hue wheel.
157
+
158
+ #+BEGIN_SRC ruby
159
+ Kodachroma.paint('red').spin(30) #=> #ff8000
160
+ Kodachroma.paint('red').spin(60) #=> yellow
161
+ Kodachroma.paint('red').spin(90) #=> #80ff00
162
+ #+END_SRC
163
+
164
+ ** Generating palettes
165
+
166
+ Kodachroma's most powerful feature is palette generation. You can use the
167
+ default palettes available or even create your own custom palettes.
168
+
169
+ Palette methods are available via =Color#palette= and by default output
170
+ an array of colors. If you want the underlying color strings, you can
171
+ pass in the desired format via the =:as= option.
172
+
173
+ **** Available Formats
174
+
175
+ - name
176
+ - rgb
177
+ - hex
178
+ - hex6 (alias for hex)
179
+ - hex3
180
+ - hex8 (includes the alpha value in the highest order byte)
181
+ - hsl
182
+ - hsv
183
+
184
+ **** Complement
185
+
186
+ Generate a complement palette.
187
+
188
+ #+BEGIN_SRC ruby
189
+ Kodachroma.paint('red').palette.complement #=> [red, cyan]
190
+ Kodachroma.paint('red').palette.complement(as: :name) #=> ['red', 'cyan']
191
+ Kodachroma.paint('red').palette.complement(as: :hex) #=> ['#ff0000', '#00ffff']
192
+ #+END_SRC
193
+
194
+ **** Triad
195
+
196
+ Generate a triad palette.
197
+
198
+ #+BEGIN_SRC ruby
199
+ Kodachroma.paint('red').palette.triad #=> [red, lime, blue]
200
+ Kodachroma.paint('red').palette.triad(as: :name) #=> ['red', 'lime', 'blue']
201
+ Kodachroma.paint('red').palette.triad(as: :hex) #=> ['#ff0000', '#00ff00', '#0000ff']
202
+ #+END_SRC
203
+
204
+ **** Tetrad
205
+
206
+ Generate a tetrad palette.
207
+
208
+ #+BEGIN_SRC ruby
209
+ Kodachroma.paint('red').palette.tetrad
210
+ #=> [red, #80ff00, cyan, #7f00ff]
211
+
212
+ Kodachroma.paint('red').palette.tetrad(as: :name)
213
+ #=> ['red', '#80ff00', 'cyan', '#7f00ff']
214
+
215
+ Kodachroma.paint('red').palette.tetrad(as: :hex)
216
+ #=> ['#ff0000', '#80ff00', '#00ffff', '#7f00ff']
217
+ #+END_SRC
218
+
219
+ **** Split complement
220
+
221
+ Generate a split complement palette.
222
+
223
+ #+BEGIN_SRC ruby
224
+ Kodachroma.paint('red').palette.split_complement
225
+ #=> [red, #ccff00, #0066ff]
226
+
227
+ Kodachroma.paint('red').palette.split_complement(as: :name)
228
+ #=> ['red', '#ccff00', '#0066ff']
229
+
230
+ Kodachroma.paint('red').palette.split_complement(as: :hex)
231
+ #=> ['#ff0000', '#ccff00', '#0066ff']
232
+ #+END_SRC
233
+
234
+ **** Analogous
235
+
236
+ Generate an analogous palette. Pass in a =:size= option to specify the
237
+ size of the palette (defaults to 6). Pass in a =:slice_by= option to
238
+ specify the angle size to slice into the hue wheel (defaults to 30
239
+ degrees).
240
+
241
+ #+BEGIN_SRC ruby
242
+ Kodachroma.paint('red').palette.analogous
243
+ #=> [red, #ff0066, #ff0033, red, #ff3300, #ff6600]
244
+
245
+ Kodachroma.paint('red').palette.analogous(as: :hex)
246
+ #=> ['#f00', '#f06', '#f03', '#f00', '#f30', '#f60']
247
+
248
+ Kodachroma.paint('red').palette.analogous(size: 3)
249
+ #=> [red, #ff001a, #ff1a00]
250
+
251
+ Kodachroma.paint('red').palette.analogous(size: 3, slice_by: 60)
252
+ #=> [red, #ff000d, #ff0d00]
253
+ #+END_SRC
254
+
255
+ **** Monochromatic
256
+
257
+ Generate a monochromatic palette. Pass in a =:size= option to specify
258
+ the size of the palette (defaults to 6).
259
+
260
+ #+BEGIN_SRC ruby
261
+ Kodachroma.paint('red').palette.monochromatic
262
+ #=> [red, #2a0000, #550000, maroon, #aa0000, #d40000]
263
+
264
+ Kodachroma.paint('red').palette.monochromatic(as: :hex)
265
+ #=> ['#ff0000', '#2a0000', '#550000', '#800000', '#aa0000', '#d40000']
266
+
267
+ Kodachroma.paint('red').palette.monochromatic(size: 3)
268
+ #=> [red, #550000, #aa0000]
269
+ #+END_SRC
270
+
271
+ ** Defining custom palettes
272
+
273
+ Kodachroma allows you to define your own custom palettes if the default ones
274
+ aren't all you're looking for. You can define a custom palette by
275
+ calling =Kodachroma.define_palette=, passing in a palette name and
276
+ definition block. The definition block uses the color manipulation
277
+ methods (i.e. =lighten=, =spin=, etc.) as its DSL. Every DSL call
278
+ defines a new color that will be included in the palette. Your seed
279
+ color (i.e. the color from which you call the palette method) will be
280
+ included as the first color in your palette too.
281
+
282
+ #+BEGIN_SRC ruby
283
+ red = Kodachroma.paint('red')
284
+
285
+ red.palette.respond_to? :my_palette #=> false
286
+
287
+ # Define a palette with 5 colors including the seed color
288
+ Kodachroma.define_palette :my_palette do
289
+ spin 60
290
+ spin 180
291
+ spin(60).brighten(20) # chain calls as well
292
+ greyscale
293
+ end
294
+
295
+ red.palette.respond_to? :my_palette #=> true
296
+
297
+ red.palette.my_palette #=> [#ff0000 #ffff00 #00ffff #ffff33 #808080]
298
+ #+END_SRC
299
+
300
+ ** Dynamic custom palettes
301
+
302
+ You can generate custom palettes on the fly too with
303
+ =Kodachroma::Color#custom_palette=.
304
+
305
+ #+BEGIN_SRC ruby
306
+ Kodachroma.paint('red').custom_palette do
307
+ spin 60
308
+ spin 180
309
+ end
310
+
311
+ #=> [red, yellow, cyan]
312
+ #+END_SRC
313
+
314
+ ** Serializing colors
315
+
316
+ Colors offer several methods to output to different string color
317
+ [[#available-formats][formats]].
318
+
319
+ | Method | Description |
320
+ |-------------+--------------------------------------------------------------------------------------------------------------------|
321
+ | =to_hsv= | output to hsv string, outputs hsva if alpha < 1 |
322
+ | =to_hsl= | output to hsl string, outputs hsla if alpha < 1 |
323
+ | =to_hex= | output to hex string, optional argument allows 3-character hex output if possible |
324
+ | =to_hex8= | output to 8-character hex string with alpha value in the highest order byte |
325
+ | =to_rgb= | output to rgb string, outputs rgba if alpha < 1 |
326
+ | =to_name= | output to color name string if available, otherwise ='<unknown>'= or =to_hex= output based on optional arg value |
327
+ | =to_s= | output to the appropriate string format based on how the color was created, optional arg forces the format |
328
+
329
+ #+BEGIN_SRC ruby
330
+ # to_hsv
331
+ Kodachroma.paint('red').to_hsv #=> 'hsv(0, 100%, 100%)'
332
+ Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hsv #=> 'hsva(0, 100%, 100%, 0.5)'
333
+
334
+ # to_hsl
335
+ Kodachroma.paint('red').to_hsl #=> 'hsl(0, 100%, 50%)'
336
+ Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hsl #=> 'hsla(0, 100%, 50%, 0.5)'
337
+
338
+ # to_hex
339
+ Kodachroma.paint('red').to_hex #=> '#ff0000'
340
+ Kodachroma.paint('red').to_hex(true) #=> '#f00'
341
+ Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hex #=> '#ff0000'
342
+ Kodachroma.paint('red').to_hex #=> '#ffff0000'
343
+ Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hex #=> '#80ff0000'
344
+
345
+ # to_rgb
346
+ Kodachroma.paint('red').to_rgb #=> 'rgb(255, 0, 0)'
347
+ Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_rgb #=> 'rgb(255, 0, 0, 0.5)'
348
+
349
+ # to_name
350
+ Kodachroma.paint('red').to_name #=> 'red'
351
+ Kodachroma.paint('#00f').to_name #=> 'blue'
352
+ Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_name #=> '<unknown>'
353
+ Kodachroma.paint('#123').to_name(true) #=> '#112233'
354
+
355
+ # to_s
356
+ Kodachroma.paint('red').to_s #=> 'red'
357
+ Kodachroma.paint('rgb(255, 0, 0)').to_s #=> 'rgb(255, 0, 0)'
358
+ Kodachroma.paint('#f00').to_s #=> '#f00'
359
+ Kodachroma.paint('#80ff0000').to_s(:rgb) #=> 'rgba(255, 0, 0, 0.5)'
360
+ #+END_SRC
361
+
362
+ ** Other methods
363
+
364
+ Colors also have a few other helper methods:
365
+
366
+ | Method | Description |
367
+ |----------------+----------------------------------------------------------|
368
+ | =dark?= | is the color dark? |
369
+ | =light?= | is the color light? |
370
+ | =alpha= | retrieve the alpha value |
371
+ | =brightness= | calculate the brightness as a number between 0 and 255 |
372
+ | =complement= | return the complementary color |
373
+
374
+ #+BEGIN_SRC ruby
375
+ # dark?
376
+ Kodachroma.paint('red').dark? #=> true
377
+ Kodachroma.paint('yellow').dark? #=> false
378
+
379
+ # light?
380
+ Kodachroma.paint('red').light? #=> false
381
+ Kodachroma.paint('yellow').light? #=> true
382
+
383
+ # alpha
384
+ Kodachroma.paint('red').alpha #=> 1.0
385
+ Kodachroma.paint('rgba(0, 0, 0, 0.5)').alpha #=> 0.5
386
+
387
+ # brightness
388
+ Kodachroma.paint('red').brightness #=> 76.245
389
+ Kodachroma.paint('yellow').brightness #=> 225.93
390
+ Kodachroma.paint('white').brightness #=> 255.0
391
+ Kodachroma.paint('black').brightness #=> 0.0
392
+
393
+ # complement
394
+ Kodachroma.paint('red').complement #=> cyan
395
+ #+END_SRC
396
+
397
+ ** Trivia
398
+
399
+ The name "Kodachroma" is inspired by Paul Simon's lovely song "Kodachrome" and
400
+ my desire to keep "chroma" in the name of the gem so people searching for the
401
+ original gem might find this fork.
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+ module Kodachroma
3
+ class Color
4
+ # Attribute methods for {Color}.
5
+ module Attributes
6
+ attr_reader :format
7
+
8
+ # Determines if the color is dark.
9
+ #
10
+ # @example
11
+ # 'red'.paint.dark? #=> true
12
+ # 'yellow'.paint.dark? #=> false
13
+ #
14
+ # @return [true, false]
15
+ def dark?
16
+ brightness < 128
17
+ end
18
+
19
+ # Determines if the color is light.
20
+ #
21
+ # @example
22
+ # 'red'.paint.light? #=> false
23
+ # 'yellow'.paint.light? #=> true
24
+ #
25
+ # @return [true, false]
26
+ def light?
27
+ !dark?
28
+ end
29
+
30
+ # Returns the alpha channel value.
31
+ #
32
+ # @example
33
+ # 'red'.paint.alpha #=> 1.0
34
+ # 'rgba(0, 0, 0, 0.5)'.paint.alpha #=> 0.5
35
+ #
36
+ # @return [Float]
37
+ def alpha
38
+ @rgb.a
39
+ end
40
+
41
+ # Calculates the brightness.
42
+ #
43
+ # @example
44
+ # 'red'.paint.brightness #=> 76.245
45
+ # 'yellow'.paint.brightness #=> 225.93
46
+ #
47
+ # @return [Float]
48
+ def brightness
49
+ ((@rgb.r * 299) + (@rgb.g * 587) + (@rgb.b * 114)) / 1000.0
50
+ end
51
+
52
+ private
53
+
54
+ def rounded_alpha
55
+ @rounded_alpha ||= (alpha * 100).round / 100.0
56
+ end
57
+ end
58
+ end
59
+ end