paleta 0.2.0 → 0.2.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b03ada62d667c325f97922bd22b05801aff9cccd
4
+ data.tar.gz: cb7d2375cfcf0ac8cceb96719d1c9cdb13b5af23
5
+ SHA512:
6
+ metadata.gz: 2a4cd1d750c2f78091b15b904d0d2e599dea95d91922a32b494ecd559bf5fa0eb504cb53e2ca735688efcab05195f573a5944eacaa37cef455d0430282873dbb
7
+ data.tar.gz: 1eeac708731584488a6a1611a14f3ba7417f3de5693f5144602cee107c43fe6d3b48b296c8dbd411a04561b46cead354641d77262f2aa8608f7a0a299292ad57
data/Gemfile CHANGED
@@ -2,6 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rspec', '~>2.8.0'
6
- gem 'guard-rspec'
7
- gem 'rmagick'
5
+ gem 'rmagick'
@@ -4,9 +4,9 @@ module Paleta
4
4
  # Represents a color
5
5
  class Color
6
6
  include Math
7
-
7
+
8
8
  attr_reader :red, :green, :blue, :hue, :saturation, :lightness, :hex
9
-
9
+
10
10
  # Initailize a {Color}
11
11
  #
12
12
  # @overload initialize()
@@ -36,7 +36,6 @@ module Paleta
36
36
  #
37
37
  # @return [Color] A new instance of {Color}
38
38
  def initialize(*args)
39
-
40
39
  if args.length == 1 && args[0].is_a?(Color)
41
40
  args[0].instance_variables.each do |key|
42
41
  self.send("#{key[1..key.length]}=".to_sym, args[0].send("#{key[1..key.length]}"))
@@ -59,43 +58,43 @@ module Paleta
59
58
  raise(ArgumentError, "Invalid arguments")
60
59
  end
61
60
  end
62
-
61
+
63
62
  def red=(val)
64
63
  @red = range_validator(val, 0..255)
65
64
  update_hsl
66
65
  update_hex
67
66
  end
68
-
67
+
69
68
  def green=(val)
70
69
  @green = range_validator(val, 0..255)
71
70
  update_hsl
72
71
  update_hex
73
72
  end
74
-
73
+
75
74
  def blue=(val)
76
75
  @blue = range_validator(val, 0..255)
77
76
  update_hsl
78
77
  update_hex
79
78
  end
80
-
79
+
81
80
  def lightness=(val)
82
81
  @lightness = range_validator(val, 0..100)
83
82
  update_rgb
84
83
  update_hex
85
84
  end
86
-
85
+
87
86
  def saturation=(val)
88
87
  @saturation = range_validator(val, 0..100)
89
88
  update_rgb
90
89
  update_hex
91
90
  end
92
-
91
+
93
92
  def hue=(val)
94
93
  @hue = range_validator(val, 0..360)
95
94
  update_rgb
96
95
  update_hex
97
96
  end
98
-
97
+
99
98
  def hex=(val)
100
99
  raise(ArgumentError, "Invalid Hex String") unless val.length == 6 && /^[[:xdigit:]]+$/ === val
101
100
  @hex = val.upcase
@@ -104,23 +103,23 @@ module Paleta
104
103
  @blue = val[4..5].hex
105
104
  update_hsl
106
105
  end
107
-
106
+
108
107
  # Determine the equality of the receiver and another {Color}
109
108
  # @param [Color] color color to compare
110
109
  # @return [Boolean]
111
110
  def ==(color)
112
111
  color.is_a?(Color) ? (self.hex == color.hex) : false
113
112
  end
114
-
113
+
115
114
  # Create a copy of the receiver and lighten it by a percentage
116
115
  # @param [Number] percentage percentage by which to lighten the {Color}
117
116
  # @return [Color] a lightened copy of the receiver
118
117
  def lighten(percentage = 5)
119
- copy = self.class.new(self)
118
+ copy = self.dup
120
119
  copy.lighten!(percentage)
121
120
  copy
122
121
  end
123
-
122
+
124
123
  # Lighten the receiver by a percentage
125
124
  # @param [Number] percentage percentage by which to lighten the {Color}
126
125
  # @return [Color] self
@@ -131,16 +130,16 @@ module Paleta
131
130
  update_hex
132
131
  self
133
132
  end
134
-
133
+
135
134
  # Create a copy of the receiver and darken it by a percentage
136
135
  # @param [Number] percentage percentage by which to darken the {Color}
137
136
  # @return [Color] a darkened copy of the receiver
138
137
  def darken(percentage = 5)
139
- copy = self.class.new(self)
138
+ copy = self.dup
140
139
  copy.darken!(percentage)
141
140
  copy
142
141
  end
143
-
142
+
144
143
  # Darken the receiver by a percentage
145
144
  # @param [Number] percentage percentage by which to darken the {Color}
146
145
  # @return [Color] self
@@ -151,7 +150,7 @@ module Paleta
151
150
  update_hex
152
151
  self
153
152
  end
154
-
153
+
155
154
  # Create a copy of the receiver and invert it
156
155
  # @return [Color] an inverted copy of the receiver
157
156
  def invert
