paleta 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/lib/paleta/color.rb +17 -14
- data/lib/paleta/core_ext/math.rb +30 -33
- data/lib/paleta/palette.rb +88 -25
- data/lib/paleta/version.rb +1 -1
- data/paleta.gemspec +1 -1
- data/readme.markdown +84 -36
- data/spec/models/color_spec.rb +12 -2
- data/spec/models/palette_spec.rb +50 -9
- metadata +3 -3
data/Gemfile
CHANGED
data/lib/paleta/color.rb
CHANGED
@@ -9,15 +9,9 @@ module Paleta
|
|
9
9
|
def initialize(*args)
|
10
10
|
|
11
11
|
if args.length == 1 && args[0].is_a?(Color)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@green = args[0].green
|
16
|
-
@blue = args[0].blue
|
17
|
-
@hue = args[0].hue
|
18
|
-
@saturation = args[0].saturation
|
19
|
-
@lightness = args[0].lightness
|
20
|
-
@hex = args[0].hex
|
12
|
+
args[0].instance_variables.each do |key|
|
13
|
+
self.send("#{key[1..key.length]}=".to_sym, args[0].send("#{key[1..key.length]}"))
|
14
|
+
end
|
21
15
|
elsif args.length == 2 && args[0] == :hex && args[1].is_a?(String)
|
22
16
|
# example: new(:hex, "336699")
|
23
17
|
hex_init(args[1])
|
@@ -98,10 +92,14 @@ module Paleta
|
|
98
92
|
update_hsl
|
99
93
|
end
|
100
94
|
|
95
|
+
def ==(color)
|
96
|
+
color.is_a?(Color) ? (self.hex == color.hex) : false
|
97
|
+
end
|
98
|
+
|
101
99
|
def lighten(percent = 5)
|
102
100
|
copy = self.class.new(self)
|
103
101
|
copy.lighten!(percent)
|
104
|
-
|
102
|
+
copy
|
105
103
|
end
|
106
104
|
|
107
105
|
def lighten!(percent = 5)
|
@@ -109,12 +107,13 @@ module Paleta
|
|
109
107
|
@lightness = 100 if @lightness > 100
|
110
108
|
update_rgb
|
111
109
|
update_hex
|
110
|
+
self
|
112
111
|
end
|
113
112
|
|
114
113
|
def darken(percent = 5)
|
115
114
|
copy = self.class.new(self)
|
116
115
|
copy.darken!(percent)
|
117
|
-
|
116
|
+
copy
|
118
117
|
end
|
119
118
|
|
120
119
|
def darken!(percent = 5)
|
@@ -122,12 +121,13 @@ module Paleta
|
|
122
121
|
@lightness = 0 if @lightness < 0
|
123
122
|
update_rgb
|
124
123
|
update_hex
|
124
|
+
self
|
125
125
|
end
|
126
126
|
|
127
127
|
def invert
|
128
128
|
copy = self.class.new(self)
|
129
129
|
copy.invert!
|
130
|
-
|
130
|
+
copy
|
131
131
|
end
|
132
132
|
|
133
133
|
def invert!
|
@@ -136,30 +136,33 @@ module Paleta
|
|
136
136
|
@blue = 255 - @blue
|
137
137
|
update_hsl
|
138
138
|
update_hex
|
139
|
+
self
|
139
140
|
end
|
140
141
|
|
141
142
|
def desaturate
|
142
143
|
copy = self.class.new(self)
|
143
144
|
copy.desaturate!
|
144
|
-
|
145
|
+
copy
|
145
146
|
end
|
146
147
|
|
147
148
|
def desaturate!
|
148
149
|
@saturation = 0
|
149
150
|
update_rgb
|
150
151
|
update_hex
|
152
|
+
self
|
151
153
|
end
|
152
154
|
|
153
155
|
def complement
|
154
156
|
copy = self.class.new(self)
|
155
157
|
copy.complement!
|
156
|
-
|
158
|
+
copy
|
157
159
|
end
|
158
160
|
|
159
161
|
def complement!
|
160
162
|
@hue = (@hue + 180) % 360
|
161
163
|
update_rgb
|
162
164
|
update_hex
|
165
|
+
self
|
163
166
|
end
|
164
167
|
|
165
168
|
def similarity(color)
|
data/lib/paleta/core_ext/math.rb
CHANGED
@@ -9,42 +9,39 @@ module Math
|
|
9
9
|
sqrt(sum)
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@slope, @offset = {}, {}
|
18
|
-
@size = dr.size
|
19
|
-
raise "arguments not same length!" unless @size == dg.size && @size == db.size
|
12
|
+
def multiple_regression(dx, dy, dz)
|
13
|
+
regression = {}
|
14
|
+
regression[:slope], regression[:offset] = {}, {}
|
15
|
+
size = dx.size
|
20
16
|
|
21
|
-
|
22
|
-
@slope = { :r => dr[0], :g => dg[0], :b => db[0] }
|
23
|
-
@offset = { :r => 0, :g => 0, :b => 0 }
|
24
|
-
return
|
25
|
-
end
|
17
|
+
raise "arguments not same length!" unless size == dy.size && size == dz.size
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
sbr += b * r
|
33
|
-
sgb += g * b
|
34
|
-
sr += r
|
35
|
-
sb += g
|
36
|
-
sg += b
|
37
|
-
end
|
38
|
-
|
39
|
-
@slope[:r] = ( @size * srg - sr * sb ) / ( @size * srr - sr ** 2 ).to_f
|
40
|
-
@slope[:g] = ( @size * sgb - sb * sg ) / ( @size * sgg - sb ** 2 ).to_f
|
41
|
-
@slope[:b] = ( @size * sgb - sb * sg ) / ( @size * sbb - sg ** 2 ).to_f
|
19
|
+
if size == 1
|
20
|
+
regression[:slope] = { :x => dx[0], :y => dy[0], :z => dz[0] }
|
21
|
+
regression[:offset] = { :x => 0, :y => 0, :z => 0 }
|
22
|
+
return regression
|
23
|
+
end
|
42
24
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
25
|
+
sxx = syy = szz = sxy = szx = syz = sx = sy = sz = 0
|
26
|
+
dx.zip(dy, dz).each do |x, y, z|
|
27
|
+
sxx += x ** 2
|
28
|
+
syy += y ** 2
|
29
|
+
sxy += x * y
|
30
|
+
szx += z * x
|
31
|
+
syz += y * z
|
32
|
+
sx += x
|
33
|
+
sy += y
|
34
|
+
sz += z
|
48
35
|
end
|
36
|
+
|
37
|
+
regression[:slope][:x] = ( size * sxy - sx * sz ) / ( size * sxx - sx ** 2 ).to_f
|
38
|
+
regression[:slope][:y] = ( size * syz - sz * sy ) / ( size * syy - sz ** 2 ).to_f
|
39
|
+
regression[:slope][:z] = ( size * syz - sz * sy ) / ( size * szz - sy ** 2 ).to_f
|
40
|
+
|
41
|
+
regression[:offset][:x] = (sz - regression[:slope][:x] * sx) / size
|
42
|
+
regression[:offset][:y] = (sy - regression[:slope][:y] * sz) / size
|
43
|
+
regression[:offset][:z] = (sx - regression[:slope][:z] * sy) / size
|
44
|
+
|
45
|
+
regression
|
49
46
|
end
|
50
47
|
end
|
data/lib/paleta/palette.rb
CHANGED
@@ -15,13 +15,19 @@ module Paleta
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def <<(
|
19
|
-
|
18
|
+
def <<(obj)
|
19
|
+
if obj.is_a?(Color)
|
20
|
+
@colors << obj
|
21
|
+
elsif obj.is_a?(Palette)
|
22
|
+
@colors |= obj.colors
|
23
|
+
else
|
24
|
+
raise(ArgumentError, "Passed argument is not a Color")
|
25
|
+
end
|
20
26
|
self
|
21
27
|
end
|
22
28
|
|
23
|
-
def push(
|
24
|
-
self <<
|
29
|
+
def push(obj)
|
30
|
+
self << obj
|
25
31
|
end
|
26
32
|
|
27
33
|
def pop
|
@@ -81,13 +87,13 @@ module Paleta
|
|
81
87
|
(0..1).each { |i| a[i], b[i] = {}, {} }
|
82
88
|
|
83
89
|
# r[i] is the Math::MultipleRegression of the Palette in RGB space
|
84
|
-
r[0] =
|
90
|
+
r[0] = fit
|
85
91
|
r[1] = palette.fit
|
86
|
-
|
92
|
+
|
87
93
|
[0, 1].each do |i|
|
88
|
-
[:
|
89
|
-
a[i][k] = 0 * r[i]
|
90
|
-
b[i][k] = 255 * r[i]
|
94
|
+
[:x, :y, :z].each do |k|
|
95
|
+
a[i][k] = 0 * r[i][:slope][k] + r[i][:offset][k]
|
96
|
+
b[i][k] = 255 * r[i][:slope][k] + r[i][:offset][k]
|
91
97
|
end
|
92
98
|
end
|
93
99
|
|
@@ -105,22 +111,26 @@ module Paleta
|
|
105
111
|
type = opts[:type] || :shades
|
106
112
|
size = opts[:size] || 5
|
107
113
|
case type
|
108
|
-
when :analogous; self.
|
109
|
-
when :
|
110
|
-
when :
|
111
|
-
when :random; self.
|
114
|
+
when :analogous; self.generate_analogous_from_color(color, size)
|
115
|
+
when :complementary; self.generate_complementary_from_color(color, size)
|
116
|
+
when :monochromatic; self.generate_monochromatic_from_color(color, size)
|
117
|
+
when :random; self.generate_random_from_color(color, size)
|
118
|
+
when :shades; self.generate_shades_from_color(color, size)
|
119
|
+
when :split_complement; self.generate_split_complement_from_color(color, size)
|
120
|
+
when :tetrad; self.generate_tetrad_from_color(color, size)
|
121
|
+
when :triad; self.generate_triad_from_color(color, size)
|
112
122
|
else raise(ArgumentError, "Palette type is not defined. Try :analogous, :monochromatic, :shades, or :random")
|
113
123
|
end
|
114
124
|
end
|
115
125
|
|
116
126
|
private
|
117
127
|
|
118
|
-
def self.
|
128
|
+
def self.generate_analogous_from_color(color, size)
|
119
129
|
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
120
130
|
palette = self.new(color)
|
121
131
|
step = 20
|
122
|
-
below = (
|
123
|
-
above = (
|
132
|
+
below = (size / 2)
|
133
|
+
above = (size % 2 == 0) ? (size / 2) - 1: (size / 2)
|
124
134
|
below.times do |i|
|
125
135
|
hue = color.hue - ((i + 1) * step)
|
126
136
|
hue += 360 if hue < 0
|
@@ -134,13 +144,37 @@ module Paleta
|
|
134
144
|
palette.sort! { |a, b| a.hue <=> b.hue }
|
135
145
|
end
|
136
146
|
|
137
|
-
def self.
|
147
|
+
def self.generate_complementary_from_color(color, size)
|
148
|
+
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
149
|
+
complement = color.complement
|
150
|
+
palette = self.new(color, complement)
|
151
|
+
add_monochromatic_in_hues_of_color(palette, color, size)
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.generate_triad_from_color(color, size)
|
155
|
+
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
156
|
+
color2 = Paleta::Color.new(:hsl, (color.hue + 120) % 360, color.saturation, color.lightness)
|
157
|
+
color3 = Paleta::Color.new(:hsl, (color2.hue + 120) % 360, color2.saturation, color2.lightness)
|
158
|
+
palette = self.new(color, color2, color3)
|
159
|
+
add_monochromatic_in_hues_of_color(palette, color, size)
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.generate_tetrad_from_color(color, size)
|
163
|
+
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
164
|
+
color2 = Paleta::Color.new(:hsl, (color.hue + 90) % 360, color.saturation, color.lightness)
|
165
|
+
color3 = Paleta::Color.new(:hsl, (color2.hue + 90) % 360, color2.saturation, color2.lightness)
|
166
|
+
color4 = Paleta::Color.new(:hsl, (color3.hue + 90) % 360, color3.saturation, color3.lightness)
|
167
|
+
palette = self.new(color, color2, color3, color4)
|
168
|
+
add_monochromatic_in_hues_of_color(palette, color, size)
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.generate_monochromatic_from_color(color, size)
|
138
172
|
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
139
173
|
palette = self.new(color)
|
140
|
-
step = (100 /
|
174
|
+
step = (100 / size)
|
141
175
|
saturation = color.saturation
|
142
176
|
d = :down
|
143
|
-
until palette.size ==
|
177
|
+
until palette.size == size
|
144
178
|
saturation -= step if d == :down
|
145
179
|
saturation += step if d == :up
|
146
180
|
palette << Paleta::Color.new(:hsl, color.hue, saturation, color.lightness)
|
@@ -152,13 +186,13 @@ module Paleta
|
|
152
186
|
palette.sort! { |a, b| a.saturation <=> b.saturation }
|
153
187
|
end
|
154
188
|
|
155
|
-
def self.
|
189
|
+
def self.generate_shades_from_color(color, size)
|
156
190
|
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
157
191
|
palette = self.new(color)
|
158
|
-
step = (100 /
|
192
|
+
step = (100 / size)
|
159
193
|
lightness = color.lightness
|
160
194
|
d = :down
|
161
|
-
until palette.size ==
|
195
|
+
until palette.size == size
|
162
196
|
lightness -= step if d == :down
|
163
197
|
lightness += step if d == :up
|
164
198
|
palette << Paleta::Color.new(:hsl, color.hue, color.saturation, lightness)
|
@@ -170,21 +204,50 @@ module Paleta
|
|
170
204
|
palette.sort! { |a, b| a.lightness <=> b.lightness }
|
171
205
|
end
|
172
206
|
|
173
|
-
def self.
|
207
|
+
def self.generate_split_complement_from_color(color, size)
|
208
|
+
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
209
|
+
color2 = Paleta::Color.new(:hsl, (color.hue + 150) % 360, color.saturation, color.lightness)
|
210
|
+
color3 = Paleta::Color.new(:hsl, (color2.hue + 60) % 360, color2.saturation, color2.lightness)
|
211
|
+
palette = self.new(color, color2, color3)
|
212
|
+
add_monochromatic_in_hues_of_color(palette, color, size)
|
213
|
+
end
|
214
|
+
|
215
|
+
def self.generate_random_from_color(color = nil, size)
|
174
216
|
palette = color.is_a?(Color) ? self.new(color) : self.new
|
175
217
|
r = Random.new(Time.now.sec)
|
176
|
-
until palette.size ==
|
218
|
+
until palette.size == size
|
177
219
|
palette << Paleta::Color.new(r.rand(0..255), r.rand(0..255), r.rand(0..255))
|
178
220
|
end
|
179
221
|
palette
|
180
222
|
end
|
181
223
|
|
224
|
+
def self.add_monochromatic_in_hues_of_color(palette, color, size)
|
225
|
+
raise(ArgumentError, "Second argument is not a Color") unless color.is_a?(Color)
|
226
|
+
hues = palette.map { |c| c.hue }
|
227
|
+
step = ugap = dgap = 100 / size
|
228
|
+
i = j = 0
|
229
|
+
saturation = color.saturation
|
230
|
+
until palette.size == size
|
231
|
+
if color.saturation + ugap < 100
|
232
|
+
saturation = color.saturation + ugap
|
233
|
+
ugap += step
|
234
|
+
else
|
235
|
+
saturation = color.saturation - dgap
|
236
|
+
dgap += step
|
237
|
+
end if j == 3 || j == 1
|
238
|
+
new_color = Paleta::Color.new(:hsl, hues[i], saturation, color.lightness)
|
239
|
+
palette << new_color unless palette.include?(new_color)
|
240
|
+
i += 1; j += 1; i %= hues.size; j %= (2 * hues.size)
|
241
|
+
end
|
242
|
+
palette.sort! { |a, b| a.saturation <=> b.saturation }
|
243
|
+
end
|
244
|
+
|
182
245
|
def fit
|
183
246
|
# create a 3xn matrix where n = @colors.size to represent the set of colors
|
184
247
|
reds = @colors.map { |c| c.red }
|
185
248
|
greens = @colors.map { |c| c.green }
|
186
249
|
blues = @colors.map { |c| c.blue }
|
187
|
-
|
250
|
+
multiple_regression(reds, greens, blues)
|
188
251
|
end
|
189
252
|
end
|
190
253
|
end
|
data/lib/paleta/version.rb
CHANGED
data/paleta.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ['iam@jordanstephens.net']
|
7
7
|
gem.description = 'A gem for working with color palettes'
|
8
8
|
gem.summary = 'A little library for creating, manipulating and comparing colors and color palettes'
|
9
|
-
gem.homepage = 'http://
|
9
|
+
gem.homepage = 'http://rubygems.org/gems/paleta'
|
10
10
|
|
11
11
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
12
|
gem.files = `git ls-files`.split("\n")
|
data/readme.markdown
CHANGED
@@ -22,77 +22,97 @@ and run
|
|
22
22
|
|
23
23
|
### Color
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
Paleta allows users to create Color objects. Color objects can be defined by HSL, RGB or HEX values and can be manipulated and compared.
|
26
|
+
|
27
|
+
#### Creating Colors
|
28
|
+
|
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.
|
27
30
|
|
28
|
-
|
31
|
+
color = Paleta::Color.new(:hsl, 280, 37, 68)
|
29
32
|
color = Paleta::Color.new(:rgb, 94, 161, 235)
|
30
|
-
|
31
|
-
# create a Color with a HEX value
|
32
33
|
color = Paleta::Color.new(:hex, "5EA1EB")
|
33
34
|
|
34
35
|
# creating a Color with no flag defaults to RGB components
|
35
36
|
color = Paleta::Color.new(94, 161, 235)
|
36
37
|
|
37
|
-
|
38
|
+
Individual component values can be accessed by name
|
39
|
+
|
38
40
|
color.red # => 94
|
39
41
|
color.green # => 161
|
40
42
|
color.blue # => 235
|
41
|
-
|
42
|
-
# HSL components are maintained too!
|
43
43
|
color.hue # => 211.48936170212767
|
44
44
|
color.saturation # => 77.90055248618782
|
45
45
|
color.lightness # => 64.50980392156862
|
46
|
-
|
47
|
-
# a HEX value is also maintained for each Color
|
48
46
|
color.hex # => "5EA1EB"
|
49
47
|
|
50
|
-
|
48
|
+
#### Manipulating Colors
|
49
|
+
|
50
|
+
Colors can be lightened or darkened by a percentage
|
51
|
+
|
51
52
|
color.lighten!(10)
|
53
|
+
color.darken!(30)
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
# desaturate a Color
|
55
|
+
Colors can be desaturated
|
56
|
+
|
57
57
|
color.desaturate!
|
58
58
|
|
59
|
-
|
59
|
+
Colors can be turned into their complement Colors
|
60
|
+
|
60
61
|
color.complement!
|
61
|
-
|
62
|
-
|
62
|
+
|
63
|
+
Colors can be inverted
|
64
|
+
|
63
65
|
color.invert!
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
**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 `!`.
|
68
|
+
|
69
|
+
For example, lets create a new Color that is the complement of a Color we have already defined.
|
70
|
+
|
71
|
+
new_color = color.complement
|
72
|
+
|
73
|
+
#### Comparing Colors
|
74
|
+
|
75
|
+
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.
|
76
|
+
|
77
|
+
color = Paleta::Color.new(:hsl, 280, 37, 68)
|
68
78
|
color2 = Paleta::Color.new(237, 172, 33)
|
69
|
-
color.similarity(color2) # => 0.
|
79
|
+
color.similarity(color2) # => 0.4100287904421024
|
70
80
|
|
71
81
|
### Palette
|
72
82
|
|
73
|
-
|
83
|
+
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.
|
84
|
+
|
85
|
+
#### Creating a Palette
|
86
|
+
|
87
|
+
Palettes can be created by passing a list of Colors to the Palette constructor, or on the fly with `push` and `<<`.
|
88
|
+
|
74
89
|
color1 = Paleta::Color.new(13, 57, 182)
|
75
90
|
color2 = Paleta::Color.new(94, 161, 235)
|
76
91
|
color3 = Paleta::Color.new(237, 182, 17)
|
77
92
|
palette = Paleta::Palette.new(color1, color2)
|
78
93
|
|
79
|
-
# add Colors to a Palette
|
80
94
|
palette << color3
|
81
95
|
|
82
|
-
|
96
|
+
#### Retrieving and Removing Colors from Palettes
|
97
|
+
|
98
|
+
Colors can be accessed and removed by index.
|
99
|
+
|
83
100
|
palette[1] # => color2
|
84
101
|
|
85
|
-
# remove a Color from a Palette by index
|
86
102
|
palette.delete_at(2)
|
103
|
+
|
104
|
+
#### Manipulating Palettes
|
105
|
+
|
106
|
+
Palettes can be lightened, darkened or inverted as a whole.
|
87
107
|
|
88
|
-
# lighten and darken an entire Palette by a percentage
|
89
108
|
palette.lighten!(15)
|
90
109
|
palette.darken!(20)
|
91
|
-
|
92
|
-
# invert each color in a Palette
|
93
110
|
palette.invert!
|
94
111
|
|
95
|
-
|
112
|
+
#### Comparing Palettes
|
113
|
+
|
114
|
+
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.
|
115
|
+
|
96
116
|
color1 = Paleta::Color.new(13, 57, 182)
|
97
117
|
color2 = Paleta::Color.new(237, 172, 33)
|
98
118
|
palette1 = Paleta::Palette.new(color1, color2)
|
@@ -101,25 +121,53 @@ and run
|
|
101
121
|
color4 = Paleta::Color.new(94, 161, 235)
|
102
122
|
palette2 = Paleta::Palette.new(color3, color4)
|
103
123
|
|
104
|
-
# Palette#similarity calculates the similarity between two Palettes and returns a
|
105
|
-
# value in 0..1, with 0 being identical and 1 being as dissimilar as possible
|
106
124
|
palette1.similarity(palette2) # => 0.0046992695975874915
|
107
125
|
|
108
|
-
|
126
|
+
#### Generating Palettes
|
127
|
+
|
128
|
+
Palettes can be generated from a "seed" Color by using the `generate` method.
|
129
|
+
|
130
|
+
**Generate a random Palette**
|
131
|
+
|
109
132
|
palette = Paleta::Palette.generate(:type => :random, :size = 5)
|
110
133
|
|
111
|
-
|
134
|
+
**Generate a Palette of shades from a Color**
|
135
|
+
|
112
136
|
color = Paleta::Color.new(:hex, "ff0000")
|
113
137
|
palette = Paleta::Palette.generate(:type => :shades, :from => color, :size => 5)
|
114
138
|
|
115
|
-
|
139
|
+
**Generate a Palette of analogous Colors from a Color**
|
140
|
+
|
116
141
|
color = Paleta::Color.new(:hex, "0066cc")
|
117
142
|
palette = Paleta::Palette.generate(:type => :analogous, :from => color, :size => 5)
|
118
143
|
|
119
|
-
|
144
|
+
**Generate a Palette of monochromatic Colors from a Color**
|
145
|
+
|
120
146
|
color = Paleta::Color.new(:hex, "336699")
|
121
147
|
palette = Paleta::Palette.generate(:type => :monochromatic, :from => color, :size => 5)
|
122
148
|
|
149
|
+
**Generate a Palette of complementary Colors from a Color**
|
150
|
+
|
151
|
+
color = Paleta::Color.new(:hex, "0000ff")
|
152
|
+
palette = Paleta::Palette.generate(:type => :complementary, :from => color, :size => 5)
|
153
|
+
|
154
|
+
**Generate a Palette of split-complement Colors from a Color**
|
155
|
+
|
156
|
+
color = Paleta::Color.new(:hex, "006699")
|
157
|
+
palette = Paleta::Palette.generate(:type => :split_complement, :from => color, :size => 5)
|
158
|
+
|
159
|
+
**Generate a Palette of triad Colors from a Color**
|
160
|
+
|
161
|
+
color = Paleta::Color.new(:hex, "006699")
|
162
|
+
palette = Paleta::Palette.generate(:type => :triad, :from => color, :size => 5)
|
163
|
+
|
164
|
+
**Generate a Palette of tetrad Colors from a Color**
|
165
|
+
|
166
|
+
color = Paleta::Color.new(:hex, "dd5533")
|
167
|
+
palette = Paleta::Palette.generate(:type => :tetrad, :from => color, :size => 5)
|
168
|
+
|
169
|
+
***
|
170
|
+
|
123
171
|
See the [documentation](http://rubydoc.info/gems/paleta/ "Documentation").
|
124
172
|
|
125
173
|
|
data/spec/models/color_spec.rb
CHANGED
@@ -57,6 +57,16 @@ describe Paleta::Color do
|
|
57
57
|
expect{ Paleta::Color.new(:hsl, 200, 50, 150) }.to raise_error(ArgumentError)
|
58
58
|
end
|
59
59
|
|
60
|
+
it "should determine its equality to another Color" do
|
61
|
+
color1 = Paleta::Color.new(237, 172, 33)
|
62
|
+
color2 = Paleta::Color.new(:hex, "EDAC21")
|
63
|
+
(color1 == color2).should be_true
|
64
|
+
color3 = Paleta::Color.new(:hsl, 200, 50, 100)
|
65
|
+
(color1 == color3).should be_false
|
66
|
+
obj = Object.new
|
67
|
+
(color1 == obj).should be_false
|
68
|
+
end
|
69
|
+
|
60
70
|
it "should calculate its HSL value on itialization" do
|
61
71
|
color = Paleta::Color.new(237, 172, 33)
|
62
72
|
color.hue.to_i.should == 40
|
@@ -193,13 +203,13 @@ describe Paleta::Color do
|
|
193
203
|
it "should become its complement" do
|
194
204
|
color = Paleta::Color.new(:hsl, 90, 50, 50)
|
195
205
|
color.complement!
|
196
|
-
color.hue.should == 270
|
206
|
+
color.hue.to_i.should == 270
|
197
207
|
end
|
198
208
|
|
199
209
|
it "should return its complement Color" do
|
200
210
|
color = Paleta::Color.new(:hsl, 90, 50, 50)
|
201
211
|
complement = color.complement
|
202
|
-
complement.hue.should == 270
|
212
|
+
complement.hue.to_i.should == 270
|
203
213
|
end
|
204
214
|
|
205
215
|
it "should calculate its similarity to another Color" do
|
data/spec/models/palette_spec.rb
CHANGED
@@ -99,12 +99,12 @@ describe Paleta::Palette do
|
|
99
99
|
c3 = Paleta::Color.new(237, 172, 33)
|
100
100
|
palette = Paleta::Palette.new(c1, c2, c3)
|
101
101
|
r = palette.fit
|
102
|
-
r
|
103
|
-
r
|
104
|
-
r
|
105
|
-
r
|
106
|
-
r
|
107
|
-
r
|
102
|
+
r[:slope][:x].should == 0.19585157930194594
|
103
|
+
r[:slope][:y].should == 0.5276697919048708
|
104
|
+
r[:slope][:z].should == 0.09102564102564102
|
105
|
+
r[:offset][:x].should == 127.54235224004354
|
106
|
+
r[:offset][:y].should == 50.849531214269376
|
107
|
+
r[:offset][:z].should == 102.83333333333333
|
108
108
|
end
|
109
109
|
|
110
110
|
it "should calculate its similarity to another Palette" do
|
@@ -132,17 +132,17 @@ describe Paleta::Palette do
|
|
132
132
|
c9 = Paleta::Color.new(13, 57, 182)
|
133
133
|
c10 = Paleta::Color.new(94, 161, 235)
|
134
134
|
p6 = Paleta::Palette.new(c9, c10)
|
135
|
-
p5.similarity(p6).round(5).should == 0.
|
135
|
+
p5.similarity(p6).round(5).should == 0.00627
|
136
136
|
end
|
137
137
|
|
138
138
|
it "should generate a new Palette of shades of a single Color" do
|
139
139
|
color = Paleta::Color.new(:hex, "ff0000")
|
140
140
|
palette = Paleta::Palette.generate(:from => color, :size => 5)
|
141
|
+
palette.size.should == 5
|
141
142
|
palette.each do |p|
|
142
143
|
p.hue.should == color.hue
|
143
144
|
p.saturation.should == color.saturation
|
144
145
|
end
|
145
|
-
|
146
146
|
palette[0].lightness.should == 10
|
147
147
|
palette[1].lightness.should == 30
|
148
148
|
palette[2].lightness.should == 50
|
@@ -153,6 +153,7 @@ describe Paleta::Palette do
|
|
153
153
|
it "should generate a new Palette of Colors analogous to the seed Color" do
|
154
154
|
color = Paleta::Color.new(:hex, "0066cc")
|
155
155
|
palette = Paleta::Palette.generate(:type => :analogous, :from => color, :size => 5)
|
156
|
+
palette.size.should == 5
|
156
157
|
palette.each do |p|
|
157
158
|
p.lightness.should == color.lightness
|
158
159
|
p.saturation.should == color.saturation
|
@@ -167,6 +168,7 @@ describe Paleta::Palette do
|
|
167
168
|
it "should generate a new Palette of Colors monochromatic to the seed Color" do
|
168
169
|
color = Paleta::Color.new(:hex, "0066cc")
|
169
170
|
palette = Paleta::Palette.generate(:type => :monochromatic, :from => color, :size => 5)
|
171
|
+
palette.size.should == 5
|
170
172
|
palette.each do |p|
|
171
173
|
p.hue.should == color.hue
|
172
174
|
p.lightness.should == color.lightness
|
@@ -176,11 +178,50 @@ describe Paleta::Palette do
|
|
176
178
|
palette[2].saturation.should == 60
|
177
179
|
palette[3].saturation.should == 80
|
178
180
|
palette[4].saturation.should == 100
|
179
|
-
|
180
181
|
end
|
181
182
|
|
182
183
|
it "should generate a new Palette of random Colors" do
|
183
184
|
palette = Paleta::Palette.generate(:type => :random, :size => 5)
|
184
185
|
palette.size.should == 5
|
185
186
|
end
|
187
|
+
|
188
|
+
it "should generate a new complementary Palette from the seed Color" do
|
189
|
+
color = Paleta::Color.new(:hex, "0066cc")
|
190
|
+
palette = Paleta::Palette.generate(:type => :complementary, :from => color, :size => 5)
|
191
|
+
palette.size.should == 5
|
192
|
+
palette.each do |c|
|
193
|
+
c.lightness.should == color.lightness
|
194
|
+
[color.hue, color.complement.hue].include?(c.hue).should be_true
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should generate a new triad Palette from the seed Color" do
|
199
|
+
color = Paleta::Color.new(:hex, "0066cc")
|
200
|
+
palette = Paleta::Palette.generate(:type => :triad, :from => color, :size => 5)
|
201
|
+
palette.size.should == 5
|
202
|
+
palette.each do |c|
|
203
|
+
c.lightness.should == color.lightness
|
204
|
+
[color.hue, (color.hue + 120) % 360, (color.hue + 240) % 360].include?(c.hue).should be_true
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should generate a new tetrad Palette from the seed Color" do
|
209
|
+
color = Paleta::Color.new(:hex, "0066cc")
|
210
|
+
palette = Paleta::Palette.generate(:type => :tetrad, :from => color, :size => 5)
|
211
|
+
palette.size.should == 5
|
212
|
+
palette.each do |c|
|
213
|
+
c.lightness.should == color.lightness
|
214
|
+
[color.hue, (color.hue + 90) % 360, (color.hue + 180) % 360, (color.hue + 270) % 360].include?(c.hue).should be_true
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should generate a new split-complement Palette from the seed Color" do
|
219
|
+
color = Paleta::Color.new(:hex, "0066cc")
|
220
|
+
palette = Paleta::Palette.generate(:type => :split_complement, :from => color, :size => 5)
|
221
|
+
palette.size.should == 5
|
222
|
+
palette.each do |c|
|
223
|
+
c.lightness.should == color.lightness
|
224
|
+
[color.hue, (color.hue + 150) % 360, (color.hue + 210) % 360].include?(c.hue).should be_true
|
225
|
+
end
|
226
|
+
end
|
186
227
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paleta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-20 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: A gem for working with color palettes
|
15
15
|
email:
|
@@ -31,7 +31,7 @@ files:
|
|
31
31
|
- spec/models/color_spec.rb
|
32
32
|
- spec/models/palette_spec.rb
|
33
33
|
- spec/spec_helper.rb
|
34
|
-
homepage: http://
|
34
|
+
homepage: http://rubygems.org/gems/paleta
|
35
35
|
licenses: []
|
36
36
|
post_install_message:
|
37
37
|
rdoc_options: []
|