style_train 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/style_train.rb +0 -7
- data/lib/style_train/color.rb +769 -97
- data/lib/style_train/sheet.rb +6 -2
- data/lib/style_train/support/numbers.rb +6 -2
- data/spec/color_spec.rb +1447 -0
- data/spec/numbers_spec.rb +13 -1
- data/spec/sheet_spec.rb +24 -10
- data/spec/themed_sheet_spec.rb +2 -2
- data/style_train.gemspec +4 -17
- metadata +7 -20
- data/lib/style_train/color_types/color_type.rb +0 -233
- data/lib/style_train/color_types/hex_color.rb +0 -44
- data/lib/style_train/color_types/hsl_color.rb +0 -5
- data/lib/style_train/color_types/keyword_color.rb +0 -192
- data/lib/style_train/color_types/rgb_color.rb +0 -57
- data/spec/color/color_spec.rb +0 -252
- data/spec/color/color_type_spec.rb +0 -389
- data/spec/color/hex_color_spec.rb +0 -160
- data/spec/color/keyword_color_spec.rb +0 -56
- data/spec/color/rgb_color_spec.rb +0 -75
data/lib/style_train/sheet.rb
CHANGED
|
@@ -294,14 +294,18 @@ CSS
|
|
|
294
294
|
end
|
|
295
295
|
end
|
|
296
296
|
|
|
297
|
-
def opacity(value)
|
|
297
|
+
def opacity(value, opts={})
|
|
298
298
|
value = value.to_f
|
|
299
299
|
str = ""
|
|
300
300
|
str << property( 'opacity', value )
|
|
301
|
-
str <<
|
|
301
|
+
str << alpha( value.to_f*100 ) if opts[:alpha]
|
|
302
302
|
str
|
|
303
303
|
end
|
|
304
304
|
|
|
305
|
+
def alpha(value)
|
|
306
|
+
property('filter', "alpha(opacity=#{(value.to_i)})")
|
|
307
|
+
end
|
|
308
|
+
|
|
305
309
|
[
|
|
306
310
|
'color', 'display', 'float', 'clear', 'visibility', 'cursor',
|
|
307
311
|
'height', 'width', 'max_height', 'max_width', 'min_height', 'min_width',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
class Fixnum
|
|
2
|
-
['px', 'em', 'pt'].each do |meth|
|
|
2
|
+
['px', 'em', 'pt', 'degrees'].each do |meth|
|
|
3
3
|
class_eval <<-RUBY
|
|
4
4
|
def #{meth}
|
|
5
5
|
self.to_s + "#{meth}"
|
|
@@ -13,11 +13,15 @@ class Fixnum
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
class Float
|
|
16
|
-
['em', 'pt'].each do |meth|
|
|
16
|
+
['em', 'pt', 'degrees'].each do |meth|
|
|
17
17
|
class_eval <<-RUBY
|
|
18
18
|
def #{meth}
|
|
19
19
|
self.to_s + "#{meth}"
|
|
20
20
|
end
|
|
21
21
|
RUBY
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
def percent
|
|
25
|
+
"#{self}%"
|
|
26
|
+
end
|
|
23
27
|
end
|
data/spec/color_spec.rb
ADDED
|
@@ -0,0 +1,1447 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
Color = StyleTrain::Color unless defined?(Color)
|
|
4
|
+
describe Color do
|
|
5
|
+
TOLERANCE = 0.009
|
|
6
|
+
|
|
7
|
+
describe 'initialization' do
|
|
8
|
+
describe 'auto-detection' do
|
|
9
|
+
it 'raises an error if autodetection fails' do
|
|
10
|
+
lambda{ Color.new('ggg') }.should raise_error(Color::AutodetectionError)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe 'transparent' do
|
|
14
|
+
before :all do
|
|
15
|
+
@trans = Color.new(:transparent)
|
|
16
|
+
@trans_too = Color.new('transparent')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'has the type transparent' do
|
|
20
|
+
@trans.type.should == @trans_too.type
|
|
21
|
+
@trans.type.should == :transparent
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'has r, g, b values of 0' do
|
|
25
|
+
@trans.r.should == 0
|
|
26
|
+
@trans.g.should == 0
|
|
27
|
+
@trans.b.should == 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'has an alpha of 0' do
|
|
31
|
+
@trans.alpha.should == 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should ignore options, alpha, background, etc' do
|
|
35
|
+
color = Color.new(:transparent, :alpha => 1.0, :background => '#666')
|
|
36
|
+
color.type.should == :transparent
|
|
37
|
+
color.alpha.should == 0
|
|
38
|
+
color.background.should be_nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe 'keyword colors' do
|
|
43
|
+
it 'sets the type appropriately when passed a symbol' do
|
|
44
|
+
Color.new(:lightyellow).type.should == :keyword
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'raises an error if the symbol is not found' do
|
|
48
|
+
lambda{ Color.new(:light_puke) }.should raise_error(
|
|
49
|
+
Color::KeywordError, "Color :light_puke not found as a keyword"
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'should not raise an error if :transparent is given' do
|
|
54
|
+
lambda{ Color.new(:transparent) }.should_not raise_error
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'should set the r, g, and b values based on the key' do
|
|
58
|
+
color = Color.new(:azure)
|
|
59
|
+
color.r.should == 240/255.0
|
|
60
|
+
color.b.should == 1.0
|
|
61
|
+
color.g.should == 1.0
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe 'hexidecimal colors' do
|
|
66
|
+
it 'sets the type to :hex' do
|
|
67
|
+
Color.new('#666').type.should == :hex
|
|
68
|
+
Color.new('#666666').type.should == :hex
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'sets the hex_6' do
|
|
72
|
+
Color.new('#444').hex_6.should == 0x444444
|
|
73
|
+
Color.new('#404040').hex_6.should == 0x404040
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'sets the rgb appropriately' do
|
|
77
|
+
@gray = Color.new('#666')
|
|
78
|
+
@red = Color.new('#993300')
|
|
79
|
+
@gold = Color.new('#FC0')
|
|
80
|
+
|
|
81
|
+
@gray.r.should == 102/255.0
|
|
82
|
+
@red.r.should == 153/255.0
|
|
83
|
+
@gold.r.should == 255/255.0
|
|
84
|
+
|
|
85
|
+
@gray.g.should == 102/255.0
|
|
86
|
+
@red.g.should == 51/255.0
|
|
87
|
+
@gold.g.should == 204/255.0
|
|
88
|
+
|
|
89
|
+
@gray.b.should == 102/255.0
|
|
90
|
+
@red.b.should == 0
|
|
91
|
+
@gold.b.should == 0
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'should pass of colors with many arguments' do
|
|
95
|
+
lambda { Color.new('666', 100, 100) }.should raise_error(Color::AutodetectionError)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe 'rgb colors' do
|
|
100
|
+
before do
|
|
101
|
+
@color = Color.new(20,40,60)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'should set the type to :rgb' do
|
|
105
|
+
@color.type.should == :rgb
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'sets the rgb values appropriately' do
|
|
109
|
+
@color.r.should == 20/255.0
|
|
110
|
+
@color.g.should == 40/255.0
|
|
111
|
+
@color.b.should == 60/255.0
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'takes percentages if a string' do
|
|
115
|
+
color = Color.new(0.percent, 50.percent, 100.percent)
|
|
116
|
+
color.type.should == :rgb
|
|
117
|
+
color.r.should == 0
|
|
118
|
+
color.g.should == 0.5
|
|
119
|
+
color.b.should == 1.0
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'takes a ratio' do
|
|
123
|
+
color = Color.new(0.0, 0.5, 1.0)
|
|
124
|
+
color.type.should == :rgb
|
|
125
|
+
color.r.should == 0
|
|
126
|
+
color.g.should == 0.5
|
|
127
|
+
color.b.should == 1.0
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'raises an error if numbers are too large' do
|
|
131
|
+
lambda{ Color.new(20, 300, 255) }.should raise_error(Color::ByteError)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'raises an error if the numbers are too small' do
|
|
135
|
+
lambda{ Color.new(20, 100, -155) }.should raise_error(Color::ByteError)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
describe 'hsl colors' do
|
|
140
|
+
before do
|
|
141
|
+
@color = Color.new( 350, 50.percent, 100.percent )
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'correctly detects the type when first argument is greater than 255' do
|
|
145
|
+
@color.type.should == :hsl
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'takes ratios for s and l' do
|
|
149
|
+
color = Color.new( 120.degrees, 0.0, 0.75 )
|
|
150
|
+
color.type.should == :hsl
|
|
151
|
+
color.h.should == 120.0/360
|
|
152
|
+
color.s.should == 0
|
|
153
|
+
color.l.should == 0.75
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it 'sets the hsl correctly' do
|
|
157
|
+
color = Color.new(0.degrees, 0.percent, 40.percent)
|
|
158
|
+
color.h.should == 0
|
|
159
|
+
color.s.should == 0
|
|
160
|
+
color.l.should == 0.4
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'converts to rgb correctly' do
|
|
164
|
+
color = Color.new(0.degrees, 0.percent, 40.percent)
|
|
165
|
+
color.r.should == 102/255.0
|
|
166
|
+
color.g.should == 102/255.0
|
|
167
|
+
color.b.should == 102/255.0
|
|
168
|
+
|
|
169
|
+
color = Color.new(210.degrees, 65.percent, 20.percent)
|
|
170
|
+
color.r.should == 0.07
|
|
171
|
+
color.g.should be_within(TOLERANCE).of(0.2)
|
|
172
|
+
color.b.should == 0.33
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe 'explicit typing' do
|
|
178
|
+
describe 'keyword' do
|
|
179
|
+
it 'will raise an error if the keyword is not found' do
|
|
180
|
+
lambda { Color.new(:light_puke, :type => :keyword) }.should raise_error(Color::KeywordError)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
describe 'hexidecimal colors' do
|
|
185
|
+
it 'will convert a string without the preceeding #' do
|
|
186
|
+
color = Color.new('666', :type => :hex )
|
|
187
|
+
color.type.should == :hex
|
|
188
|
+
color.r.should == 102/255.0
|
|
189
|
+
color.g.should == 102/255.0
|
|
190
|
+
color.b.should == 102/255.0
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'raises an error if the string does not match hex color standards' do
|
|
194
|
+
lambda{ Color.new('ggg', :type => :hex) }.should raise_error(ArgumentError)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
describe 'rgb colors' do
|
|
199
|
+
it 'should work with good numbers' do
|
|
200
|
+
color = Color.new(255,255,0, :type => :rgb)
|
|
201
|
+
color.type.should == :rgb
|
|
202
|
+
color.r.should == 1.0
|
|
203
|
+
color.g.should == 1.0
|
|
204
|
+
color.b.should == 0
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it 'raises an error if any byte number is out of range' do
|
|
208
|
+
lambda{ Color.new(300, 100, 100, :type => :rgb) }.should raise_error(ArgumentError)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it 'raises an error if any percentage is out of range' do
|
|
212
|
+
lambda{ Color.new(300.percent, 100.percent, 100.percent, :type => :rgb) }.should raise_error(ArgumentError)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it 'raises an error if any ratio is out of range' do
|
|
216
|
+
lambda{ Color.new(2.0, 1.0, 1.0, :type => :rgb) }.should raise_error(ArgumentError)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe 'hsl colors' do
|
|
221
|
+
it 'will recognize the type even if hue is within byte range' do
|
|
222
|
+
color = Color.new(220, 127, 127, :type => :hsl)
|
|
223
|
+
color.type.should == :hsl
|
|
224
|
+
color.r.should be_within(TOLERANCE).of(0.25)
|
|
225
|
+
color.g.should be_within(TOLERANCE).of(0.416)
|
|
226
|
+
color.b.should be_within(TOLERANCE).of(0.75)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it 'accepts ratios for hue' do
|
|
230
|
+
color = Color.new(0.611111, 0.5, 0.5, :type => :hsl)
|
|
231
|
+
color.type.should == :hsl
|
|
232
|
+
color.r.should == 0.25
|
|
233
|
+
color.g.should be_within(TOLERANCE).of(0.416)
|
|
234
|
+
color.b.should == 0.75
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it 'accepts percentages for hue' do
|
|
238
|
+
color = Color.new(61.1111.percent, 50.percent, 50.percent, :type => :hsl)
|
|
239
|
+
color.type.should == :hsl
|
|
240
|
+
color.r.should == 0.25
|
|
241
|
+
color.g.should be_within(TOLERANCE).of(0.416)
|
|
242
|
+
color.b.should == 0.75
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
describe 'alpha' do
|
|
248
|
+
describe 'autodetection' do
|
|
249
|
+
it 'ignores the alpha with a transparent color' do
|
|
250
|
+
Color.new(:transparent, :alpha => 0.5).alpha.should == 0.0
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it 'sets the alpha with a keyword type' do
|
|
254
|
+
Color.new(:lightyellow, :alpha => 0.5).alpha.should == 0.5
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it 'sets the alpha with a hex color' do
|
|
258
|
+
Color.new('#666', :alpha => 0.75).alpha.should == 0.75
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it 'sets the alpha with a rgb color' do
|
|
262
|
+
Color.new(100.percent, 50.percent, 25.percent, :alpha => 0.25).alpha.should == 0.25
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it 'sets the alpha with a hsl color' do
|
|
266
|
+
Color.new(20.degrees, 50.percent, 50.percent, :alpha => 0.10).alpha.should == 0.1
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
it 'sets the alpha to 1.0 by default' do
|
|
270
|
+
Color.new(:lightyellow).alpha.should == 1.0
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
describe 'explicit typing' do
|
|
275
|
+
it 'ignores the alpha with a transparent color' do
|
|
276
|
+
Color.new(:transparent, :alpha => 0.5, :type => :transparent).alpha.should == 0.0
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
it 'sets the alpha with a keyword type' do
|
|
280
|
+
Color.new(:lightyellow, :type => :keyword, :alpha => 0.5).alpha.should == 0.5
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
it 'sets the alpha with a hex color' do
|
|
284
|
+
Color.new('#123456', :type => :hex, :alpha => 0.25).alpha.should == 0.25
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it 'sets the alpha with a rgb color' do
|
|
288
|
+
Color.new(255,127,64, :type => :rgb, :alpha => 0.1).alpha.should == 0.1
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it 'sets the alpha with a hsl color' do
|
|
292
|
+
Color.new(20, 50.percent, 50.percent, :type => :hsl, :alpha => 0.75).alpha.should == 0.75
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
describe 'background' do
|
|
298
|
+
describe 'autodetection' do
|
|
299
|
+
describe 'different detection types' do
|
|
300
|
+
it 'ignores the background with a transparent color' do
|
|
301
|
+
Color.new(:transparent, :background => :black).background.should == nil
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it 'sets the background with a keyword type' do
|
|
305
|
+
Color.new(:lightyellow, :background => :black).background.should == Color.new(:black)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it 'sets the background with a hex color' do
|
|
309
|
+
Color.new('#666', :background => :black).background.should == Color.new(:black)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it 'sets the background with a rgb color' do
|
|
313
|
+
Color.new(100.percent, 50.percent, 25.percent, :background => :black).background.should == Color.new(:black)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it 'sets the background with a hsl color' do
|
|
317
|
+
Color.new(20.degrees, 50.percent, 50.percent, :background => :black).background.should == Color.new(:black)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
it 'sets the background to :white by default' do
|
|
321
|
+
Color.new(:lightyellow).background.should == Color.new(:white)
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
describe "different background types/arguments" do
|
|
326
|
+
it 'takes background a keyword arguments' do
|
|
327
|
+
Color.new(:lightyellow, :background => :black).background.should == Color.new(:black)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it 'takes background with hex color arguments' do
|
|
331
|
+
Color.new(:lightyellow, :background => '#000').background.should == Color.new(:black)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it 'takes background with rgb color arguments' do
|
|
335
|
+
Color.new(:lightyellow, :background => [0,0,0]).background.should == Color.new(:black)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
it 'takes background with hsl color arguments' do
|
|
339
|
+
Color.new(:lightyellow, :background => [0.degrees, 0, 0]).background.should == Color.new(:black)
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
describe 'explicit typing' do
|
|
345
|
+
it 'ignores the background with a transparent color' do
|
|
346
|
+
Color.new(:transparent, :background => :black, :type => :transparent).background.should == nil
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
it 'sets the background with a keyword type' do
|
|
350
|
+
Color.new(:lightyellow, :background => :black, :type => :keyword).background.should == Color.new(:black)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it 'sets the background with a hex color' do
|
|
354
|
+
Color.new('#666', :background => :black, :type => :hex).background.should == Color.new(:black)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
it 'sets the background with a rgb color' do
|
|
358
|
+
Color.new(100.percent, 50.percent, 25.percent, :background => :black, :type => :rgb).background.should == Color.new(:black)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
it 'sets the background with a hsl color' do
|
|
362
|
+
Color.new(20.degrees, 50.percent, 50.percent, :background => :black, :type => :hsl).background.should == Color.new(:black)
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
describe 'alpha' do
|
|
369
|
+
describe 'acceptable values' do
|
|
370
|
+
before do
|
|
371
|
+
@color = Color.new('666')
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it 'takes ratios' do
|
|
375
|
+
@color.alpha = 0.5
|
|
376
|
+
@color.alpha.should == 0.5
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
it 'should raise an error if the ratio is out of range' do
|
|
380
|
+
lambda { @color.alpha = 1.1 }.should raise_error( Color::RatioError )
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
it 'takes percentages' do
|
|
384
|
+
@color.alpha = 72.5.percent
|
|
385
|
+
@color.alpha.should == 0.725
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
it 'accepts integers as percentages' do
|
|
389
|
+
@color.alpha = 78
|
|
390
|
+
@color.alpha.should == 0.78
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
it 'should raise an error if the percentage is out of range' do
|
|
394
|
+
lambda { @color.alpha = 300.percent }.should raise_error(Color::PercentageError)
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
describe 'background' do
|
|
400
|
+
before do
|
|
401
|
+
@background = Color.new(:lightyellow)
|
|
402
|
+
@color = Color.new(:black, :alpha => 0.5)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it 'takes a color object' do
|
|
406
|
+
@color.background = @background
|
|
407
|
+
@color.background.should == @background
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it 'otherwise tries to construct a color object from the arguments' do
|
|
411
|
+
@color.background = :lightyellow
|
|
412
|
+
@color.background.should == @background
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
describe 'comparisons' do
|
|
417
|
+
it 'should be === if the colors have the same object id' do
|
|
418
|
+
(Color.new(:lightyellow) === Color.new(:lightyellow)).should == false
|
|
419
|
+
color = Color.new(:lightyellow)
|
|
420
|
+
(color === color).should == true
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
it 'should be =~ if the colors have the same rgb, but different alphas' do
|
|
424
|
+
(Color.new(:lightyellow, :alpha => 0.5) =~ Color.new(:lightyellow)).should == true
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
describe '==' do
|
|
428
|
+
it 'should be false if the alpha is different' do
|
|
429
|
+
Color.new(255, 255, 224, :alpha => 0.5).should_not == Color.new(:lightyellow)
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
it 'should be false if the rgb values are different' do
|
|
433
|
+
Color.new(255, 255, 225, :alpha => 1.0).should_not == Color.new(:lightyellow)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
it 'should be == if the colors have the same rgb and alpha' do
|
|
437
|
+
Color.new(255, 255, 224, :alpha => 1.0).should == Color.new(:lightyellow)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
it 'should be indifferent to backgrounds' do
|
|
441
|
+
Color.new(255, 255, 224, :alpha => 1.0, :background => :black).should == Color.new(:lightyellow)
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
describe 'normalizer' do
|
|
447
|
+
describe 'percentages' do
|
|
448
|
+
it 'should return valid integers' do
|
|
449
|
+
Color.normalize_percentage(25.percent).should == 25
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
it 'should return valid floats' do
|
|
453
|
+
Color.normalize_percentage(50.5.percent).should == 50.5
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
it 'works with an integer' do
|
|
457
|
+
Color.normalize_percentage(50).should == 50
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
it 'works with floats' do
|
|
461
|
+
Color.normalize_percentage(20.5).should == 20.5
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it 'raises an error if greater than 100' do
|
|
465
|
+
lambda{ Color.normalize_percentage(105) }.should raise_error(Color::PercentageError)
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
it 'raises an error if lower than 0' do
|
|
469
|
+
lambda{ Color.normalize_percentage(-25) }.should raise_error(Color::PercentageError)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it 'converts to byte' do
|
|
473
|
+
Color.percentage_to_byte(100.0).should == 255
|
|
474
|
+
Color.percentage_to_byte(0).should == 0
|
|
475
|
+
Color.percentage_to_byte(50.percent).should == 127
|
|
476
|
+
end
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
describe 'degrees' do
|
|
480
|
+
it 'should return a number between 0 and 359 when given such a number' do
|
|
481
|
+
Color.normalize_degrees(30).should == 30/360.0
|
|
482
|
+
Color.normalize_degrees(42).should == 42/360.0
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
it 'should return a number when given a degree string' do
|
|
486
|
+
Color.normalize_degrees(42.degrees).should == 42/360.0
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
it 'should return nil when given a string without degrees' do
|
|
490
|
+
Color.normalize_degrees('42').should == nil
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
it 'should normalize a number greater than 359' do
|
|
494
|
+
Color.normalize_degrees(360).should == 0
|
|
495
|
+
Color.normalize_degrees(460).should == 100/360.0
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
it 'should normalize negative number' do
|
|
499
|
+
Color.normalize_degrees(-127).should == 233/360.0
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
it 'works with strings containing "degrees"' do
|
|
503
|
+
Color.normalize_degrees(127.degrees).should == 127/360.0
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
it 'rejects percentage strings' do
|
|
507
|
+
Color.normalize_degrees(12.percent).should == nil
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
describe 'ratios' do
|
|
512
|
+
it 'raises an error if below 0' do
|
|
513
|
+
lambda{ Color.ratio_to_byte(-0.1) }.should raise_error(Color::RatioError)
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
it 'raises an error if it is above 1.0' do
|
|
517
|
+
lambda{ Color.ratio_to_byte(1.1)}.should raise_error(Color::RatioError)
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
it 'converts correctly to byte otherwise' do
|
|
521
|
+
Color.ratio_to_byte(0.5).should == 127
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
describe 'type transformation' do
|
|
527
|
+
before do
|
|
528
|
+
@red_values = {
|
|
529
|
+
:rgb => [100, 25, 25],
|
|
530
|
+
:hex => ['641919', 0x641919],
|
|
531
|
+
:hsl => [0.degrees, 0.6, 0.25]
|
|
532
|
+
}
|
|
533
|
+
@green_values = {
|
|
534
|
+
:rgb => [25, 100, 25],
|
|
535
|
+
:hex => ['196419', 0x196419],
|
|
536
|
+
:hsl => [120.degrees, 0.60, 0.25]
|
|
537
|
+
}
|
|
538
|
+
@blue_values = {
|
|
539
|
+
:rgb => [25, 25, 100],
|
|
540
|
+
:hex => ['191964', 0x191964],
|
|
541
|
+
:hsl => [240.degrees, 0.60, 0.25]
|
|
542
|
+
}
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
describe '#set_hsl' do
|
|
546
|
+
before do
|
|
547
|
+
@red = Color.new(*@red_values[:rgb])
|
|
548
|
+
@red.set_hsl
|
|
549
|
+
@blue = Color.new(*@blue_values[:rgb])
|
|
550
|
+
@blue.set_hsl
|
|
551
|
+
@green = Color.new(*@green_values[:rgb])
|
|
552
|
+
@green.set_hsl
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
it 'changes the type to :hsl' do
|
|
556
|
+
@red.type.should == :hsl
|
|
557
|
+
@blue.type.should == :hsl
|
|
558
|
+
@green.type.should == :hsl
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
it 'converts adds hsl value' do
|
|
562
|
+
@red.h.should be_within(TOLERANCE).of(Color.normalize_degrees(@red_values[:hsl][0]))
|
|
563
|
+
@red.s.should be_within(TOLERANCE).of( @red_values[:hsl][1])
|
|
564
|
+
@red.l.should be_within(TOLERANCE).of(@red_values[:hsl][2])
|
|
565
|
+
|
|
566
|
+
@green.h.should be_within(TOLERANCE).of(Color.normalize_degrees(@green_values[:hsl][0]))
|
|
567
|
+
@green.s.should be_within(TOLERANCE).of( @green_values[:hsl][1])
|
|
568
|
+
@green.l.should be_within(TOLERANCE).of(@green_values[:hsl][2])
|
|
569
|
+
|
|
570
|
+
@blue.h.should be_within(TOLERANCE).of(Color.normalize_degrees(@blue_values[:hsl][0]))
|
|
571
|
+
@blue.s.should be_within(TOLERANCE).of( @blue_values[:hsl][1])
|
|
572
|
+
@blue.l.should be_within(TOLERANCE).of(@blue_values[:hsl][2])
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
describe '#set_rgb' do
|
|
577
|
+
before do
|
|
578
|
+
@color = Color.new('#555')
|
|
579
|
+
@color.set_rgb
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
it 'changes the type' do
|
|
583
|
+
@color.type.should == :rgb
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
describe '#set_hex' do
|
|
588
|
+
before do
|
|
589
|
+
@red = Color.new(*@red_values[:rgb])
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
it 'sets the hex and hex_6' do
|
|
593
|
+
@red.hex = 'foo'
|
|
594
|
+
@red.hex_6 = 'foo'
|
|
595
|
+
@red.set_hex
|
|
596
|
+
@red.hex.should == @red_values[:hex][0]
|
|
597
|
+
@red.hex_6.should == @red_values[:hex][1]
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
it 'sets the type to :hex' do
|
|
601
|
+
@red.set_hex
|
|
602
|
+
@red.type.should == :hex
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
describe '#hsl_to_rgb' do
|
|
607
|
+
before do
|
|
608
|
+
@red = Color.new(*@red_values[:hsl])
|
|
609
|
+
@red.set_hex
|
|
610
|
+
@red.l += 0.1
|
|
611
|
+
@red.hsl_to_rgb
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
it 'resets the r, g, b values from h, s, l' do
|
|
615
|
+
@red.r.should be_within(TOLERANCE).of(143/255.0)
|
|
616
|
+
@red.g.should be_within(TOLERANCE).of(36/255.0)
|
|
617
|
+
@red.b.should be_within(TOLERANCE).of(36/255.0)
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
it 'clears the hex' do
|
|
621
|
+
@red.hex.should == nil
|
|
622
|
+
@red.hex_6.should == nil
|
|
623
|
+
end
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
describe 'modification' do
|
|
628
|
+
before do
|
|
629
|
+
@red_values = {
|
|
630
|
+
:rgb => [100, 25, 25],
|
|
631
|
+
:hex => ['641919', 0x641919],
|
|
632
|
+
:hsl => [Color.normalize_degrees(0.degrees), 0.6, 0.25]
|
|
633
|
+
}
|
|
634
|
+
@red = Color.new(*@red_values[:rgb])
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
describe 'shift' do
|
|
638
|
+
describe 'lighten!' do
|
|
639
|
+
before do
|
|
640
|
+
@red.lighten!
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
it 'adds 10% to the l value by default' do
|
|
644
|
+
@red.l.should be_within(TOLERANCE).of(@red_values[:hsl][2] + 0.1)
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
it 'recalculates the rgb' do
|
|
648
|
+
@red.r.should be_within(TOLERANCE).of(143/255.0)
|
|
649
|
+
@red.g.should be_within(TOLERANCE).of(36/255.0)
|
|
650
|
+
@red.b.should be_within(TOLERANCE).of(36/255.0)
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
it 'takes a percentage argument and adds that from the l' do
|
|
654
|
+
l = @red.l
|
|
655
|
+
@red.lighten!(30.percent)
|
|
656
|
+
@red.l.should == l + 0.30
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
it 'takes a ratio argument' do
|
|
660
|
+
l = @red.l
|
|
661
|
+
@red.lighten!(0.21)
|
|
662
|
+
@red.l.should == l + 0.21
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
it 'assumes integers are percentages' do
|
|
666
|
+
l = @red.l
|
|
667
|
+
@red.lighten!(20)
|
|
668
|
+
@red.l.should == l + 0.2
|
|
669
|
+
@red.lighten!(80)
|
|
670
|
+
@red.l.should == 1.0
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
it 'should cap at 100 percent' do
|
|
674
|
+
@red.lighten!(0.80)
|
|
675
|
+
@red.l.should == 1.0
|
|
676
|
+
end
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
describe 'lighten' do
|
|
680
|
+
before do
|
|
681
|
+
@less_red = @red.lighten
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
it 'should not affect the originating color' do
|
|
685
|
+
@red.type.should == :rgb
|
|
686
|
+
@red.r.should be_within(TOLERANCE).of(0.4)
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
it 'should return a transformed object' do
|
|
690
|
+
@less_red.r.should be_within(TOLERANCE).of(143/255.0)
|
|
691
|
+
@less_red.g.should be_within(TOLERANCE).of(36/255.0)
|
|
692
|
+
@less_red.b.should be_within(TOLERANCE).of(36/255.0)
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
describe 'darken!' do
|
|
697
|
+
before do
|
|
698
|
+
@red.darken!
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
it 'makes subtracts 10% to the l value by default' do
|
|
702
|
+
@red.l.should be_within(TOLERANCE).of(@red_values[:hsl][2] - 0.1)
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
it 'recalculates the rgb' do
|
|
706
|
+
@red.r.should be_within(TOLERANCE).of(61/255.0)
|
|
707
|
+
@red.g.should be_within(TOLERANCE).of(15/255.0)
|
|
708
|
+
@red.b.should be_within(TOLERANCE).of(15/255.0)
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
it 'takes a percentage argument and subtracts that from the l' do
|
|
712
|
+
l = @red.l
|
|
713
|
+
@red.darken!(5.percent)
|
|
714
|
+
@red.l.should == l - 0.05
|
|
715
|
+
end
|
|
716
|
+
|
|
717
|
+
it 'takes a ratio argument' do
|
|
718
|
+
l = @red.l
|
|
719
|
+
@red.darken!(0.07)
|
|
720
|
+
@red.l.should == l - 0.07
|
|
721
|
+
end
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
describe 'darken' do
|
|
725
|
+
before do
|
|
726
|
+
@darker_red = @red.darken
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
it 'should not affect the originating color' do
|
|
730
|
+
@red.type.should == :rgb
|
|
731
|
+
@red.r.should be_within(TOLERANCE).of(0.4)
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
it 'should return a transformed object' do
|
|
735
|
+
@darker_red.r.should be_within(TOLERANCE).of(61/255.0)
|
|
736
|
+
@darker_red.g.should be_within(TOLERANCE).of(15/255.0)
|
|
737
|
+
@darker_red.b.should be_within(TOLERANCE).of(15/255.0)
|
|
738
|
+
end
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
describe 'saturate!' do
|
|
742
|
+
before do
|
|
743
|
+
@red.saturate!
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
it 'adds 10% to the s value by default' do
|
|
747
|
+
@red.s.should be_within(TOLERANCE).of(@red_values[:hsl][1] + 0.1)
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
it 'recalculates the rgb' do
|
|
751
|
+
@red.r.should be_within(TOLERANCE).of(108/255.0)
|
|
752
|
+
@red.g.should be_within(TOLERANCE).of(19/255.0)
|
|
753
|
+
@red.b.should be_within(TOLERANCE).of(19/255.0)
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
it 'takes a percentage argument and adds that from the s' do
|
|
757
|
+
s = @red.s
|
|
758
|
+
@red.saturate!(30.percent)
|
|
759
|
+
@red.s.should == s + 0.30
|
|
760
|
+
end
|
|
761
|
+
|
|
762
|
+
it 'takes a ratio argument' do
|
|
763
|
+
s = @red.s
|
|
764
|
+
@red.saturate!(0.21)
|
|
765
|
+
@red.s.should be_within(TOLERANCE).of(s + 0.21)
|
|
766
|
+
end
|
|
767
|
+
|
|
768
|
+
it 'assumes integers are percentages' do
|
|
769
|
+
s = @red.s
|
|
770
|
+
@red.saturate!(20)
|
|
771
|
+
@red.s.should == s + 0.2
|
|
772
|
+
@red.saturate!(80)
|
|
773
|
+
@red.s.should == 1.0
|
|
774
|
+
end
|
|
775
|
+
|
|
776
|
+
it 'should cap at 100 percent' do
|
|
777
|
+
@red.saturate!(0.80)
|
|
778
|
+
@red.s.should == 1.0
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
it 'aliases to #brighten' do
|
|
782
|
+
@red.brighten!(0.8)
|
|
783
|
+
@red.s.should == 1.0
|
|
784
|
+
end
|
|
785
|
+
end
|
|
786
|
+
|
|
787
|
+
describe 'saturate' do
|
|
788
|
+
before do
|
|
789
|
+
@brighter_red = @red.saturate
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
it 'should not affect the originating color' do
|
|
793
|
+
@red.type.should == :rgb
|
|
794
|
+
@red.r.should be_within(TOLERANCE).of(0.4)
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
it 'should return a transformed object' do
|
|
798
|
+
@brighter_red.r.should be_within(TOLERANCE).of(108/255.0)
|
|
799
|
+
@brighter_red.g.should be_within(TOLERANCE).of(19/255.0)
|
|
800
|
+
@brighter_red.b.should be_within(TOLERANCE).of(19/255.0)
|
|
801
|
+
end
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
describe 'dull!' do
|
|
805
|
+
before do
|
|
806
|
+
@red.dull!
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
it 'adds 10% to the s value by default' do
|
|
810
|
+
@red.s.should be_within(TOLERANCE).of(@red_values[:hsl][1] - 0.1)
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
it 'recalculates the rgb' do
|
|
814
|
+
@red.r.should be_within(TOLERANCE).of(96/255.0)
|
|
815
|
+
@red.g.should be_within(TOLERANCE).of(32/255.0)
|
|
816
|
+
@red.b.should be_within(TOLERANCE).of(32/255.0)
|
|
817
|
+
end
|
|
818
|
+
|
|
819
|
+
it 'takes a percentage argument and adds that from the s' do
|
|
820
|
+
s = @red.s
|
|
821
|
+
@red.dull!(30.percent)
|
|
822
|
+
@red.s.should be_within(TOLERANCE).of(s - 0.30)
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
it 'takes a ratio argument' do
|
|
826
|
+
s = @red.s
|
|
827
|
+
@red.dull!(0.21)
|
|
828
|
+
@red.s.should be_within(TOLERANCE).of(s - 0.21)
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
it 'assumes integers are percentages' do
|
|
832
|
+
s = @red.s
|
|
833
|
+
@red.dull!(20)
|
|
834
|
+
@red.s.should be_within(TOLERANCE).of(s - 0.2)
|
|
835
|
+
@red.dull!(80)
|
|
836
|
+
@red.s.should == 0.0
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
it 'should cap at 100 percent' do
|
|
840
|
+
@red.dull!(0.80)
|
|
841
|
+
@red.s.should == 0.0
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
it 'aliases to #desaturate' do
|
|
845
|
+
@red.desaturate!(0.8)
|
|
846
|
+
@red.s.should == 0.0
|
|
847
|
+
end
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
describe 'dull' do
|
|
851
|
+
before do
|
|
852
|
+
@dull_red = @red.dull
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
it 'should not affect the originating color' do
|
|
856
|
+
@red.type.should == :rgb
|
|
857
|
+
@red.r.should be_within(TOLERANCE).of(0.4)
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
it 'should return a transformed object' do
|
|
861
|
+
@dull_red.r.should be_within(TOLERANCE).of(96/255.0)
|
|
862
|
+
@dull_red.g.should be_within(TOLERANCE).of(32/255.0)
|
|
863
|
+
@dull_red.b.should be_within(TOLERANCE).of(32/255.0)
|
|
864
|
+
end
|
|
865
|
+
end
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
describe 'rotate' do
|
|
869
|
+
describe 'arbitrary' do
|
|
870
|
+
it 'defaults to 10 degrees' do
|
|
871
|
+
@new = @red.rotate
|
|
872
|
+
@new.h.should be_within(TOLERANCE).of(10/360.0)
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
it 'takes other positive degree values' do
|
|
876
|
+
@new = @red.rotate(30.degrees)
|
|
877
|
+
@new.h.should be_within(TOLERANCE).of(30/360.0 )
|
|
878
|
+
end
|
|
879
|
+
|
|
880
|
+
it 'takes negative degrees' do
|
|
881
|
+
@new = @red.rotate(-20.degrees)
|
|
882
|
+
@new.h.should be_within(TOLERANCE).of((360-20)/360.0 )
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
it 'will rotate beyond end points' do
|
|
886
|
+
@new = @red.rotate(300.degrees)
|
|
887
|
+
@new.h.should be_within(TOLERANCE).of(300/360.0)
|
|
888
|
+
|
|
889
|
+
@new.rotate!(100.degrees)
|
|
890
|
+
@new.h.should be_within(TOLERANCE).of(40/360.0)
|
|
891
|
+
end
|
|
892
|
+
|
|
893
|
+
it 'takes ratios' do
|
|
894
|
+
@red.rotate(0.5).h.should be_within(TOLERANCE).of(0.5)
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
it 'calculates the rgb values' do
|
|
898
|
+
@new = @red.rotate(0.5)
|
|
899
|
+
@new.r.should be_within(TOLERANCE).of(26/255.0)
|
|
900
|
+
@new.g.should be_within(TOLERANCE).of(102/255.0)
|
|
901
|
+
@new.b.should be_within(TOLERANCE).of(102/255.0)
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
it 'returns a new color object' do
|
|
905
|
+
@new = @red.rotate(0.5)
|
|
906
|
+
@new.should_not == @red
|
|
907
|
+
end
|
|
908
|
+
|
|
909
|
+
it 'does not modify the existing object' do
|
|
910
|
+
@red.rotate(0.5)
|
|
911
|
+
@red.type.should == :rgb
|
|
912
|
+
@red.r.should be_within(TOLERANCE).of(@red_values[:rgb][0]/255.0)
|
|
913
|
+
end
|
|
914
|
+
|
|
915
|
+
it 'has a ! method that modifies self' do
|
|
916
|
+
@red.rotate!(0.5)
|
|
917
|
+
@red.type.should == :hsl
|
|
918
|
+
@red.r.should be_within(TOLERANCE).of(26/255.0)
|
|
919
|
+
end
|
|
920
|
+
end
|
|
921
|
+
|
|
922
|
+
describe 'compliment' do
|
|
923
|
+
it 'rotates half way around' do
|
|
924
|
+
@red.compliment.should == @red.rotate(0.5)
|
|
925
|
+
end
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
describe '#dial' do
|
|
929
|
+
it 'gives triangular colors' do
|
|
930
|
+
@red.triangulate.should == [@red, @red.rotate(120.degrees), @red.rotate(240.degrees)]
|
|
931
|
+
end
|
|
932
|
+
|
|
933
|
+
it 'gives offset triangular colors' do
|
|
934
|
+
dial = @red.triangulate(1/6.0)
|
|
935
|
+
dial[0].should == @red.rotate(1/6.0)
|
|
936
|
+
dial[1].should == @red.rotate(0.5)
|
|
937
|
+
dial[2].should == @red.rotate(5/6.0)
|
|
938
|
+
end
|
|
939
|
+
|
|
940
|
+
it 'dialing allows dividing by any integer' do
|
|
941
|
+
@red.dial(5).should == [
|
|
942
|
+
@red,
|
|
943
|
+
@red.rotate((360/5.0).degrees),
|
|
944
|
+
@red.rotate((2*360/5.0).degrees),
|
|
945
|
+
@red.rotate((3*360/5.0).degrees),
|
|
946
|
+
@red.rotate((4*360/5.0).degrees)
|
|
947
|
+
]
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
it 'dailing allows offset too' do
|
|
951
|
+
@red.dial(5, 120.degrees).should == [
|
|
952
|
+
@red.rotate(120.degrees),
|
|
953
|
+
@red.rotate((120 + 360/5.0).degrees),
|
|
954
|
+
@red.rotate((120 + 2*360/5.0).degrees),
|
|
955
|
+
@red.rotate((120 + 3*360/5.0).degrees),
|
|
956
|
+
@red.rotate((120 + 4*360/5.0).degrees)
|
|
957
|
+
]
|
|
958
|
+
end
|
|
959
|
+
end
|
|
960
|
+
|
|
961
|
+
describe 'warmer' do
|
|
962
|
+
it 'does nothing if at the warmest hue' do
|
|
963
|
+
@red.rotate!(Color::WARMEST_HUE)
|
|
964
|
+
@red.warmer.should == @red
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
it 'does nothing if at the coldest hue' do
|
|
968
|
+
@red.rotate!(Color::COLDEST_HUE)
|
|
969
|
+
@red.warmer.should == @red
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
describe 'direction' do
|
|
973
|
+
before do
|
|
974
|
+
@red.rotate!(0.5)
|
|
975
|
+
end
|
|
976
|
+
|
|
977
|
+
describe 'hue is between 0 degrees and 240 degrees' do
|
|
978
|
+
it 'defaults to rotating 10 degrees lower' do
|
|
979
|
+
@red.warmer.h.should be_within(TOLERANCE).of( 0.5 - 10/360.0 )
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
it 'will not go below the warmest point' do
|
|
983
|
+
# currently at 180
|
|
984
|
+
@red.rotate!(-175.degrees) # to 5 degrees
|
|
985
|
+
@red.warmer.h.should be_within(TOLERANCE).of(0.0) # subtract 10 degrees, should stop at 0
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
it 'takes an custom rotation amount' do
|
|
989
|
+
@red.warmer(0.4).h.should be_within(TOLERANCE).of(0.5 - 0.4)
|
|
990
|
+
end
|
|
991
|
+
end
|
|
992
|
+
|
|
993
|
+
describe "hue is between 240 degrees and 360" do
|
|
994
|
+
before do
|
|
995
|
+
@red.rotate! 0.25 # 270 degrees
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
it 'defaults to rotating 10 degrees higher' do
|
|
999
|
+
@red.warmer.h.should be_within( TOLERANCE ).of( 0.75 + 10/360.0 )
|
|
1000
|
+
end
|
|
1001
|
+
|
|
1002
|
+
it 'takes a custom rotation amount' do
|
|
1003
|
+
@red.warmer(0.2).h.should be_within( TOLERANCE ).of( 0.95 )
|
|
1004
|
+
end
|
|
1005
|
+
|
|
1006
|
+
it 'will not go higher than 360' do
|
|
1007
|
+
@red.warmer(0.3).h.should be_within( TOLERANCE ).of( 0.0 )
|
|
1008
|
+
end
|
|
1009
|
+
end
|
|
1010
|
+
end
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
describe 'cooler' do
|
|
1014
|
+
it 'does nothing if at the warmest hue' do
|
|
1015
|
+
@red.rotate!(Color::WARMEST_HUE)
|
|
1016
|
+
@red.cooler.should == @red
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
it 'does nothing if at the coldest hue' do
|
|
1020
|
+
@red.rotate!(Color::COLDEST_HUE)
|
|
1021
|
+
@red.cooler.should == @red
|
|
1022
|
+
end
|
|
1023
|
+
|
|
1024
|
+
describe 'direction' do
|
|
1025
|
+
before do
|
|
1026
|
+
@red.rotate!(0.5)
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1029
|
+
describe 'hue is between 0 degrees and 240 degrees' do
|
|
1030
|
+
it 'defaults to rotating 10 degrees higher' do
|
|
1031
|
+
@red.cooler.h.should be_within(TOLERANCE).of( 0.5 + 10/360.0 )
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
it 'will not go below the coolest point' do
|
|
1035
|
+
# currently at 180
|
|
1036
|
+
@red.rotate!(60.degrees) # change to 235 degrees
|
|
1037
|
+
@red.cooler.h.should be_within(TOLERANCE).of(Color::COLDEST_HUE) # adding 10 degrees should stop at 240
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
it 'takes an custom rotation amount' do
|
|
1041
|
+
@red.cooler(0.1).h.should be_within(TOLERANCE).of(0.5 + 0.1)
|
|
1042
|
+
end
|
|
1043
|
+
end
|
|
1044
|
+
|
|
1045
|
+
describe "hue is between 240 degrees and 360" do
|
|
1046
|
+
before do
|
|
1047
|
+
@red.rotate! 0.25 # 270 degrees = 0.75
|
|
1048
|
+
end
|
|
1049
|
+
|
|
1050
|
+
it 'defaults to rotating 10 degrees lower' do
|
|
1051
|
+
@red.cooler.h.should be_within( TOLERANCE ).of( 0.75 - 10/360.0 )
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
it 'takes a custom rotation amount' do
|
|
1055
|
+
@red.cooler(0.05).h.should be_within( TOLERANCE ).of( 0.70 )
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
it 'will not go lower than than 240 degress' do
|
|
1059
|
+
@red.cooler(0.1).h.should be_within( TOLERANCE ).of( Color::COLDEST_HUE )
|
|
1060
|
+
end
|
|
1061
|
+
end
|
|
1062
|
+
end
|
|
1063
|
+
end
|
|
1064
|
+
end
|
|
1065
|
+
|
|
1066
|
+
describe 'combining colors' do
|
|
1067
|
+
before :all do
|
|
1068
|
+
@black = Color.new('#000')
|
|
1069
|
+
@yellow = Color.new(:lightyellow)
|
|
1070
|
+
@trans = Color.new(:lightyellow, :alpha => 0.5)
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
describe 'layering' do
|
|
1074
|
+
before do
|
|
1075
|
+
@white = Color.new('#FFF')
|
|
1076
|
+
@shadow = Color.new('#000', :alpha => 0.5)
|
|
1077
|
+
@dark_blue = Color.new(20,40,60, :alpha => 0.5)
|
|
1078
|
+
end
|
|
1079
|
+
|
|
1080
|
+
describe 'r, g, b values' do
|
|
1081
|
+
describe 'opaque top layer' do
|
|
1082
|
+
it 'should have the r, g, b values of the top layer' do
|
|
1083
|
+
color = @shadow.layer(@white)
|
|
1084
|
+
color.r.should == 1.0
|
|
1085
|
+
color.g.should == 1.0
|
|
1086
|
+
color.b.should == 1.0
|
|
1087
|
+
end
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
describe 'opaque bottom layer' do
|
|
1091
|
+
before do
|
|
1092
|
+
@color = @white.layer(@shadow)
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
it 'should mix the r, g, and b in proportion to the top layer\'s alpha' do
|
|
1096
|
+
@color.r.should == 0.5
|
|
1097
|
+
@color.g.should == 0.5
|
|
1098
|
+
@color.b.should == 0.5
|
|
1099
|
+
@color.alpha.should == 1.0
|
|
1100
|
+
|
|
1101
|
+
red = Color.new(153,0,0, :alpha => 0.25)
|
|
1102
|
+
color = @white.layer(red)
|
|
1103
|
+
color.r.should == 0.6*0.25 + 1.0*0.75
|
|
1104
|
+
color.g.should == 0*0.25 + 1.0*0.75
|
|
1105
|
+
color.b.should == 0*0.25 + 1.0*0.75
|
|
1106
|
+
end
|
|
1107
|
+
end
|
|
1108
|
+
end
|
|
1109
|
+
|
|
1110
|
+
describe 'alpha blending' do
|
|
1111
|
+
it 'should be 1.0 if bottom layer is opaque' do
|
|
1112
|
+
color = @white.layer(@shadow)
|
|
1113
|
+
color.alpha.should == 1.0
|
|
1114
|
+
end
|
|
1115
|
+
|
|
1116
|
+
it 'should be 1.0 if the top layer is opaque' do
|
|
1117
|
+
color = @shadow.layer(@white)
|
|
1118
|
+
color.alpha.should == 1.0
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
it 'should have an alpha greater than or equal to the composites' do
|
|
1122
|
+
color = @dark_blue.layer(@shadow)
|
|
1123
|
+
(color.alpha >= @dark_blue.alpha).should be_true
|
|
1124
|
+
(color.alpha >= @shadow.alpha).should be_true
|
|
1125
|
+
end
|
|
1126
|
+
|
|
1127
|
+
it 'should calculate the blending of two alphas properly' do
|
|
1128
|
+
color = @dark_blue.layer(@shadow)
|
|
1129
|
+
color.alpha.should == 0.75 # 0.5 for the base color, plus 0.5 of the remaining transparency
|
|
1130
|
+
end
|
|
1131
|
+
end
|
|
1132
|
+
end
|
|
1133
|
+
|
|
1134
|
+
describe 'mix' do
|
|
1135
|
+
it 'should not affect either color' do
|
|
1136
|
+
black = @black.dup
|
|
1137
|
+
yellow = @yellow.dup
|
|
1138
|
+
@black.mix(@yellow)
|
|
1139
|
+
@black.should == black
|
|
1140
|
+
@yellow.should == yellow
|
|
1141
|
+
end
|
|
1142
|
+
|
|
1143
|
+
it 'mixes half of each by default' do
|
|
1144
|
+
color = @black.mix(@yellow)
|
|
1145
|
+
color.r.should == (@yellow.r/2.0)
|
|
1146
|
+
color.g.should == (@yellow.g/2.0)
|
|
1147
|
+
color.b.should == (@yellow.b/2.0)
|
|
1148
|
+
color.alpha.should == 1.0
|
|
1149
|
+
end
|
|
1150
|
+
|
|
1151
|
+
it 'mixes alphas' do
|
|
1152
|
+
color = @black.mix(@trans)
|
|
1153
|
+
color.r.should == (@yellow.r/2.0)
|
|
1154
|
+
color.g.should == (@yellow.g/2.0)
|
|
1155
|
+
color.b.should == (@yellow.b/2.0)
|
|
1156
|
+
color.alpha.should == 0.75
|
|
1157
|
+
end
|
|
1158
|
+
|
|
1159
|
+
it 'returns a copy, and does not alter the original' do
|
|
1160
|
+
color = @black.mix(@trans)
|
|
1161
|
+
color.should_not === @black
|
|
1162
|
+
color.should_not === @trans
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
describe 'on another ratio' do
|
|
1166
|
+
it 'will mix on a ratio' do
|
|
1167
|
+
color = @black.mix(@trans, 0.25)
|
|
1168
|
+
color.r.should == @trans.r*0.25
|
|
1169
|
+
color.b.should == @trans.b*0.25
|
|
1170
|
+
color.g.should == @trans.g*0.25
|
|
1171
|
+
color.alpha.should == 1.0*0.75 + 0.5*0.25
|
|
1172
|
+
end
|
|
1173
|
+
|
|
1174
|
+
describe '#percent alternate syntax' do
|
|
1175
|
+
it 'sets the mix ratio on the color being mixed in' do
|
|
1176
|
+
@trans.percent(13)
|
|
1177
|
+
@trans.mix_ratio.should == 0.13
|
|
1178
|
+
end
|
|
1179
|
+
|
|
1180
|
+
it 'will be used by the mix when applied to the first color' do
|
|
1181
|
+
color = @black.percent(75).mix(@trans)
|
|
1182
|
+
color.r.should == @trans.r*0.25
|
|
1183
|
+
color.b.should == @trans.b*0.25
|
|
1184
|
+
color.g.should == @trans.g*0.25
|
|
1185
|
+
color.alpha.should == 1.0*0.75 + 0.5*0.25
|
|
1186
|
+
end
|
|
1187
|
+
|
|
1188
|
+
it 'will be used by the mix when applied to the second color' do
|
|
1189
|
+
color = @black.mix(@trans.percent(25))
|
|
1190
|
+
color.r.should == @trans.r*0.25
|
|
1191
|
+
color.b.should == @trans.b*0.25
|
|
1192
|
+
color.g.should == @trans.g*0.25
|
|
1193
|
+
color.alpha.should == 1.0*0.75 + 0.5*0.25
|
|
1194
|
+
end
|
|
1195
|
+
|
|
1196
|
+
it 'consumes the mix ratio' do
|
|
1197
|
+
color = @black.percent(75).mix(@trans.percent(75))
|
|
1198
|
+
@black.mix_ratio.should be_nil
|
|
1199
|
+
@trans.mix_ratio.should be_nil
|
|
1200
|
+
end
|
|
1201
|
+
end
|
|
1202
|
+
end
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
describe 'flatten' do
|
|
1206
|
+
it 'does not affect colors with an alpha of 1' do
|
|
1207
|
+
@black.background = Color.new(:white)
|
|
1208
|
+
color = @black.flatten
|
|
1209
|
+
color.should == @black
|
|
1210
|
+
end
|
|
1211
|
+
|
|
1212
|
+
it 'layers the transparent color onto the background' do
|
|
1213
|
+
@yellow.background = @black
|
|
1214
|
+
color = @yellow.flatten
|
|
1215
|
+
layered = @black.layer(@yellow)
|
|
1216
|
+
color.should == layered
|
|
1217
|
+
end
|
|
1218
|
+
|
|
1219
|
+
it 'ignores the alpha of the background' do
|
|
1220
|
+
background = Color.new(:white, :alpha => 0.5)
|
|
1221
|
+
@yellow.background = background
|
|
1222
|
+
color = @yellow.flatten
|
|
1223
|
+
|
|
1224
|
+
background.alpha = 1.0
|
|
1225
|
+
color.should == background.layer(@yellow)
|
|
1226
|
+
end
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
describe 'stepping' do
|
|
1230
|
+
before :all do
|
|
1231
|
+
@black = Color.new('#000')
|
|
1232
|
+
@yellow = Color.new(:lightyellow, :alpha => 0.5)
|
|
1233
|
+
@steps = @black.step(@yellow)
|
|
1234
|
+
end
|
|
1235
|
+
|
|
1236
|
+
it 'returs an array' do
|
|
1237
|
+
@steps.is_a?(Array).should be_true
|
|
1238
|
+
end
|
|
1239
|
+
|
|
1240
|
+
it 'has 10 steps by default' do
|
|
1241
|
+
@steps.size.should == 10
|
|
1242
|
+
end
|
|
1243
|
+
|
|
1244
|
+
it 'first color should be the starting point (dupped)' do
|
|
1245
|
+
@steps.first.should == @black
|
|
1246
|
+
@steps.first.should_not === @black
|
|
1247
|
+
end
|
|
1248
|
+
|
|
1249
|
+
it 'last color should be the last point (dupped)' do
|
|
1250
|
+
@steps.last.should == @yellow
|
|
1251
|
+
@steps.last.should_not === @yellow
|
|
1252
|
+
end
|
|
1253
|
+
|
|
1254
|
+
it 'interior steps should be equally spaced colors between the two' do
|
|
1255
|
+
mid = @steps[4]
|
|
1256
|
+
mid.r.should == @yellow.r/2.0
|
|
1257
|
+
mid.g.should == @yellow.g/2.0
|
|
1258
|
+
mid.b.should == @yellow.b/2.0
|
|
1259
|
+
end
|
|
1260
|
+
|
|
1261
|
+
it 'has takes optional number of steps' do
|
|
1262
|
+
@black.step(@yellow, 5).size.should == 5
|
|
1263
|
+
end
|
|
1264
|
+
end
|
|
1265
|
+
end
|
|
1266
|
+
end
|
|
1267
|
+
|
|
1268
|
+
describe 'rendering' do
|
|
1269
|
+
before do
|
|
1270
|
+
Color.render_as = nil
|
|
1271
|
+
end
|
|
1272
|
+
|
|
1273
|
+
it 'inspects' do
|
|
1274
|
+
color = Color.new('#000')
|
|
1275
|
+
color.inspect.should == "#<#{color.class}:#{color.object_id} @alpha=#{color.alpha} @r=#{color.r} @g=#{color.g} @b=#{color.b}>"
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
describe 'class level render_as' do
|
|
1279
|
+
it 'defaults to :hex' do
|
|
1280
|
+
Color.render_as.should == :hex
|
|
1281
|
+
end
|
|
1282
|
+
|
|
1283
|
+
it 'can be set' do
|
|
1284
|
+
Color.render_as = :foo
|
|
1285
|
+
Color.render_as.should == :foo
|
|
1286
|
+
end
|
|
1287
|
+
end
|
|
1288
|
+
|
|
1289
|
+
describe '#render' do
|
|
1290
|
+
it 'renders to the default render_as method without transparency' do
|
|
1291
|
+
color = Color.new(0,0,0)
|
|
1292
|
+
color.render.should == '#000000'
|
|
1293
|
+
end
|
|
1294
|
+
|
|
1295
|
+
it 'renders as rgba if there is transparency' do
|
|
1296
|
+
color = Color.new(0.5, 0.5, 0.5, :alpha => 0.5)
|
|
1297
|
+
color.render.should == "rgba(50.0%, 50.0%, 50.0%, 0.5)"
|
|
1298
|
+
end
|
|
1299
|
+
|
|
1300
|
+
describe 'specific render methods' do
|
|
1301
|
+
describe ':hex' do
|
|
1302
|
+
it 'will render as :hex if alpha is 1' do
|
|
1303
|
+
Color.render_as = :rgb
|
|
1304
|
+
color = Color.new(0,0,0)
|
|
1305
|
+
color.render(:hex).should == '#000000'
|
|
1306
|
+
end
|
|
1307
|
+
|
|
1308
|
+
it 'will render as :rgba if alpha is less than 1' do
|
|
1309
|
+
Color.render_as = :hsl
|
|
1310
|
+
color = Color.new(0,0,0, :alpha => 0.9)
|
|
1311
|
+
color.render(:hex).should == "rgba(0.0%, 0.0%, 0.0%, 0.9)"
|
|
1312
|
+
end
|
|
1313
|
+
|
|
1314
|
+
it 'will render as :hex if render_as is set that way' do
|
|
1315
|
+
Color.render_as = :hex
|
|
1316
|
+
color = Color.new(0,0,0)
|
|
1317
|
+
color.render.should == '#000000'
|
|
1318
|
+
end
|
|
1319
|
+
|
|
1320
|
+
it 'will render as :rgba if render_as is set that way but alpha is less than 1' do
|
|
1321
|
+
Color.render_as = :hex
|
|
1322
|
+
color = Color.new(0,0,0, :alpha => 0.9)
|
|
1323
|
+
color.render.should == "rgba(0.0%, 0.0%, 0.0%, 0.9)"
|
|
1324
|
+
end
|
|
1325
|
+
end
|
|
1326
|
+
|
|
1327
|
+
describe ':hsl' do
|
|
1328
|
+
it 'will render as :hsl from #render if the alpha is 1' do
|
|
1329
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1330
|
+
color.set_hsl
|
|
1331
|
+
color.render(:hsl).should == "hsl(#{(color.h*360).round}, #{color.s*100}%, #{color.l*100}%)"
|
|
1332
|
+
end
|
|
1333
|
+
|
|
1334
|
+
it 'will render as hsla from #render if the alpha is less than 1' do
|
|
1335
|
+
color = Color.new(0.5, 0.5, 0.5, :alpha => 0.75)
|
|
1336
|
+
color.set_hsl
|
|
1337
|
+
color.render(:hsl).should == "hsla(#{(color.h*360).round}, #{color.s*100}%, #{color.l*100}%, 0.75)"
|
|
1338
|
+
end
|
|
1339
|
+
|
|
1340
|
+
it "will render this way when the render_as is set to it and alpha is 1" do
|
|
1341
|
+
Color.render_as = :hsl
|
|
1342
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1343
|
+
color.set_hsl
|
|
1344
|
+
color.render.should == "hsl(#{(color.h*360).round}, #{color.s*100}%, #{color.l*100}%)"
|
|
1345
|
+
end
|
|
1346
|
+
|
|
1347
|
+
it 'wil render as hsla with a render_as of :hsl if the alpha is less than 1' do
|
|
1348
|
+
Color.render_as = :hsl
|
|
1349
|
+
color = Color.new(0.5, 0.5, 0.5, :alpha => 0.75)
|
|
1350
|
+
color.set_hsl
|
|
1351
|
+
color.render.should == "hsla(#{(color.h*360).round}, #{color.s*100}%, #{color.l*100}%, 0.75)"
|
|
1352
|
+
end
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1355
|
+
describe ':hsla' do
|
|
1356
|
+
it 'will render as :hsla if alpha is 1' do
|
|
1357
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1358
|
+
color.set_hsl
|
|
1359
|
+
color.render(:hsla).should == "hsla(#{(color.h*360).round}, #{color.s*100}%, #{color.l*100}%, 1.0)"
|
|
1360
|
+
end
|
|
1361
|
+
|
|
1362
|
+
it 'will render as :hsla if alpha is less than 1' do
|
|
1363
|
+
color = Color.new(0.5, 0.5, 0.5, :alpha => 0.2)
|
|
1364
|
+
color.set_hsl
|
|
1365
|
+
color.render(:hsla).should == "hsla(#{(color.h*360).round}, #{color.s*100}%, #{color.l*100}%, 0.2)"
|
|
1366
|
+
end
|
|
1367
|
+
|
|
1368
|
+
it 'will render as :hsla when the Colol render_as is set that way' do
|
|
1369
|
+
Color.render_as = :hsla
|
|
1370
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1371
|
+
color.set_hsl
|
|
1372
|
+
color.render.should == "hsla(#{(color.h*360).round}, #{color.s*100}%, #{color.l*100}%, 1.0)"
|
|
1373
|
+
end
|
|
1374
|
+
end
|
|
1375
|
+
|
|
1376
|
+
describe ':rgb' do
|
|
1377
|
+
it 'will render as :rgb from #render if the alpha is 1' do
|
|
1378
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1379
|
+
color.render(:rgb).should == "rgb(#{color.r*100}%, #{color.g*100}%, #{color.b*100}%)"
|
|
1380
|
+
end
|
|
1381
|
+
|
|
1382
|
+
it 'will render as rgba from #render if the alpha is less than 1' do
|
|
1383
|
+
color = Color.new(0.5, 0.5, 0.5, :alpha => 0.75)
|
|
1384
|
+
color.render(:rgb).should == "rgba(#{color.r*100}%, #{color.g*100}%, #{color.b*100}%, 0.75)"
|
|
1385
|
+
end
|
|
1386
|
+
|
|
1387
|
+
it "will render this way when the render_as is set to it and alpha is 1" do
|
|
1388
|
+
Color.render_as = :rgb
|
|
1389
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1390
|
+
color.render.should == "rgb(#{color.r*100}%, #{color.g*100}%, #{color.b*100}%)"
|
|
1391
|
+
end
|
|
1392
|
+
|
|
1393
|
+
it 'wil render as rgba with a render_as of :rgb if the alpha is less than 1' do
|
|
1394
|
+
Color.render_as = :rgb
|
|
1395
|
+
color = Color.new(0.5, 0.5, 0.5, :alpha => 0.75)
|
|
1396
|
+
color.render(:rgb).should == "rgba(#{color.r*100}%, #{color.g*100}%, #{color.b*100}%, 0.75)"
|
|
1397
|
+
end
|
|
1398
|
+
end
|
|
1399
|
+
|
|
1400
|
+
describe ':rgba' do
|
|
1401
|
+
it 'will render as :rgba if alpha is 1' do
|
|
1402
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1403
|
+
color.set_rgb
|
|
1404
|
+
color.render(:rgba).should == "rgba(#{color.r*100}%, #{color.g*100}%, #{color.b*100}%, 1.0)"
|
|
1405
|
+
end
|
|
1406
|
+
|
|
1407
|
+
it 'will render as :rgba if alpha is less than 1' do
|
|
1408
|
+
color = Color.new(0.5, 0.5, 0.5, :alpha => 0.2)
|
|
1409
|
+
color.set_rgb
|
|
1410
|
+
color.render(:rgba).should == "rgba(#{color.r*100}%, #{color.g*100}%, #{color.b*100}%, 0.2)"
|
|
1411
|
+
end
|
|
1412
|
+
|
|
1413
|
+
it 'will render as :rgba when the Colol render_as is set that way' do
|
|
1414
|
+
Color.render_as = :rgba
|
|
1415
|
+
color = Color.new(0.5, 0.5, 0.5)
|
|
1416
|
+
color.set_rgb
|
|
1417
|
+
color.render.should == "rgba(#{color.r*100}%, #{color.g*100}%, #{color.b*100}%, 1.0)"
|
|
1418
|
+
end
|
|
1419
|
+
end
|
|
1420
|
+
end
|
|
1421
|
+
|
|
1422
|
+
describe 'flattened' do
|
|
1423
|
+
it 'will render as the render_as type when opaque' do
|
|
1424
|
+
Color.render_as = :hsl
|
|
1425
|
+
color = Color.new(:black)
|
|
1426
|
+
color.render(:flat).should == Color.new(:black).render_as_hsl
|
|
1427
|
+
end
|
|
1428
|
+
|
|
1429
|
+
it 'will flatten the color before rendering' do
|
|
1430
|
+
Color.render_as = :rgb
|
|
1431
|
+
color = Color.new(:black, :alpha => 0.5)
|
|
1432
|
+
color.render(:flat).should == Color.new(0.5,0.5,0.5).render_as_rgb
|
|
1433
|
+
end
|
|
1434
|
+
|
|
1435
|
+
it 'will render as the non-alpha type even with alhpa' do
|
|
1436
|
+
Color.render_as = :hex
|
|
1437
|
+
color = Color.new(:black, :alpha => 0.5)
|
|
1438
|
+
color.render(:flat).should == Color.new(0.5,0.5,0.5).render_as_hex
|
|
1439
|
+
end
|
|
1440
|
+
end
|
|
1441
|
+
|
|
1442
|
+
it 'aliases to #to_s' do
|
|
1443
|
+
Color.new(:black).render(:rgba).should == Color.new(:black).to_s(:rgba)
|
|
1444
|
+
end
|
|
1445
|
+
end
|
|
1446
|
+
end
|
|
1447
|
+
end
|