@@ -159,7 +158,7 @@ module Paleta
159
158
  copy.invert!
160
159
  copy
161
160
  end
162
-
161
+
163
162
  # Invert the receiver
164
163
  # @return [Color] self
165
164
  def invert!
@@ -170,7 +169,7 @@ module Paleta
170
169
  update_hex
171
170
  self
172
171
  end
173
-
172
+
174
173
  # Create a copy of the receiver and desaturate it
175
174
  # @return [Color] a desaturated copy of the receiver
176
175
  def desaturate
@@ -187,7 +186,7 @@ module Paleta
187
186
  update_hex
188
187
  self
189
188
  end
190
-
189
+
191
190
  # Create a new {Color} that is the complement of the receiver
192
191
  # @return [Color] a desaturated copy of the receiver
193
192
  def complement
@@ -195,7 +194,7 @@ module Paleta
195
194
  copy.complement!
196
195
  copy
197
196
  end
198
-
197
+
199
198
  # Turn the receiver into it's complement
200
199
  # @return [Color] self
201
200
  def complement!
@@ -204,14 +203,14 @@ module Paleta
204
203
  update_hex
205
204
  self
206
205
  end
207
-
206
+
208
207
  # Calculate the similarity between the receiver and another {Color}
209
208
  # @param [Color] color color to calculate the similarity to
210
209
  # @return [Number] a value in [0..1] with 0 being identical and 1 being as dissimilar as possible
211
210
  def similarity(color)
212
211
  distance({ :r => @red, :g => @green, :b => @blue}, { :r => color.red, :g => color.green, :b => color.blue}) / sqrt(3 * (255 ** 2))
213
212
  end
214
-
213
+
215
214
  # Return an array representation of a {Color} instance,
216
215
  # @param [Symbol] model the color model, should be :rgb or :hsl
217
216
  # @return [Array] an array of component values
@@ -226,25 +225,25 @@ module Paleta
226
225
  end
227
226
  array
228
227
  end
229
-
228
+
230
229
  private
231
-
230
+
232
231
  def rgb_init(red = 0, green = 0, blue = 0)
233
232
  self.red = red
234
233
  self.green = green
235
234
  self.blue = blue
236
235
  end
237
-
236
+
238
237
  def hsl_init(hue = 0, saturation = 0, lightness = 0)
239
238
  self.hue = hue
240
239
  self.saturation = saturation
241
240
  self.lightness = lightness
242
241
  end
243
-
242
+
244
243
  def hex_init(val = "000000")
245
244
  self.hex = val
246
245
  end
247
-
246
+
248
247
  def update_hsl
249
248
  r = @red / 255.0 rescue 0.0
250
249
  g = @green / 255.0 rescue 0.0
@@ -253,10 +252,14 @@ module Paleta
253
252
  min = [r, g, b].min
254
253
  max = [r, g, b].max
255
254
  delta = max - min
256
-
255
+
257
256
  h = 0
258
257
  l = (max + min) / 2.0
259
- s = ((l == 0 || l == 1) ? 0 : (delta / (1 - (2 * l - 1).abs)))
258
+ if ![1, 0].include?(l) && delta / 2.0 == l
259
+ s = 1.0
260
+ else
261
+ s = ((l == 0 || l == 1) ? 0 : (delta / (1 - (2 * l - 1).abs)))
262
+ end
260
263
 
261
264
  if delta != 0
262
265
  case max
@@ -265,15 +268,14 @@ module Paleta
265
268
  when b; h = ((r - g) / delta) + 4
266
269
  end
267
270
  end
268
-
271
+
269
272
  @hue = h * 60
270
273
  @hue += 360 if @hue < 0
271
274
  @saturation = s * 100
272
275
  @lightness = l * 100
273
276
  end
274
-
277
+
275
278
  def update_rgb
276
-
277
279
  h = @hue / 60.0 rescue 0.0
278
280
  s = @saturation / 100.0 rescue 0.0
279
281
  l = @lightness / 100.0 rescue 0.0
@@ -281,7 +283,7 @@ module Paleta
281
283
  d1 = (1 - (2 * l - 1).abs) * s
282
284
  d2 = d1 * (1 - (h % 2 - 1).abs)
283
285
  d3 = l - (d1 / 2.0)
284
-
286
+
285
287
  case h.to_i
286
288
  when 0; @red, @green, @blue = d1, d2, 0
287
289
  when 1; @red, @green, @blue = d2, d1, 0
@@ -291,12 +293,12 @@ module Paleta
291
293
  when 5; @red, @green, @blue = d1, 0, d2
292
294
  else; @red, @green, @blue = 0, 0, 0
293
295
  end
294
-
296
+
295
297
  @red = 255 * (@red + d3)
296
298
  @green = 255 * (@green + d3)
297
299
  @blue = 255 * (@blue + d3)
298
300
  end
299
-
301
+
300
302
  def update_hex
301
303
  r = @red.to_i.to_s(16) rescue "00"
302
304
  g = @green.to_i.to_s(16) rescue "00"
@@ -306,7 +308,7 @@ module Paleta
306
308
  b = "0#{b}" if b.length < 2
