kodachroma 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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