paleta 0.0.4 → 0.0.5
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.
- 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: []
|