307
309
  @hex = "#{r}#{g}#{b}".upcase
308
310
  end
309
-
311
+
310
312
  def range_validator(val, range)
311
313
  range.include?(val) ? val : raise(ArgumentError, "Component range exceeded")
312
314
  end
@@ -8,20 +8,20 @@ module Math
8
8
  a.each_with_index { |v, i| sum += (a[i] - b[i]) ** 2 } if a.is_a?(Array)
9
9
  sqrt(sum)
10
10
  end
11
-
11
+
12
12
  def multiple_regression(dx, dy, dz)
13
13
  regression = {}
14
14
  regression[:slope], regression[:offset] = {}, {}
15
15
  size = dx.size
16
-
16
+
17
17
  raise "arguments not same length!" unless size == dy.size && size == dz.size
18
-
18
+
19
19
  if size == 1
20
20
  regression[:slope] = { :x => dx[0], :y => dy[0], :z => dz[0] }
21
21
  regression[:offset] = { :x => 0, :y => 0, :z => 0 }
22
22
  return regression
23
23
  end
24
-
24
+
25
25
  sxx = syy = szz = sxy = szx = syz = sx = sy = sz = 0
26
26
  dx.zip(dy, dz).each do |x, y, z|
27
27
  sxx += x ** 2
@@ -34,15 +34,15 @@ module Math
34
34
  sy += y
35
35
  sz += z
36
36
  end
37
-
37
+
38
38
  regression[:slope][:x] = ( size * sxy - sx * sz ) / ( size * sxx - sx ** 2 ).to_f
39
39
  regression[:slope][:y] = ( size * syz - sz * sy ) / ( size * syy - sz ** 2 ).to_f
40
40
  regression[:slope][:z] = ( size * syz - sz * sy ) / ( size * szz - sy ** 2 ).to_f
41
-
41
+
42
42
  regression[:offset][:x] = (sz - regression[:slope][:x] * sx) / size
43
43
  regression[:offset][:y] = (sy - regression[:slope][:y] * sz) / size
44
44
  regression[:offset][:z] = (sx - regression[:slope][:z] * sy) / size
45
-
45
+
46
46
  regression
47
47
  end
48
48
  end
@@ -1,24 +1,23 @@
1
1
  require 'paleta/core_ext/math'
2
2
 
3
3
  module Paleta
4
-
5
4
  module MagickDependent
6
5
  def self.included(klass)
7
- require 'RMagick'
6
+ require 'RMagick' unless defined?(Magick)
8
7
  klass.extend(ClassMethods)
9
8
  rescue LoadError
10
9
  puts "You must install RMagick to use Palette.generate(:from => :image, ...)"
11
10
  end
12
-
11
+
13
12
  module ClassMethods
14
13
  def generate_from_image(path, size = 5)
15
14
  include Magick
16
15
  begin
17
16
  image = Magick::ImageList.new(path)
18
-
17
+
19
18
  # quantize image to the nearest power of 2 greater the desired palette size
20
19
  quantized_image = image.quantize((Math.sqrt(size).ceil ** 2), Magick::RGBColorspace)
21
- colors = quantized_image.color_histogram.sort { |a, b| b[1] <=> a[1] }[0..(size - 1)].map do |color|
20
+ colors = quantized_image.color_histogram.sort { |a, b| b[1] <=> a[1] }[0..(size - 1)].map do |color|
22
21
  Paleta::Color.new(color[0].red / 256, color[0].green / 256, color[0].blue / 256)
23
22
  end
24
23
  return Paleta::Palette.new(colors)
@@ -28,15 +27,15 @@ module Paleta
28
27
  end
29
28
  end
30
29
  end
31
-
30
+
32
31
  # Represents a palette, a collection of {Color}s
33
32
  class Palette
34
33
  include Math
35
34
  include Enumerable
36
35
  include MagickDependent
37
-
36
+
38
37
  attr_accessor :colors
39
-
38
+
40
39
  # Initialize a {Palette} from a list of {Color}s
41
40
  # @param [Array] colors a list of {Color}s to include in the {Palette}
42
41
  # @return [Palette] A new instance of {Palette}
@@ -45,7 +44,7 @@ module Paleta
45
44
  colors = (args.length == 1 && args[0].is_a?(Array)) ? args[0] : args
46
45
  colors.each { |color| self << color }
47
46
  end
48
-
47
+
49
48
  # Add a {Color} to the {Palette}
50
49
  # @overload <<(color)
51
50
  # @param [Color] color a {Color} to add to the receiver
@@ -63,7 +62,7 @@ module Paleta
63
62
  end
64
63
  self
65
64
  end
66
-
65
+
67
66
  # Add a {Color} to the {Palette}
68
67
  # @overload push(color)
69
68
  # @param [Color] color a {Color} to add to the receiver
@@ -74,56 +73,56 @@ module Paleta
74
73
  def push(obj)
75
74
  self << obj
76
75
  end
77
-
76
+
78
77
  # Remove the most recently added {Color} from the receiver
79
78
  def pop
80
79
  @colors.pop
81
80
  end
82
-
81
+
83
82
  # Remove a {Color} from the receiver by index
