paleta 0.0.3 → 0.0.4
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/lib/paleta/color.rb +90 -48
- data/lib/paleta/palette.rb +99 -2
- data/lib/paleta/version.rb +1 -1
- data/readme.markdown +41 -15
- data/spec/models/color_spec.rb +102 -18
- data/spec/models/palette_spec.rb +53 -2
- metadata +2 -2
data/lib/paleta/color.rb
CHANGED
@@ -8,11 +8,21 @@ module Paleta
|
|
8
8
|
|
9
9
|
def initialize(*args)
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
if args.length == 1 && args[0].is_a?(Color)
|
12
|
+
# TODO: refactor this, find out how to call a method name by the value of a variable
|
13
|
+
# something like args[0].instance_variables.each { |k, v| self.(k) = v }
|
14
|
+
@red = args[0].red
|
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
|
21
|
+
elsif args.length == 2 && args[0] == :hex && args[1].is_a?(String)
|
22
|
+
# example: new(:hex, "336699")
|
13
23
|
hex_init(args[1])
|
14
|
-
# example: new(235, 129, 74)
|
15
24
|
elsif args.length == 3 && args[0].is_a?(Numeric) && args[1].is_a?(Numeric) && args[2].is_a?(Numeric)
|
25
|
+
# example: new(235, 129, 74)
|
16
26
|
rgb_init(args[0], args[1], args[2])
|
17
27
|
elsif args.length == 4 && [:rgb, :hsl].include?(args[0]) && args[1].is_a?(Numeric) && args[2].is_a?(Numeric) && args[3].is_a?(Numeric)
|
18
28
|
# example: new(:hsl, 320, 96, 74)
|
@@ -80,9 +90,7 @@ module Paleta
|
|
80
90
|
end
|
81
91
|
|
82
92
|
def hex=(val)
|
83
|
-
unless val.length == 6 && /^[[:xdigit:]]+$/ === val
|
84
|
-
raise(ArgumentError, "Invalid Hex String")
|
85
|
-
end
|
93
|
+
raise(ArgumentError, "Invalid Hex String") unless val.length == 6 && /^[[:xdigit:]]+$/ === val
|
86
94
|
@hex = val.upcase
|
87
95
|
@red = val[0..1].hex
|
88
96
|
@green = val[2..3].hex
|
@@ -90,6 +98,12 @@ module Paleta
|
|
90
98
|
update_hsl
|
91
99
|
end
|
92
100
|
|
101
|
+
def lighten(percent = 5)
|
102
|
+
copy = self.class.new(self)
|
103
|
+
copy.lighten!(percent)
|
104
|
+
return copy
|
105
|
+
end
|
106
|
+
|
93
107
|
def lighten!(percent = 5)
|
94
108
|
@lightness += percent
|
95
109
|
@lightness = 100 if @lightness > 100
|
@@ -97,6 +111,12 @@ module Paleta
|
|
97
111
|
update_hex
|
98
112
|
end
|
99
113
|
|
114
|
+
def darken(percent = 5)
|
115
|
+
copy = self.class.new(self)
|
116
|
+
copy.darken!(percent)
|
117
|
+
return copy
|
118
|
+
end
|
119
|
+
|
100
120
|
def darken!(percent = 5)
|
101
121
|
@lightness -= percent
|
102
122
|
@lightness = 0 if @lightness < 0
|
@@ -104,6 +124,12 @@ module Paleta
|
|
104
124
|
update_hex
|
105
125
|
end
|
106
126
|
|
127
|
+
def invert
|
128
|
+
copy = self.class.new(self)
|
129
|
+
copy.invert!
|
130
|
+
return copy
|
131
|
+
end
|
132
|
+
|
107
133
|
def invert!
|
108
134
|
@red = 255 - @red
|
109
135
|
@green = 255 - @green
|
@@ -112,6 +138,30 @@ module Paleta
|
|
112
138
|
update_hex
|
113
139
|
end
|
114
140
|
|
141
|
+
def desaturate
|
142
|
+
copy = self.class.new(self)
|
143
|
+
copy.desaturate!
|
144
|
+
return copy
|
145
|
+
end
|
146
|
+
|
147
|
+
def desaturate!
|
148
|
+
@saturation = 0
|
149
|
+
update_rgb
|
150
|
+
update_hex
|
151
|
+
end
|
152
|
+
|
153
|
+
def complement
|
154
|
+
copy = self.class.new(self)
|
155
|
+
copy.complement!
|
156
|
+
return copy
|
157
|
+
end
|
158
|
+
|
159
|
+
def complement!
|
160
|
+
@hue = (@hue + 180) % 360
|
161
|
+
update_rgb
|
162
|
+
update_hex
|
163
|
+
end
|
164
|
+
|
115
165
|
def similarity(color)
|
116
166
|
distance({ :r => @red, :g => @green, :b => @blue}, { :r => color.red, :g => color.green, :b => color.blue}) / sqrt(3 * (255 ** 2))
|
117
167
|
end
|
@@ -122,22 +172,23 @@ module Paleta
|
|
122
172
|
r = @red / 255.0 rescue 0.0
|
123
173
|
g = @green / 255.0 rescue 0.0
|
124
174
|
b = @blue / 255.0 rescue 0.0
|
125
|
-
|
175
|
+
|
126
176
|
min = [r, g, b].min
|
127
177
|
max = [r, g, b].max
|
128
178
|
delta = max - min
|
129
179
|
|
130
|
-
h =
|
180
|
+
h = 0
|
131
181
|
l = (max + min) / 2.0
|
132
|
-
|
182
|
+
s = ((l == 0 || l == 1) ? 0 : (delta / (1 - (2 * l - 1).abs)))
|
183
|
+
|
133
184
|
if delta != 0
|
134
|
-
s = (l < 0.5) ? delta / (max + min) : delta / (2.0 - max - min)
|
135
185
|
case max
|
136
|
-
when r; h = (g - b) / delta
|
137
|
-
when g; h =
|
138
|
-
when b; h =
|
186
|
+
when r; h = ((g - b) / delta) % 6
|
187
|
+
when g; h = ((b - r) / delta) + 2
|
188
|
+
when b; h = ((r - g) / delta) + 4
|
139
189
|
end
|
140
190
|
end
|
191
|
+
|
141
192
|
@hue = h * 60
|
142
193
|
@hue += 360 if @hue < 0
|
143
194
|
@saturation = s * 100
|
@@ -145,49 +196,40 @@ module Paleta
|
|
145
196
|
end
|
146
197
|
|
147
198
|
def update_rgb
|
199
|
+
|
200
|
+
h = @hue / 60.0 rescue 0.0
|
201
|
+
s = @saturation / 100.0 rescue 0.0
|
202
|
+
l = @lightness / 100.0 rescue 0.0
|
203
|
+
|
204
|
+
d1 = (1 - (2 * l - 1).abs) * s
|
205
|
+
d2 = d1 * (1 - (h % 2 - 1).abs)
|
206
|
+
d3 = l - (d1 / 2.0)
|
148
207
|
|
149
|
-
h
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
t2 = l < 0.5 ? l * (s + 1) : (l + s) - (l * s)
|
158
|
-
t1 = 2 * l - t2
|
159
|
-
|
160
|
-
r = h + (1.0 / 3.0)
|
161
|
-
g = h
|
162
|
-
b = h - (1.0 / 3.0)
|
163
|
-
|
164
|
-
r = hue_calc(r, t1, t2)
|
165
|
-
g = hue_calc(g, t1, t2)
|
166
|
-
b = hue_calc(b, t1, t2)
|
167
|
-
|
168
|
-
@red = r * 255.0
|
169
|
-
@green = g * 255.0
|
170
|
-
@blue = b * 255.0
|
208
|
+
case h.to_i
|
209
|
+
when 0; @red, @green, @blue = d1, d2, 0
|
210
|
+
when 1; @red, @green, @blue = d2, d1, 0
|
211
|
+
when 2; @red, @green, @blue = 0, d1, d2
|
212
|
+
when 3; @red, @green, @blue = 0, d2, d1
|
213
|
+
when 4; @red, @green, @blue = d2, 0, d1
|
214
|
+
when 5; @red, @green, @blue = d1, 0, d2
|
215
|
+
else; @red, @green, @blue = 0, 0, 0
|
171
216
|
end
|
217
|
+
|
218
|
+
@red = 255 * (@red + d3)
|
219
|
+
@green = 255 * (@green + d3)
|
220
|
+
@blue = 255 * (@blue + d3)
|
172
221
|
end
|
173
222
|
|
174
223
|
def update_hex
|
175
|
-
r = @red.to_s(16) rescue "00"
|
176
|
-
g = @green.to_s(16) rescue "00"
|
177
|
-
b = @blue.to_s(16) rescue "00"
|
178
|
-
|
224
|
+
r = @red.to_i.to_s(16) rescue "00"
|
225
|
+
g = @green.to_i.to_s(16) rescue "00"
|
226
|
+
b = @blue.to_i.to_s(16) rescue "00"
|
227
|
+
r = "0#{r}" if r.length < 2
|
228
|
+
g = "0#{g}" if g.length < 2
|
229
|
+
b = "0#{b}" if b.length < 2
|
179
230
|
@hex = "#{r}#{g}#{b}".upcase
|
180
231
|
end
|
181
232
|
|
182
|
-
def hue_calc(value, t1, t2)
|
183
|
-
value += 1 if value < 0
|
184
|
-
value -= 1 if value > 1
|
185
|
-
return (t1 + (t2 - t1) * 6 * value) if 6 * value < 1
|
186
|
-
return t2 if 2 * value < 1
|
187
|
-
return (t1 + (t2 - t1) * (2.0 / 3.0 - value) * 6) if 3 * value < 2
|
188
|
-
return t1;
|
189
|
-
end
|
190
|
-
|
191
233
|
def range_validator(val, range)
|
192
234
|
range.include?(val) ? val : raise(ArgumentError, "Component range exceeded")
|
193
235
|
end
|
data/lib/paleta/palette.rb
CHANGED
@@ -3,11 +3,13 @@ require 'paleta/core_ext/math'
|
|
3
3
|
module Paleta
|
4
4
|
class Palette
|
5
5
|
include Math
|
6
|
+
include Enumerable
|
6
7
|
|
7
8
|
attr_accessor :colors
|
8
9
|
|
9
|
-
def initialize(*
|
10
|
+
def initialize(*args)
|
10
11
|
@colors = []
|
12
|
+
colors = (args.length == 1 && args[0].is_a?(Array)) ? args[0] : args
|
11
13
|
colors.each do |color|
|
12
14
|
self << color
|
13
15
|
end
|
@@ -15,6 +17,7 @@ module Paleta
|
|
15
17
|
|
16
18
|
def <<(color)
|
17
19
|
color.is_a?(Color) ? @colors << color : raise(ArgumentError, "Passed argument is not a Color")
|
20
|
+
self
|
18
21
|
end
|
19
22
|
|
20
23
|
def push(color)
|
@@ -37,6 +40,20 @@ module Paleta
|
|
37
40
|
@colors.size
|
38
41
|
end
|
39
42
|
|
43
|
+
def each
|
44
|
+
@colors.each { |c| yield c }
|
45
|
+
end
|
46
|
+
|
47
|
+
def sort &blk
|
48
|
+
@colors.sort &blk
|
49
|
+
Paleta::Palette.new(@colors)
|
50
|
+
end
|
51
|
+
|
52
|
+
def sort! &blk
|
53
|
+
@colors.sort! &blk
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
40
57
|
def include?(color)
|
41
58
|
@colors.include?(color)
|
42
59
|
end
|
@@ -81,7 +98,87 @@ module Paleta
|
|
81
98
|
|
82
99
|
d1 + d2
|
83
100
|
end
|
84
|
-
|
101
|
+
|
102
|
+
def self.generate(opts = {})
|
103
|
+
raise(ArgumentError, "Pass a Color using :from, generate( :from => Color )") if opts.empty?
|
104
|
+
color = opts[:from]
|
105
|
+
type = opts[:type] || :shades
|
106
|
+
size = opts[:size] || 5
|
107
|
+
case type
|
108
|
+
when :analogous; self.generate_analogous_palette_from_color(color, size)
|
109
|
+
when :monochromatic; self.generate_monochromatic_palette_from_color(color, size)
|
110
|
+
when :shades; self.generate_shades_palette_from_color(color, size)
|
111
|
+
when :random; self.generate_random_palette_from_color(color, size)
|
112
|
+
else raise(ArgumentError, "Palette type is not defined. Try :analogous, :monochromatic, :shades, or :random")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def self.generate_analogous_palette_from_color(color, n)
|
119
|
+
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
120
|
+
palette = self.new(color)
|
121
|
+
step = 20
|
122
|
+
below = (n / 2)
|
123
|
+
above = (n % 2 == 0) ? (n / 2) - 1: (n / 2)
|
124
|
+
below.times do |i|
|
125
|
+
hue = color.hue - ((i + 1) * step)
|
126
|
+
hue += 360 if hue < 0
|
127
|
+
palette << Paleta::Color.new(:hsl, hue, color.saturation, color.lightness)
|
128
|
+
end
|
129
|
+
above.times do |i|
|
130
|
+
hue = color.hue + ((i + 1) * step)
|
131
|
+
hue -= 360 if hue > 360
|
132
|
+
palette << Paleta::Color.new(:hsl, hue, color.saturation, color.lightness)
|
133
|
+
end
|
134
|
+
palette.sort! { |a, b| a.hue <=> b.hue }
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.generate_monochromatic_palette_from_color(color, n)
|
138
|
+
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
139
|
+
palette = self.new(color)
|
140
|
+
step = (100 / n)
|
141
|
+
saturation = color.saturation
|
142
|
+
d = :down
|
143
|
+
until palette.size == n
|
144
|
+
saturation -= step if d == :down
|
145
|
+
saturation += step if d == :up
|
146
|
+
palette << Paleta::Color.new(:hsl, color.hue, saturation, color.lightness)
|
147
|
+
if saturation - step < 0
|
148
|
+
d = :up
|
149
|
+
saturation = color.saturation
|
150
|
+
end
|
151
|
+
end
|
152
|
+
palette.sort! { |a, b| a.saturation <=> b.saturation }
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.generate_shades_palette_from_color(color, n)
|
156
|
+
raise(ArgumentError, "Passed argument is not a Color") unless color.is_a?(Color)
|
157
|
+
palette = self.new(color)
|
158
|
+
step = (100 / n)
|
159
|
+
lightness = color.lightness
|
160
|
+
d = :down
|
161
|
+
until palette.size == n
|
162
|
+
lightness -= step if d == :down
|
163
|
+
lightness += step if d == :up
|
164
|
+
palette << Paleta::Color.new(:hsl, color.hue, color.saturation, lightness)
|
165
|
+
if lightness - step < 0
|
166
|
+
d = :up
|
167
|
+
lightness = color.lightness
|
168
|
+
end
|
169
|
+
end
|
170
|
+
palette.sort! { |a, b| a.lightness <=> b.lightness }
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.generate_random_palette_from_color(color = nil, n)
|
174
|
+
palette = color.is_a?(Color) ? self.new(color) : self.new
|
175
|
+
r = Random.new(Time.now.sec)
|
176
|
+
until palette.size == n
|
177
|
+
palette << Paleta::Color.new(r.rand(0..255), r.rand(0..255), r.rand(0..255))
|
178
|
+
end
|
179
|
+
palette
|
180
|
+
end
|
181
|
+
|
85
182
|
def fit
|
86
183
|
# create a 3xn matrix where n = @colors.size to represent the set of colors
|
87
184
|
reds = @colors.map { |c| c.red }
|
data/lib/paleta/version.rb
CHANGED
data/readme.markdown
CHANGED
@@ -22,16 +22,16 @@ and run
|
|
22
22
|
|
23
23
|
### Color
|
24
24
|
|
25
|
-
# create a
|
25
|
+
# create a Color with HSL components
|
26
26
|
color = Paleta::Color.new(:hsl, 280, 37, 68)
|
27
27
|
|
28
|
-
# create a
|
28
|
+
# create a Color with RGB components
|
29
29
|
color = Paleta::Color.new(:rgb, 94, 161, 235)
|
30
30
|
|
31
|
-
# create a
|
31
|
+
# create a Color with a HEX value
|
32
32
|
color = Paleta::Color.new(:hex, "5EA1EB")
|
33
33
|
|
34
|
-
# creating a
|
34
|
+
# creating a Color with no flag defaults to RGB components
|
35
35
|
color = Paleta::Color.new(94, 161, 235)
|
36
36
|
|
37
37
|
# access component values
|
@@ -53,11 +53,17 @@ and run
|
|
53
53
|
# darken by a percentage
|
54
54
|
color.darken!(10)
|
55
55
|
|
56
|
-
#
|
56
|
+
# desaturate a Color
|
57
|
+
color.desaturate!
|
58
|
+
|
59
|
+
# convert a Color into its complement
|
60
|
+
color.complement!
|
61
|
+
|
62
|
+
# invert a Color
|
57
63
|
color.invert!
|
58
64
|
|
59
65
|
# calculate similarity between Colors
|
60
|
-
# Color#similarity calculates the similarity between two
|
66
|
+
# Color#similarity calculates the similarity between two Colors and returns a
|
61
67
|
# value in 0..1, with 0 being identical and 1 being as dissimilar as possible
|
62
68
|
color2 = Paleta::Color.new(237, 172, 33)
|
63
69
|
color.similarity(color2) # => 0.5609077061558945
|
@@ -68,8 +74,11 @@ and run
|
|
68
74
|
color1 = Paleta::Color.new(13, 57, 182)
|
69
75
|
color2 = Paleta::Color.new(94, 161, 235)
|
70
76
|
color3 = Paleta::Color.new(237, 182, 17)
|
71
|
-
palette = Paleta::Palette.new(color1, color2
|
72
|
-
|
77
|
+
palette = Paleta::Palette.new(color1, color2)
|
78
|
+
|
79
|
+
# add Colors to a Palette
|
80
|
+
palette << color3
|
81
|
+
|
73
82
|
# retreive a Color from a Palette
|
74
83
|
palette[1] # => color2
|
75
84
|
|
@@ -84,16 +93,33 @@ and run
|
|
84
93
|
palette.invert!
|
85
94
|
|
86
95
|
# calculate similarity of two Palettes
|
87
|
-
|
88
|
-
|
89
|
-
palette1 = Paleta::Palette.new(
|
96
|
+
color1 = Paleta::Color.new(13, 57, 182)
|
97
|
+
color2 = Paleta::Color.new(237, 172, 33)
|
98
|
+
palette1 = Paleta::Palette.new(color1, color2)
|
90
99
|
|
91
|
-
|
92
|
-
|
93
|
-
palette2 = Paleta::Palette.new(
|
94
|
-
|
100
|
+
color3 = Paleta::Color.new(13, 57, 182)
|
101
|
+
color4 = Paleta::Color.new(94, 161, 235)
|
102
|
+
palette2 = Paleta::Palette.new(color3, color4)
|
103
|
+
|
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
|
95
106
|
palette1.similarity(palette2) # => 0.0046992695975874915
|
96
107
|
|
108
|
+
# generate random Palette
|
109
|
+
palette = Paleta::Palette.generate(:type => :random, :size = 5)
|
110
|
+
|
111
|
+
# generate a Palette of shades from a Color
|
112
|
+
color = Paleta::Color.new(:hex, "ff0000")
|
113
|
+
palette = Paleta::Palette.generate(:type => :shades, :from => color, :size => 5)
|
114
|
+
|
115
|
+
# generate a Palette of Colors analogous to the seed Color
|
116
|
+
color = Paleta::Color.new(:hex, "0066cc")
|
117
|
+
palette = Paleta::Palette.generate(:type => :analogous, :from => color, :size => 5)
|
118
|
+
|
119
|
+
# generate a Palette of Colors monochromatic to the seed Color
|
120
|
+
color = Paleta::Color.new(:hex, "336699")
|
121
|
+
palette = Paleta::Palette.generate(:type => :monochromatic, :from => color, :size => 5)
|
122
|
+
|
97
123
|
See the [documentation](http://rubydoc.info/gems/paleta/ "Documentation").
|
98
124
|
|
99
125
|
|
data/spec/models/color_spec.rb
CHANGED
@@ -16,10 +16,14 @@ describe Paleta::Color do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should initialize with the :hsl flag, hue in 0..360, and saturation and lightness in 0..100" do
|
19
|
-
color = Paleta::Color.new(:hsl,
|
20
|
-
color.hue.should ==
|
21
|
-
color.saturation.should ==
|
22
|
-
color.lightness.should ==
|
19
|
+
color = Paleta::Color.new(:hsl, 0, 0, 100)
|
20
|
+
color.hue.should == 0
|
21
|
+
color.saturation.should == 0
|
22
|
+
color.lightness.should == 100
|
23
|
+
color.red.should == 255
|
24
|
+
color.green.should == 255
|
25
|
+
color.blue.should == 255
|
26
|
+
color.hex.should == "FFFFFF"
|
23
27
|
end
|
24
28
|
|
25
29
|
it "should initialize with the :rgb flag with RGB components in 0..255" do
|
@@ -29,8 +33,28 @@ describe Paleta::Color do
|
|
29
33
|
color.blue.should == 235
|
30
34
|
end
|
31
35
|
|
32
|
-
it "should
|
33
|
-
expect{ Paleta::Color.new(
|
36
|
+
it "should raise an error on an invalid format flag" do
|
37
|
+
expect{ Paleta::Color.new(:something, 50, 50, 50) }.to raise_error(ArgumentError)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should raise an error on an invalid hex string" do
|
41
|
+
expect{ Paleta::Color.new(:hex, "xkfjs") }.to raise_error(ArgumentError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise an error on RGB components not in 0..255" do
|
45
|
+
expect{ Paleta::Color.new(-74, 333, 4321) }.to raise_error(ArgumentError)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should raise an error on hue not in 0..360" do
|
49
|
+
expect{ Paleta::Color.new(:hsl, 400, 50, 50) }.to raise_error(ArgumentError)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should raise an error on saturation not in 0..100" do
|
53
|
+
expect{ Paleta::Color.new(:hsl, 200, 150, 50) }.to raise_error(ArgumentError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should raise an error on lightness not in 0..100" do
|
57
|
+
expect{ Paleta::Color.new(:hsl, 200, 50, 150) }.to raise_error(ArgumentError)
|
34
58
|
end
|
35
59
|
|
36
60
|
it "should calculate its HSL value on itialization" do
|
@@ -50,9 +74,9 @@ describe Paleta::Color do
|
|
50
74
|
|
51
75
|
color.green = 123
|
52
76
|
color.hue.to_i.should == 136
|
53
|
-
color.saturation.to_i.should ==
|
77
|
+
color.saturation.to_i.should == 99
|
54
78
|
color.lightness.to_i.should == 24
|
55
|
-
|
79
|
+
|
56
80
|
color.blue = 241
|
57
81
|
color.hue.to_i.should == 209
|
58
82
|
color.saturation.to_i.should == 100
|
@@ -61,24 +85,23 @@ describe Paleta::Color do
|
|
61
85
|
|
62
86
|
it "should update its RGB value when its HSL value is updated" do
|
63
87
|
color = Paleta::Color.new(0, 0, 255)
|
64
|
-
|
65
88
|
color.hue = 120
|
66
|
-
color.red.to_i.should ==
|
67
|
-
color.green.to_i.should ==
|
89
|
+
color.red.to_i.should == 0
|
90
|
+
color.green.to_i.should == 255
|
68
91
|
color.blue.to_i.should == 0
|
69
92
|
|
70
93
|
color.saturation = 50
|
71
|
-
color.red.to_i.should ==
|
72
|
-
color.green.to_i.should ==
|
94
|
+
color.red.to_i.should == 63
|
95
|
+
color.green.to_i.should == 191
|
73
96
|
color.blue.to_i.should == 63
|
74
|
-
|
97
|
+
|
75
98
|
color.lightness = 80
|
76
|
-
color.red.to_i.should ==
|
77
|
-
color.green.to_i.should ==
|
99
|
+
color.red.to_i.should == 178
|
100
|
+
color.green.to_i.should == 229
|
78
101
|
color.blue.to_i.should == 178
|
79
102
|
end
|
80
103
|
|
81
|
-
it "should lighten by a percentage
|
104
|
+
it "should lighten itself by a percentage" do
|
82
105
|
color = Paleta::Color.new(94, 161, 235)
|
83
106
|
lightness = color.lightness
|
84
107
|
color.lighten!
|
@@ -88,6 +111,14 @@ describe Paleta::Color do
|
|
88
111
|
color.lightness.should == lightness + 20
|
89
112
|
end
|
90
113
|
|
114
|
+
it "should return a copy of itself, lightened by a percentage" do
|
115
|
+
color = Paleta::Color.new(94, 161, 235)
|
116
|
+
lightness = color.lightness
|
117
|
+
copy = color.lighten(20)
|
118
|
+
copy.lightness.should == lightness + 20
|
119
|
+
color.lightness.should == lightness
|
120
|
+
end
|
121
|
+
|
91
122
|
it "should quietly maintain a maximum of 100 when lightening" do
|
92
123
|
color = Paleta::Color.new(94, 161, 235)
|
93
124
|
color.lighten!(300)
|
@@ -104,6 +135,14 @@ describe Paleta::Color do
|
|
104
135
|
color.lightness.should == lightness - 20
|
105
136
|
end
|
106
137
|
|
138
|
+
it "should return a copy of itself, darkened by a percentage" do
|
139
|
+
color = Paleta::Color.new(94, 161, 235)
|
140
|
+
lightness = color.lightness
|
141
|
+
copy = color.darken(20)
|
142
|
+
copy.lightness.should == lightness - 20
|
143
|
+
color.lightness.should == lightness
|
144
|
+
end
|
145
|
+
|
107
146
|
it "should quietly maintain a minimum of 0 when darkening" do
|
108
147
|
color = Paleta::Color.new(94, 161, 235)
|
109
148
|
color.darken!(300)
|
@@ -118,6 +157,51 @@ describe Paleta::Color do
|
|
118
157
|
color.blue.should == 20
|
119
158
|
end
|
120
159
|
|
160
|
+
it "should return an inverted copy of itself" do
|
161
|
+
color = Paleta::Color.new(94, 161, 235)
|
162
|
+
copy = color.invert
|
163
|
+
copy.red.should == 161
|
164
|
+
copy.green.should == 94
|
165
|
+
copy.blue.should == 20
|
166
|
+
color.red.should == 94
|
167
|
+
color.green.should == 161
|
168
|
+
color.blue.should == 235
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should desaturate" do
|
172
|
+
color = Paleta::Color.new(94, 161, 235)
|
173
|
+
color.desaturate!
|
174
|
+
color.saturation.should == 0
|
175
|
+
color.red.to_i.should == 164
|
176
|
+
color.green.to_i.should == 164
|
177
|
+
color.blue.to_i.should == 164
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should return a desaturated copy of itself" do
|
181
|
+
color = Paleta::Color.new(94, 161, 235)
|
182
|
+
copy = color.desaturate
|
183
|
+
copy.saturation.should == 0
|
184
|
+
copy.red.to_i.should == 164
|
185
|
+
copy.green.to_i.should == 164
|
186
|
+
copy.blue.to_i.should == 164
|
187
|
+
color.saturation.to_i.should == 77
|
188
|
+
color.red.should == 94
|
189
|
+
color.green.should == 161
|
190
|
+
color.blue.should == 235
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should become its complement" do
|
194
|
+
color = Paleta::Color.new(:hsl, 90, 50, 50)
|
195
|
+
color.complement!
|
196
|
+
color.hue.should == 270
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should return its complement Color" do
|
200
|
+
color = Paleta::Color.new(:hsl, 90, 50, 50)
|
201
|
+
complement = color.complement
|
202
|
+
complement.hue.should == 270
|
203
|
+
end
|
204
|
+
|
121
205
|
it "should calculate its similarity to another Color" do
|
122
206
|
color1 = Paleta::Color.new(94, 161, 235)
|
123
207
|
color2 = Paleta::Color.new(237, 172, 33)
|
@@ -138,7 +222,7 @@ describe Paleta::Color do
|
|
138
222
|
end
|
139
223
|
|
140
224
|
it "should update its HSB and RGB components when its HEX value is updated" do
|
141
|
-
color = Paleta::Color.new
|
225
|
+
color = Paleta::Color.new(100, 100, 100)
|
142
226
|
color.hex = "ffffff"
|
143
227
|
color.red.should == 255
|
144
228
|
color.green.should == 255
|
data/spec/models/palette_spec.rb
CHANGED
@@ -11,14 +11,15 @@ describe Paleta::Palette do
|
|
11
11
|
it "should not initialize if an object in the set is not a Color" do
|
12
12
|
c1 = Paleta::Color.new(13, 57, 182)
|
13
13
|
c2 = 13
|
14
|
-
expect{ Paleta::Palette.new(c1, c2) }.to raise_error
|
14
|
+
expect{ Paleta::Palette.new(c1, c2) }.to raise_error(ArgumentError)
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should add Colors" do
|
18
18
|
c1 = Paleta::Color.new(13, 57, 182)
|
19
19
|
c2 = Paleta::Color.new(94, 161, 235)
|
20
|
+
c3 = Paleta::Color.new(0, 0, 0)
|
20
21
|
palette = Paleta::Palette.new(c1)
|
21
|
-
palette << c2
|
22
|
+
palette << c2 << c3
|
22
23
|
palette.include?(c2).should be_true
|
23
24
|
end
|
24
25
|
|
@@ -92,6 +93,7 @@ describe Paleta::Palette do
|
|
92
93
|
end
|
93
94
|
|
94
95
|
it "should calculate a multiple regression over each Color in the Palette in RGB space" do
|
96
|
+
Paleta::Palette.send(:public, :fit)
|
95
97
|
c1 = Paleta::Color.new(13, 57, 182)
|
96
98
|
c2 = Paleta::Color.new(94, 161, 235)
|
97
99
|
c3 = Paleta::Color.new(237, 172, 33)
|
@@ -132,4 +134,53 @@ describe Paleta::Palette do
|
|
132
134
|
p6 = Paleta::Palette.new(c9, c10)
|
133
135
|
p5.similarity(p6).round(5).should == 0.0047
|
134
136
|
end
|
137
|
+
|
138
|
+
it "should generate a new Palette of shades of a single Color" do
|
139
|
+
color = Paleta::Color.new(:hex, "ff0000")
|
140
|
+
palette = Paleta::Palette.generate(:from => color, :size => 5)
|
141
|
+
palette.each do |p|
|
142
|
+
p.hue.should == color.hue
|
143
|
+
p.saturation.should == color.saturation
|
144
|
+
end
|
145
|
+
|
146
|
+
palette[0].lightness.should == 10
|
147
|
+
palette[1].lightness.should == 30
|
148
|
+
palette[2].lightness.should == 50
|
149
|
+
palette[3].lightness.should == 70
|
150
|
+
palette[4].lightness.should == 90
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should generate a new Palette of Colors analogous to the seed Color" do
|
154
|
+
color = Paleta::Color.new(:hex, "0066cc")
|
155
|
+
palette = Paleta::Palette.generate(:type => :analogous, :from => color, :size => 5)
|
156
|
+
palette.each do |p|
|
157
|
+
p.lightness.should == color.lightness
|
158
|
+
p.saturation.should == color.saturation
|
159
|
+
end
|
160
|
+
palette[0].hue.should == 170
|
161
|
+
palette[1].hue.should == 190
|
162
|
+
palette[2].hue.should == 210
|
163
|
+
palette[3].hue.should == 230
|
164
|
+
palette[4].hue.should == 250
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should generate a new Palette of Colors monochromatic to the seed Color" do
|
168
|
+
color = Paleta::Color.new(:hex, "0066cc")
|
169
|
+
palette = Paleta::Palette.generate(:type => :monochromatic, :from => color, :size => 5)
|
170
|
+
palette.each do |p|
|
171
|
+
p.hue.should == color.hue
|
172
|
+
p.lightness.should == color.lightness
|
173
|
+
end
|
174
|
+
palette[0].saturation.should == 20
|
175
|
+
palette[1].saturation.should == 40
|
176
|
+
palette[2].saturation.should == 60
|
177
|
+
palette[3].saturation.should == 80
|
178
|
+
palette[4].saturation.should == 100
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should generate a new Palette of random Colors" do
|
183
|
+
palette = Paleta::Palette.generate(:type => :random, :size => 5)
|
184
|
+
palette.size.should == 5
|
185
|
+
end
|
135
186
|
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.4
|
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-11 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: A gem for working with color palettes
|
15
15
|
email:
|