84
83
  # @param [Number] index the index at which to remove a {Color}
85
84
  def delete_at(index = 0)
86
85
  @colors.delete_at(index)
87
86
  end
88
-
87
+
89
88
  # Access a {Color} in the receiver by index
90
89
  # @param [Number] index the index at which to access a {Color}
91
90
  def [](index)
92
91
  @colors[index]
93
92
  end
94
-
93
+
95
94
  # The number of {Color}s in the {Palette}
96
95
  # @return [Number] the number of {Color}s in the receiver
97
96
  def size
98
97
  @colors.size
99
98
  end
100
-
99
+
101
100
  # Iterate through each {Color} in the {Palette}
102
101
  def each
103
102
  @colors.each { |c| yield c }
104
103
  end
105
-
104
+
106
105
  # Create a new instance of {Palette} that is a sorted copy of the receiver
107
106
  # @return [Palette] a new instance of {Palette}
108
107
  def sort(&blk)
109
108
  @colors.sort(&blk)
110
109
  Paleta::Palette.new(@colors)
111
110
  end
112
-
111
+
113
112
  # Sort the {Color}s in the receiver
114
113
  # return [Palette] self
115
114
  def sort!(&blk)
116
115
  @colors.sort!(&blk)
117
116
  self
118
117
  end
119
-
118
+
120
119
  # Test if a {Color} exists in the receiver
121
120
  # @param [Color] color color to test for inclusion in the {Palette}
122
121
  # @return [Boolean]
123
122
  def include?(color)
124
123
  @colors.include?(color)
125
124
  end
126
-
125
+
127
126
  # Lighen each {Color} in the receiver by a percentage
128
127
  # @param [Number] percentage percentage by which to lighten each {Color} in the receiver
129
128
  # @return [Palette] self
@@ -131,7 +130,7 @@ module Paleta
131
130
  @colors.each { |color| color.lighten!(percentage) }
132
131
  self
133
132
  end
134
-
133
+
135
134
  # Lighen each {Color} in the receiver by a percentage
136
135
  # @param [Number] percentage percentage by which to lighten each {Color} in the receiver
137
136
  # @return [Palette] self
@@ -139,40 +138,40 @@ module Paleta
139
138
  @colors.each { |color| color.darken!(percentage) }
140
139
  self
141
140
  end
142
-
141
+
143
142
  # Invert each {Color} in the receiver by a percentage
144
143
  # @return [Palette] self
145
144
  def invert!
146
145
  @colors.each { |color| color.invert! }
147
146
  self
148
147
  end
149
-
148
+
150
149
  # Calculate the similarity between the receiver and another {Palette}
151
150
  # @param [Palette] palette palette to calculate the similarity to
152
151
  # @return [Number] a value in [0..1] with 0 being identical and 1 being as dissimilar as possible
153
152
  def similarity(palette)
154
153
  r, a, b = [], [], []
155
154
  (0..1).each { |i| a[i], b[i] = {}, {} }
156
-
155
+
157
156
  # r[i] is a hash of the multiple regression of the Palette in RGB space
158
157
  r[0] = fit
159
158
  r[1] = palette.fit
160
-
159
+
161
160
  [0, 1].each do |i|
162
161
  [:x, :y, :z].each do |k|
163
162
  a[i][k] = 0 * r[i][:slope][k] + r[i][:offset][k]
164
163
  b[i][k] = 255 * r[i][:slope][k] + r[i][:offset][k]
165
164
  end
166
165
  end
167
-
166
+
168
167
  d_max = sqrt(3 * (65025 ** 2))
169
-
168
+
170
169
  d1 = distance(a[0], a[1]) / d_max
171
170
  d2 = distance(b[0], b[1]) / d_max
172
-
171
+
173
172
  d1 + d2
174
173
  end
175
-
174
+
176
175
  # Generate a {Palette} from a seed {Color}
177
176
  # @param [Hash] opts the options with which to generate a new {Palette}
178
177
  # @option opts [Symbol] :type the type of palette to generate
@@ -182,25 +181,25 @@ module Paleta
182
181
  # @option opts [Number] :size the number of {Color}s to generate for the {Palette}
183
182
  # @return [Palette] A new instance of {Palette}
184
183
  def self.generate(opts = {})
185
-
184
+
186
185
  size = opts[:size] || 5
187
-
186
+
188
187
  if !opts[:type].nil? && opts[:type].to_sym == :random
189
188
  return self.generate_random_from_color(opts[:color], size)
190
189
  end
191
-
190
+
192
191
  unless (opts[:from].to_sym == :color && !opts[:color].nil?) || (opts[:from].to_sym == :image && !opts[:image].nil?)
193
192
  return raise(ArgumentError, 'You must pass :from and it must be either :color or :image, then you must pass :image => "/path/to/img" or :color => color')
194
193
  end
195
-
194
+
196
195
  if opts[:from].to_sym == :image
197
196
  path = opts[:image]
198
197
  return self.generate_from_image(path, size)
199
198
  end
200
-
199
+
201
200
  color = opts[:color]
202
201
  type = opts[:type] || :shades
203
-
202
+
204
203
  case type
205
204
  when :analogous; self.generate_analogous_from_color(color, size)
206
205
  when :complementary; self.generate_complementary_from_color(color, size)
@@ -212,7 +211,7 @@ module Paleta
212
211
  else raise(ArgumentError, "Palette type is not defined. Try :analogous, :monochromatic, :shades, or :random")
213
212
  end
214
213
  end
215
-
214
+
216
215
  # Return an array representation of a {Palette} instance,
217
216
  # @param [Symbol] model the color model, should be :rgb, :hsl, or :hex
218
217
  # @return [Array] an Array of Arrays where each sub-Array is a representation of a {Color} object in a {Palette} instance
@@ -227,9 +226,9 @@ module Paleta
227
226
  end
228
227
  array
229
228
  end
230
-
229
+
231
230
  private
232
-
231
+
233
232
  def self.generate_analogous_from_color(color, size)
234
233
  raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
235
234
  palette = self.new(color)
@@ -248,14 +247,14 @@ module Paleta
248
247
  end
249
248
  palette.sort! { |a, b| a.hue <=> b.hue }
250
249
  end
251
-
250
+
252
251
  def self.generate_complementary_from_color(color, size)
253
252
  raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
254
253
  complement = color.complement
255
254
  palette = self.new(color, complement)
256
255
  add_monochromatic_in_hues_of_color(palette, color, size)
257
256
  end
258
-
257
+
259
258
  def self.generate_triad_from_color(color, size)
260
259
  raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
261
260
  color2 = Paleta::Color.new(:hsl, (color.hue + 120) % 360, color.saturation, color.lightness)
@@ -263,7 +262,7 @@ module Paleta
263
262
  palette = self.new(color, color2, color3)
264
263
  add_monochromatic_in_hues_of_color(palette, color, size)
265
264
  end
266
-
265
+
267
266
  def self.generate_tetrad_from_color(color, size)
268
267
  raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
269
268
  color2 = Paleta::Color.new(:hsl, (color.hue + 90) % 360, color.saturation, color.lightness)
@@ -272,7 +271,7 @@ module Paleta
272
271
  palette = self.new(color, color2, color3, color4)
273
272
  add_monochromatic_in_hues_of_color(palette, color, size)
274
273
  end
275
-
274
+
276
275
  def self.generate_monochromatic_from_color(color, size)
277
276
  raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
278
277
  palette = self.new(color)
@@ -290,7 +289,7 @@ module Paleta
290
289
  end
291
290
  palette.sort! { |a, b| a.saturation <=> b.saturation }
292
291
  end
293
-
292
+
294
293
  def self.generate_shades_from_color(color, size)
295
294
  raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
296
295
  palette = self.new(color)
@@ -298,17 +297,17 @@ module Paleta
298
297
  lightness = color.lightness
299
298
  d = :down
300
299
  until palette.size == size
301
- lightness -= step if d == :down
302
- lightness += step if d == :up
303
- palette << Paleta::Color.new(:hsl, color.hue, color.saturation, lightness)
304
300
  if lightness - step < 0
305
301
  d = :up
306
302
  lightness = color.lightness
307
303
  end
304
+ lightness -= step if d == :down
305
+ lightness += step if d == :up
306
+ palette << Paleta::Color.new(:hsl, color.hue, color.saturation, lightness)
308
307
  end
309
308
  palette.sort! { |a, b| a.lightness <=> b.lightness }
310
309
  end
311
-
310
+
312
311
  def self.generate_split_complement_from_color(color, size)
313
312
  raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
314
313
  color2 = Paleta::Color.new(:hsl, (color.hue + 150) % 360, color.saturation, color.lightness)
@@ -316,7 +315,7 @@ module Paleta
316
315
  palette = self.new(color, color2, color3)
317
316
  add_monochromatic_in_hues_of_color(palette, color, size)
318
317
  end
319
-
318
+
320
319
  def self.generate_random_from_color(color = nil, size)
321
320
  palette = color.is_a?(Color) ? self.new(color) : self.new
322
321
  r = Random.new(Time.now.sec)
@@ -325,14 +324,14 @@ module Paleta
325
324
  end
326
325
  palette
327
326
  end
328
-
327
+
329
328
  def self.add_monochromatic_in_hues_of_color(palette, color, size)
330
- raise(ArgumentError, "Second argument is not a Color") unless color.is_a?(Color)
329
+ raise(ArgumentError, "Second argument is not a Color") unless color.is_a?(Color)
331
330
  hues = palette.map { |c| c.hue }
332
331
  step = ugap = dgap = 100 / size
333
332
  i = j = 0
334
333
  saturation = color.saturation
335
- until palette.size == size
334
+ until palette.size == size
336
335
  if color.saturation + ugap < 100
337
336
  saturation = color.saturation + ugap
338
337
  ugap += step
@@ -340,13 +339,13 @@ module Paleta
340
339
  saturation = color.saturation - dgap
341
340
  dgap += step
342
341
  end if j == 3 || j == 1
343
- new_color = Paleta::Color.new(:hsl, hues[i], saturation, color.lightness)
342
+ new_color = Paleta::Color.new(:hsl, hues[i], saturation, color.lightness)
344
343
  palette << new_color unless palette.include?(new_color)
345
344
  i += 1; j += 1; i %= hues.size; j %= (2 * hues.size)
346
345
  end
347
346
  palette.sort! { |a, b| a.saturation <=> b.saturation }
348
347
  end
349
-
348
+
350
349
  def fit
351
350
  # create a 3xn matrix where n = @colors.size to represent the set of colors
352
351
  reds = @colors.map { |c| c.red }
@@ -1,3 +1,3 @@
1
1
  module Paleta
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -14,4 +14,8 @@ Gem::Specification.new do |gem|
14
14
  gem.name = 'paleta'
15
15
  gem.require_paths = ['lib']
16
16
  gem.version = Paleta::VERSION
17
+
18
+ gem.add_development_dependency "rspec", "~> 2.8"
19
+ gem.add_development_dependency "guard-rspec", "~> 1.2"
20
+ gem.add_development_dependency "pry-byebug", "~> 2.0"
17
21
  end
@@ -27,63 +27,82 @@ Paleta allows users to create Color objects. Color objects can be defined by HSL
27
27
  #### Creating Colors
28
28
 
29
29
  Colors can be created using RGB or HSL components, or by using a HEX value by passing in a flag of the desired format as the first parameter. If no format flag is used, RGB is assumed.
30
-
31
- color = Paleta::Color.new(:hsl, 280, 37, 68)
32
- color = Paleta::Color.new(:rgb, 94, 161, 235)
33
- color = Paleta::Color.new(:hex, "5EA1EB")
34
-
35
- # creating a Color with no flag defaults to RGB components
36
- color = Paleta::Color.new(94, 161, 235)
37
-
30
+
31
+ ```ruby
32
+ color = Paleta::Color.new(:hsl, 280, 37, 68)
33
+ color = Paleta::Color.new(:rgb, 94, 161, 235)
34
+ color = Paleta::Color.new(:hex, "5EA1EB")
35
+
36
+ # creating a Color with no flag defaults to RGB components
37
+
38
+ color = Paleta::Color.new(94, 161, 235)
39
+ ```
40
+
38
41
  Individual component values can be accessed by name
39
42
 
40
- color.red # => 94
41
- color.green # => 161
42
- color.blue # => 235
43
- color.hue # => 211.48936170212767
44
- color.saturation # => 77.90055248618782
45
- color.lightness # => 64.50980392156862
46
- color.hex # => "5EA1EB"
47
-
43
+ ```ruby
44
+ color.red # => 94
45
+ color.green # => 161
46
+ color.blue # => 235
47
+ color.hue # => 211.48936170212767
48
+ color.saturation # => 77.90055248618782
49
+ color.lightness # => 64.50980392156862
50
+ color.hex # => "5EA1EB"
51
+ ```
48
52
 
49
53
  Get an array representation of a Color
50
54
 
51
- c = Paleta::Color.new(30, 90, 120)
52
- c.to_array(:rgb) # => [30, 90, 120]
53
-
55
+ ```ruby
56
+ c = Paleta::Color.new(30, 90, 120)
57
+ c.to_array(:rgb) # => [30, 90, 120]
58
+ ```
59
+
54
60
  #### Manipulating Colors
55
61
 
62
+
56
63
  Colors can be lightened or darkened by a percentage
57
64
 
58
- color.lighten!(10)
59
- color.darken!(30)
60
-
65
+ ```ruby
66
+ color.lighten!(10)
67
+ color.darken!(30)
68
+ ```
69
+
61
70
  Colors can be desaturated
62
71
 
63
- color.desaturate!
64
-
72
+ ```ruby
73
+ color.desaturate!
74
+ ```
75
+
65
76
  Colors can be turned into their complement Colors
66
77
 
67
- color.complement!
78
+ ```ruby
79
+ color.complement!
80
+ ```
68
81
 
69
82
  Colors can be inverted
70
83
 
71
- color.invert!
72
-
84
+ ```ruby
85
+ color.invert!
86
+ ```
87
+
73
88
  **Note** all of the previous methods directly manipulate the object on which they were called. If you would like to create a new Color object that is a copy of the original color (but with the desired manipulation), call the desired method without the trailing bang `!`.
74
89
 
75
90
  For example, lets create a new Color that is the complement of a Color we have already defined.
76
91
 
77
- new_color = color.complement
78
-
92
+ ```ruby
93
+ new_color = color.complement
94
+ ```
95
+
79
96
  #### Comparing Colors
80
97
 
81
98
  Colors can calculate their similarity to other Colors. The `similarity` method returns a value between 0 and 1, with 0 being identical and 1 being as dissimilar as possible.
82
99
 
83
- color = Paleta::Color.new(:hsl, 280, 37, 68)
84
- color2 = Paleta::Color.new(237, 172, 33)
85
- color.similarity(color2) # => 0.4100287904421024
86
-
100
+ ```ruby
101
+ color = Paleta::Color.new(:hsl, 280, 37, 68)
102
+ color2 = Paleta::Color.new(237, 172, 33)
103
+ color.similarity(color2) # => 0.4100287904421024
104
+ ```
105
+
87
106
  ### Palette
88
107
 
89
108
  Palettes are collections of Colors, they share many common Array methods such as `push`, `pop`, `sort`, `include?` and `each`. Palettes also allow collections of Colors to be manipulated as a whole and to be compared to each other.
@@ -92,99 +111,127 @@ Palettes are collections of Colors, they share many common Array methods such as
92
111
 
93
112
  Palettes can be created by passing a list of Colors to the Palette constructor, or on the fly with `push` and `<<`.
94
113
 
95
- color1 = Paleta::Color.new(13, 57, 182)
96
- color2 = Paleta::Color.new(94, 161, 235)
97
- color3 = Paleta::Color.new(237, 182, 17)
98
- palette = Paleta::Palette.new(color1, color2)
99
-
100
- palette << color3
101
-
114
+ ```ruby
115
+ color1 = Paleta::Color.new(13, 57, 182)
116
+ color2 = Paleta::Color.new(94, 161, 235)
117
+ color3 = Paleta::Color.new(237, 182, 17)
118
+ palette = Paleta::Palette.new(color1, color2)
119
+
120
+ palette << color3
121
+ ```
122
+
102
123
  #### Retrieving and Removing Colors from Palettes
103
124
 
104
125
  Colors can be accessed and removed by index.
105
126
 
106
- palette[1] # => color2
107
-
108
- palette.delete_at(2)
109
-
127
+ ```ruby
128
+ palette[1] # => color2
129
+
130
+ palette.delete_at(2)
131
+ ```
132
+
110
133
  Get an array representation of a Palette
111
134
 
112
- c1 = Paleta::Color.new(13, 57, 182)
113
- c2 = Paleta::Color.new(94, 161, 235)
114
- palette = Paleta::Palette.new(c1, c2)
135
+ ```ruby
136
+ c1 = Paleta::Color.new(13, 57, 182)
137
+ c2 = Paleta::Color.new(94, 161, 235)
138
+ palette = Paleta::Palette.new(c1, c2)
115
139
 
116
- palette.to_array(:rgb) # => [[13, 57, 182], [94, 161, 235]]
140
+ palette.to_array(:rgb) # => [[13, 57, 182], [94, 161, 235]]
141
+ ```
117
142
 
118
143
  #### Manipulating Palettes
119
144
 
120
145
  Palettes can be lightened, darkened or inverted as a whole.
121
-
122
- palette.lighten!(15)
123
- palette.darken!(20)
124
- palette.invert!
125
-
146
+
147
+ ```ruby
148
+ palette.lighten!(15)
149
+ palette.darken!(20)
150
+ palette.invert!
151
+ ```
152
+
126
153
  #### Comparing Palettes
127
154
 
128
155
  Palettes can calculate their similarity to other Palettes by using the `similarity` method. Just as with `Color#similarity`, this method returns a value between 0 and 1, with 0 being identical and 1 being as dissimilar as possible.
129
156
 
130
- color1 = Paleta::Color.new(13, 57, 182)
131
- color2 = Paleta::Color.new(237, 172, 33)
132
- palette1 = Paleta::Palette.new(color1, color2)
133
-
134
- color3 = Paleta::Color.new(13, 57, 182)
135
- color4 = Paleta::Color.new(94, 161, 235)
136
- palette2 = Paleta::Palette.new(color3, color4)
157
+ ```ruby
158
+ color1 = Paleta::Color.new(13, 57, 182)
159
+ color2 = Paleta::Color.new(237, 172, 33)
160
+ palette1 = Paleta::Palette.new(color1, color2)
161
+
162
+ color3 = Paleta::Color.new(13, 57, 182)
163
+ color4 = Paleta::Color.new(94, 161, 235)
164
+ palette2 = Paleta::Palette.new(color3, color4)
165
+
166
+ palette1.similarity(palette2) # => 0.0046992695975874915
167
+ ```
137
168
 
138
- palette1.similarity(palette2) # => 0.0046992695975874915
139
-
140
169
  #### Generating Palettes
141
170
 
142
171
  Palettes can be generated from a "seed" Color or from an image by using the `generate` method.
143
172
 
144
173
  **Generate a Palette of shades from a Color**
145
174
 
146
- color = Paleta::Color.new(:hex, "ff0000")
147
- palette = Paleta::Palette.generate(:type => :shades, :from => :color, :size => 5)
148
-
175
+ ```ruby
176
+ color = Paleta::Color.new(:hex, "ff0000")
177
+ palette = Paleta::Palette.generate(:type => :shades, :from => :color, :size => 5)
178
+ ```
179
+
149
180
  **Generate a Palette of analogous Colors from a Color**
150
181
 
151
- color = Paleta::Color.new(:hex, "0066cc")
152
- palette = Paleta::Palette.generate(:type => :analogous, :from => :color, :size => 5)
153
-
182
+ ```ruby
183
+ color = Paleta::Color.new(:hex, "0066cc")
184
+ palette = Paleta::Palette.generate(:type => :analogous, :from => :color, :size => 5)
185
+ ```
186
+
154
187
  **Generate a Palette of monochromatic Colors from a Color**
155
188
 
156
- color = Paleta::Color.new(:hex, "336699")
157
- palette = Paleta::Palette.generate(:type => :monochromatic, :from => :color, :size => 5)
158
-
189
+ ```ruby
190
+ color = Paleta::Color.new(:hex, "336699")
191
+ palette = Paleta::Palette.generate(:type => :monochromatic, :from => :color, :size => 5)
192
+ ```
193
+
159
194
  **Generate a Palette of complementary Colors from a Color**
160
195
 
161
- color = Paleta::Color.new(:hex, "0000ff")
162
- palette = Paleta::Palette.generate(:type => :complementary, :from => :color, :size => 5)
196
+ ```ruby
197
+ color = Paleta::Color.new(:hex, "0000ff")
198
+ palette = Paleta::Palette.generate(:type => :complementary, :from => :color, :size => 5)
199
+ ```
163
200
 
164
201
  **Generate a Palette of split-complement Colors from a Color**
165
202
 
166
- color = Paleta::Color.new(:hex, "006699")
167
- palette = Paleta::Palette.generate(:type => :split_complement, :from => :color, :size => 5)
203
+ ```ruby
204
+ color = Paleta::Color.new(:hex, "006699")
205
+ palette = Paleta::Palette.generate(:type => :split_complement, :from => :color, :size => 5)
206
+ ```
168
207
 
169
208
  **Generate a Palette of triad Colors from a Color**
170
209
 
171
- color = Paleta::Color.new(:hex, "006699")
172
- palette = Paleta::Palette.generate(:type => :triad, :from => :color, :size => 5)
210
+ ```ruby
211
+ color = Paleta::Color.new(:hex, "006699")
212
+ palette = Paleta::Palette.generate(:type => :triad, :from => :color, :size => 5)
213
+ ```
173
214
 
174
215
  **Generate a Palette of tetrad Colors from a Color**
175
216
 
176
- color = Paleta::Color.new(:hex, "dd5533")
177
- palette = Paleta::Palette.generate(:type => :tetrad, :from => :color, :size => 5)
178
-
217
+ ```ruby
218
+ color = Paleta::Color.new(:hex, "dd5533")
219
+ palette = Paleta::Palette.generate(:type => :tetrad, :from => :color, :size => 5)
220
+ ```
221
+
179
222
  **Generate a random Palette**
180
223
 
181
- palette = Paleta::Palette.generate(:type => :random, :size => 5)
182
-
224
+ ```ruby
225
+ palette = Paleta::Palette.generate(:type => :random, :size => 5)
226
+ ```
227
+
183
228
  Palettes can also be generated from a seed image
184
229
 
185
230
  **Generate a Palette from an image**
186
231
 
187
- palette = Paleta::Palette.generate(:from => :image, :image => "/path/to/image.jpg", :size => 5)
232
+ ```ruby
233
+ palette = Paleta::Palette.generate(:from => :image, :image => "/path/to/image.jpg", :size => 5)
234
+ ```
188
235
 
189
236
  ***
190
237
 
metadata CHANGED
@@ -1,16 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paleta
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jordan Stephens
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-03-13 00:00:00.000000000Z
13
- dependencies: []
11
+ date: 2014-12-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: guard-rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
14
55
  description: A gem for working with color palettes
15
56
  email:
16
57
  - iam@jordanstephens.net
@@ -18,7 +59,7 @@ executables: []
18
59
  extensions: []
19
60
  extra_rdoc_files: []
20
61
  files:
21
- - .gitignore
62
+ - ".gitignore"
22
63
  - Gemfile
23
64
  - LICENSE
24
65
  - lib/paleta.rb
@@ -34,27 +75,26 @@ files:
34
75
  - spec/spec_helper.rb
35
76
  homepage: http://rubygems.org/gems/paleta
36
77
  licenses: []
78
+ metadata: {}
37
79
  post_install_message:
38
80
  rdoc_options: []
39
81
  require_paths:
40
82
  - lib
41
83
  required_ruby_version: !ruby/object:Gem::Requirement
42
- none: false
43
84
  requirements:
44
- - - ! '>='
85
+ - - ">="
45
86
  - !ruby/object:Gem::Version
46
87
  version: '0'
47
88
  required_rubygems_version: !ruby/object:Gem::Requirement
48
- none: false
49
89
  requirements:
50
- - - ! '>='
90
+ - - ">="
51
91
  - !ruby/object:Gem::Version
52
92
  version: '0'
53
93
  requirements: []
54
94
  rubyforge_project:
55
- rubygems_version: 1.8.10
95
+ rubygems_version: 2.2.2
56
96
  signing_key:
57
- specification_version: 3
97
+ specification_version: 4
58
98
  summary: A little library for creating, manipulating and comparing colors and color
59
99
  palettes
60
100
  test_files:
@@ -62,4 +102,3 @@ test_files:
62
102
  - spec/models/color_spec.rb
63
103
  - spec/models/palette_spec.rb
64
104
  - spec/spec_helper.rb
65
- has_rdoc: