threedaymonk-colormath 0.1.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/README.md +42 -0
- data/lib/colormath.rb +28 -0
- data/lib/colormath/blend.rb +23 -0
- data/lib/colormath/color.rb +36 -0
- data/lib/colormath/color/hsl.rb +78 -0
- data/lib/colormath/color/rgb.rb +63 -0
- data/lib/colormath/version.rb +9 -0
- data/test/blend_test.rb +33 -0
- data/test/conversion_test.rb +104 -0
- data/test/hex_decoding_test.rb +56 -0
- data/test/hsl_test.rb +44 -0
- data/test/rgb_test.rb +44 -0
- metadata +75 -0
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
ColorMath
|
2
|
+
=========
|
3
|
+
|
4
|
+
A simple Ruby library to perform operations on RGB and HSL colours.
|
5
|
+
|
6
|
+
Usage
|
7
|
+
-----
|
8
|
+
|
9
|
+
Instantiate an RGB (red, green, blue) colour:
|
10
|
+
|
11
|
+
orange = ColorMath::RGB.new(1.0, 0.5, 0)
|
12
|
+
|
13
|
+
Or from a hex value via a helper method:
|
14
|
+
|
15
|
+
white = ColorMath::hex_color("#fff")
|
16
|
+
blue = ColorMath::hex_color("#0000ff")
|
17
|
+
|
18
|
+
Instantiate an HSL (hue, saturation, luminance) colour:
|
19
|
+
|
20
|
+
pink = ColorMath::HSL.new(350, 1, 0.88)
|
21
|
+
|
22
|
+
Retrieve the RGB components of a colour:
|
23
|
+
|
24
|
+
pink.red # => 1.0
|
25
|
+
pink.green # => 0.76
|
26
|
+
pink.blue # => 0.8
|
27
|
+
|
28
|
+
Or the HSL components:
|
29
|
+
|
30
|
+
orange.hue # => 30.0
|
31
|
+
orange.saturation # => 1.0
|
32
|
+
orange.luminance # => 0.5
|
33
|
+
|
34
|
+
Combine two colours via an alpha blend, e.g. 30% orange on white:
|
35
|
+
|
36
|
+
combined = ColorMath::Blend.alpha(white, orange, 0.3)
|
37
|
+
|
38
|
+
Convert a colour to hexadecimal representation:
|
39
|
+
|
40
|
+
combined.hex # => "#ffd8b2"
|
41
|
+
|
42
|
+
That’s it. It only does the basics that I need for the job in hand, but it’s probably a good basis for extension.
|
data/lib/colormath.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module ColorMath
|
2
|
+
ParsingError = Class.new(RuntimeError)
|
3
|
+
|
4
|
+
# Instantiate an RGB colour from a 3- or 6-digit hexadecimal representation.
|
5
|
+
# "#abc", "#abcdef", "abc", and "abcdef" are all valid.
|
6
|
+
#
|
7
|
+
# Invalid representations will raise a ParsingError.
|
8
|
+
#
|
9
|
+
def hex_color(s)
|
10
|
+
if m = s.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i)
|
11
|
+
RGB.new( m[1].to_i(16) / 255.0,
|
12
|
+
m[2].to_i(16) / 255.0,
|
13
|
+
m[3].to_i(16) / 255.0 )
|
14
|
+
elsif m = s.match(/^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i)
|
15
|
+
RGB.new( (m[1] + m[1]).to_i(16) / 255.0,
|
16
|
+
(m[2] + m[2]).to_i(16) / 255.0,
|
17
|
+
(m[3] + m[3]).to_i(16) / 255.0 )
|
18
|
+
else
|
19
|
+
raise ParsingError, "invalid hex sequence '#{s}'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
extend self
|
24
|
+
end
|
25
|
+
|
26
|
+
require "colormath/color"
|
27
|
+
require "colormath/blend"
|
28
|
+
require "colormath/version"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# Blend two or more colours and return a new colour.
|
4
|
+
#
|
5
|
+
module Blend
|
6
|
+
|
7
|
+
# Blend ca with cb. alpha represents the proportion of cb,
|
8
|
+
# i.e. alpha = 0 => ca; alpha = 1 => cb.
|
9
|
+
#
|
10
|
+
def alpha(ca, cb, alpha)
|
11
|
+
for_rgb(ca, cb){ |a, b| (alpha * b + (1 - alpha) * a) }
|
12
|
+
end
|
13
|
+
|
14
|
+
extend self
|
15
|
+
|
16
|
+
private
|
17
|
+
def for_rgb(a, b, &blk)
|
18
|
+
RGB.new(*([:red, :green, :blue].map{ |channel|
|
19
|
+
blk.call(a.__send__(channel), b.__send__(channel))
|
20
|
+
}))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# Color can be mixed into any class that responds to red, green, and blue, where 0 <= c <= 1
|
4
|
+
#
|
5
|
+
module Color
|
6
|
+
EPSILON = 1/256.0
|
7
|
+
|
8
|
+
# Returns true if the RGB components of the two colours differ by less than EPSILON,
|
9
|
+
# i.e. they are the same when represented in 8 bits.
|
10
|
+
#
|
11
|
+
def ==(other)
|
12
|
+
deltas = [ other.red - self.red,
|
13
|
+
other.green - self.green,
|
14
|
+
other.blue - self.blue ].map{ |e| e.abs }
|
15
|
+
deltas.max < EPSILON
|
16
|
+
end
|
17
|
+
|
18
|
+
# The six-digit hexadecimal representation of the colour, e.g. "#cafe66"
|
19
|
+
#
|
20
|
+
def hex
|
21
|
+
"#%02x%02x%02x" % [red * 0xff, green * 0xff, blue * 0xff]
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect(*args)
|
25
|
+
"<%s r=%0.3f g=%0.3f b=%0.3f>" % [self.class.to_s, red, green, blue]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def force_range(v, min, max)
|
30
|
+
[[min, v].max, max].min
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
require "colormath/color/rgb"
|
36
|
+
require "colormath/color/hsl"
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# A colour represented and stored as hue, saturation and luminance components
|
4
|
+
#
|
5
|
+
class HSL
|
6
|
+
include Color
|
7
|
+
|
8
|
+
attr_reader :hue, :saturation, :luminance, :alpha
|
9
|
+
|
10
|
+
# Initialize an HSL colour where:
|
11
|
+
# 0 <= h <= 360
|
12
|
+
# 0 <= s <= 1
|
13
|
+
# 0 <= l <= 1
|
14
|
+
#
|
15
|
+
# Values outside these ranges will be clippped.
|
16
|
+
#
|
17
|
+
def initialize(h, s, l)
|
18
|
+
@hue = force_range(h, 0, 360).to_f
|
19
|
+
@saturation = force_range(s, 0, 1).to_f
|
20
|
+
@luminance = force_range(l, 0, 1).to_f
|
21
|
+
end
|
22
|
+
|
23
|
+
# The red component of the colour in RGB representation where 0 <= r <= 1
|
24
|
+
#
|
25
|
+
def red
|
26
|
+
t = component(hk + (1/3.0))
|
27
|
+
end
|
28
|
+
|
29
|
+
# The green component of the colour in RGB representation where 0 <= g <= 1
|
30
|
+
#
|
31
|
+
def green
|
32
|
+
t = component(hk)
|
33
|
+
end
|
34
|
+
|
35
|
+
# The blue component of the colour in RGB representation where 0 <= b <= 1
|
36
|
+
#
|
37
|
+
def blue
|
38
|
+
t = component(hk - (1/3.0))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def hk
|
43
|
+
hue / 360.0
|
44
|
+
end
|
45
|
+
|
46
|
+
def q
|
47
|
+
@q ||= if luminance < 0.5
|
48
|
+
luminance * (1.0 + saturation)
|
49
|
+
else
|
50
|
+
luminance + saturation - (luminance * saturation)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def p
|
55
|
+
@p ||= 2 * luminance - q
|
56
|
+
end
|
57
|
+
|
58
|
+
def component(t)
|
59
|
+
t = if t < 0
|
60
|
+
t + 1.0
|
61
|
+
elsif t > 1
|
62
|
+
t - 1.0
|
63
|
+
else
|
64
|
+
t
|
65
|
+
end
|
66
|
+
|
67
|
+
if t < (1/6.0)
|
68
|
+
p + ((q - p) * 6.0 * t)
|
69
|
+
elsif (1/6.0) <= t && t < 0.5
|
70
|
+
q
|
71
|
+
elsif 0.5 <= t && t < (2/3.0)
|
72
|
+
p + ((q - p) * 6.0 * (2/3.0 - t))
|
73
|
+
else
|
74
|
+
p
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module ColorMath
|
2
|
+
|
3
|
+
# A colour represented and stored as red, green and blue components
|
4
|
+
#
|
5
|
+
class RGB
|
6
|
+
include Color
|
7
|
+
|
8
|
+
attr_reader :red, :green, :blue
|
9
|
+
|
10
|
+
# Initialize an RGB colour where:
|
11
|
+
# 0 <= r <= 1
|
12
|
+
# 0 <= g <= 1
|
13
|
+
# 0 <= b <= 1
|
14
|
+
#
|
15
|
+
# Values outside these ranges will be clippped.
|
16
|
+
#
|
17
|
+
def initialize(r, g, b)
|
18
|
+
@red = force_range(r, 0, 1).to_f
|
19
|
+
@green = force_range(g, 0, 1).to_f
|
20
|
+
@blue = force_range(b, 0, 1).to_f
|
21
|
+
end
|
22
|
+
|
23
|
+
# The hue component of the colour in HSL representation where 0 <= h < 360
|
24
|
+
#
|
25
|
+
def hue
|
26
|
+
case max
|
27
|
+
when red
|
28
|
+
(60.0 * ((green - blue) / (max - min))) % 360.0
|
29
|
+
when green
|
30
|
+
60.0 * ((blue - red) / (max - min)) + 120.0
|
31
|
+
when blue
|
32
|
+
60.0 * ((red - green) / (max - min)) + 240.0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# The saturation component of the colour in HSL representation where 0 <= s <= 1
|
37
|
+
#
|
38
|
+
def saturation
|
39
|
+
if max == min
|
40
|
+
0
|
41
|
+
elsif luminance <= 0.5
|
42
|
+
(max - min) / (2.0 * luminance)
|
43
|
+
else
|
44
|
+
(max - min) / (2.0 - 2.0 * luminance)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# The luminance component of the colour in HSL representation where 0 <= l <= 1
|
49
|
+
#
|
50
|
+
def luminance
|
51
|
+
0.5 * (max + min)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def min
|
56
|
+
[red, green, blue].min
|
57
|
+
end
|
58
|
+
|
59
|
+
def max
|
60
|
+
[red, green, blue].max
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/test/blend_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class AlphaBlendTest < Test::Unit::TestCase
|
7
|
+
def blend(a, b, alpha)
|
8
|
+
ColorMath::Blend.alpha(ColorMath::hex_color(a), ColorMath::hex_color(b), alpha).hex
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with sample colors" do
|
12
|
+
setup do
|
13
|
+
@background = "#ffffff"
|
14
|
+
@foreground = "#862e8b"
|
15
|
+
end
|
16
|
+
|
17
|
+
should "blend 0% sample" do
|
18
|
+
assert_equal @background, blend(@background, @foreground, 0.0)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "blend 10% sample" do
|
22
|
+
assert_equal "#f2eaf3", blend(@background, @foreground, 0.1)
|
23
|
+
end
|
24
|
+
|
25
|
+
should "blend 30% sample" do
|
26
|
+
assert_equal "#dac0dc", blend(@background, @foreground, 0.3)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "blend 100% sample" do
|
30
|
+
assert_equal @foreground, blend(@background, @foreground, 1.0)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class ConversionTest < Test::Unit::TestCase
|
7
|
+
EPSILON = 1e-2
|
8
|
+
|
9
|
+
EDGE_CASES = [
|
10
|
+
[[1, 0, 0], [ 0, 1, 0.5 ]],
|
11
|
+
[[0.5, 1, 0.5], [120, 1, 0.75]],
|
12
|
+
[[0, 0, 0.5], [240, 1, 0.25]],
|
13
|
+
]
|
14
|
+
|
15
|
+
context "with edge cases" do
|
16
|
+
EDGE_CASES.each do |(r,g,b), (h,s,l)|
|
17
|
+
should "convert RGB(#{r},#{g},#{b}) to HSL(#{h},#{s},#{l})" do
|
18
|
+
c = ColorMath::RGB.new(r, g, b)
|
19
|
+
assert_in_delta h, c.hue, EPSILON
|
20
|
+
assert_in_delta s, c.saturation, EPSILON
|
21
|
+
assert_in_delta l, c.luminance, EPSILON
|
22
|
+
end
|
23
|
+
|
24
|
+
should "convert HSL(#{h},#{s},#{l}) to RGB(#{r},#{g},#{b})" do
|
25
|
+
c = ColorMath::HSL.new(h, s, l)
|
26
|
+
assert_in_delta r, c.red, EPSILON
|
27
|
+
assert_in_delta g, c.green, EPSILON
|
28
|
+
assert_in_delta b, c.blue, EPSILON
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
HSL_SAMPLES = [
|
34
|
+
[267.0, 0.14, 0.17],
|
35
|
+
[322.0, 0.22, 0.54],
|
36
|
+
[211.0, 0.54, 0.19],
|
37
|
+
[347.0, 0.90, 0.38],
|
38
|
+
[184.0, 0.75, 0.13],
|
39
|
+
[177.0, 0.07, 0.14],
|
40
|
+
[ 97.0, 0.93, 0.70],
|
41
|
+
[139.0, 0.04, 0.37],
|
42
|
+
[ 17.0, 0.88, 0.67],
|
43
|
+
[162.0, 0.21, 0.61],
|
44
|
+
[358.0, 0.78, 0.50],
|
45
|
+
[104.0, 0.78, 0.63],
|
46
|
+
[280.0, 0.38, 0.66],
|
47
|
+
[298.0, 0.06, 0.72],
|
48
|
+
[162.0, 0.39, 0.86],
|
49
|
+
[305.0, 0.55, 0.16],
|
50
|
+
[248.0, 0.80, 0.84],
|
51
|
+
[109.0, 0.23, 0.23],
|
52
|
+
[328.0, 0.88, 0.88],
|
53
|
+
[ 26.0, 0.99, 0.52],
|
54
|
+
]
|
55
|
+
|
56
|
+
context "roundtripping HSL -> RGB -> HSL" do
|
57
|
+
HSL_SAMPLES.each do |h,s,l|
|
58
|
+
should "roundtrip HSL(#{h},#{s},#{l})" do
|
59
|
+
hsl = ColorMath::HSL.new(h, s, l)
|
60
|
+
rgb = ColorMath::RGB.new(hsl.red, hsl.green, hsl.blue)
|
61
|
+
|
62
|
+
assert_in_delta h, rgb.hue, EPSILON
|
63
|
+
assert_in_delta s, rgb.saturation, EPSILON
|
64
|
+
assert_in_delta l, rgb.luminance, EPSILON
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
RGB_SAMPLES = [
|
70
|
+
[0.19, 0.41, 0.70],
|
71
|
+
[0.13, 0.22, 0.28],
|
72
|
+
[0.45, 0.44, 0.24],
|
73
|
+
[0.96, 0.94, 0.24],
|
74
|
+
[0.76, 0.01, 0.16],
|
75
|
+
[0.55, 0.96, 0.01],
|
76
|
+
[0.07, 0.61, 0.73],
|
77
|
+
[0.05, 0.58, 0.51],
|
78
|
+
[0.43, 0.05, 0.24],
|
79
|
+
[0.66, 0.80, 0.80],
|
80
|
+
[0.54, 0.35, 0.10],
|
81
|
+
[0.12, 0.41, 0.27],
|
82
|
+
[0.78, 0.32, 0.93],
|
83
|
+
[0.52, 0.15, 0.43],
|
84
|
+
[0.17, 0.26, 0.53],
|
85
|
+
[0.19, 0.96, 0.66],
|
86
|
+
[0.54, 0.36, 0.84],
|
87
|
+
[0.12, 0.89, 0.60],
|
88
|
+
[0.75, 0.03, 0.83],
|
89
|
+
[0.09, 0.35, 0.83],
|
90
|
+
]
|
91
|
+
|
92
|
+
context "roundtripping RGB -> HSL -> RGB" do
|
93
|
+
RGB_SAMPLES.each do |r,g,b|
|
94
|
+
should "roundtrip RGB(#{r},#{g},#{b})" do
|
95
|
+
rgb = ColorMath::RGB.new(r, g, b)
|
96
|
+
hsl = ColorMath::HSL.new(rgb.hue, rgb.saturation, rgb.luminance)
|
97
|
+
|
98
|
+
assert_in_delta r, hsl.red, EPSILON
|
99
|
+
assert_in_delta g, hsl.green, EPSILON
|
100
|
+
assert_in_delta b, hsl.blue, EPSILON
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class HexDecodingTest < Test::Unit::TestCase
|
7
|
+
EPSILON = 1e-3
|
8
|
+
|
9
|
+
should "decode 6-digit hex string with leading #" do
|
10
|
+
c = ColorMath::hex_color("#abcd54")
|
11
|
+
assert_in_delta (0xab / 255.0), c.red, EPSILON
|
12
|
+
assert_in_delta (0xcd / 255.0), c.green, EPSILON
|
13
|
+
assert_in_delta (0x54 / 255.0), c.blue, EPSILON
|
14
|
+
end
|
15
|
+
|
16
|
+
should "decode 6-digit hex string without leading #" do
|
17
|
+
c = ColorMath::hex_color("abcd54")
|
18
|
+
assert_in_delta (0xab / 255.0), c.red, EPSILON
|
19
|
+
assert_in_delta (0xcd / 255.0), c.green, EPSILON
|
20
|
+
assert_in_delta (0x54 / 255.0), c.blue, EPSILON
|
21
|
+
end
|
22
|
+
|
23
|
+
should "decode 3-digit hex string with leading #" do
|
24
|
+
c = ColorMath::hex_color("#a1c")
|
25
|
+
assert_in_delta (0xaa / 255.0), c.red, EPSILON
|
26
|
+
assert_in_delta (0x11 / 255.0), c.green, EPSILON
|
27
|
+
assert_in_delta (0xcc / 255.0), c.blue, EPSILON
|
28
|
+
end
|
29
|
+
|
30
|
+
should "decode 3-digit hex string without leading #" do
|
31
|
+
c = ColorMath::hex_color("a1c")
|
32
|
+
assert_in_delta (0xaa / 255.0), c.red, EPSILON
|
33
|
+
assert_in_delta (0x11 / 255.0), c.green, EPSILON
|
34
|
+
assert_in_delta (0xcc / 255.0), c.blue, EPSILON
|
35
|
+
end
|
36
|
+
|
37
|
+
should "decode 6-digit hex string in upper case" do
|
38
|
+
c = ColorMath::hex_color("#ABCD54")
|
39
|
+
assert_in_delta (0xab / 255.0), c.red, EPSILON
|
40
|
+
assert_in_delta (0xcd / 255.0), c.green, EPSILON
|
41
|
+
assert_in_delta (0x54 / 255.0), c.blue, EPSILON
|
42
|
+
end
|
43
|
+
|
44
|
+
should "decode 3-digit hex string in upper case" do
|
45
|
+
c = ColorMath::hex_color("#A1C")
|
46
|
+
assert_in_delta (0xaa / 255.0), c.red, EPSILON
|
47
|
+
assert_in_delta (0x11 / 255.0), c.green, EPSILON
|
48
|
+
assert_in_delta (0xcc / 255.0), c.blue, EPSILON
|
49
|
+
end
|
50
|
+
|
51
|
+
should "raise a ParsingError when the hex string is invalid" do
|
52
|
+
assert_raises ColorMath::ParsingError do
|
53
|
+
ColorMath::hex_color("kjhhdfs")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/test/hsl_test.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class HSLTest < Test::Unit::TestCase
|
7
|
+
should "be equal if initialized with same values" do
|
8
|
+
assert_equal ColorMath::HSL.new(123, 0.5, 0.7), ColorMath::HSL.new(123, 0.5, 0.7)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "not be equal if initialized with different values" do
|
12
|
+
assert_not_equal ColorMath::HSL.new(124, 0.4, 0.8), ColorMath::HSL.new(123, 0.5, 0.7)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "force hue >= 0" do
|
16
|
+
c = ColorMath::HSL.new(-2, 0, 0)
|
17
|
+
assert_equal 0, c.hue
|
18
|
+
end
|
19
|
+
|
20
|
+
should "force hue <= 360" do
|
21
|
+
c = ColorMath::HSL.new(361, 0, 0)
|
22
|
+
assert_equal 360, c.hue
|
23
|
+
end
|
24
|
+
|
25
|
+
should "force saturation >= 0" do
|
26
|
+
c = ColorMath::HSL.new(0, -1, 0)
|
27
|
+
assert_equal 0, c.saturation
|
28
|
+
end
|
29
|
+
|
30
|
+
should "force saturation <= 1" do
|
31
|
+
c = ColorMath::HSL.new(0, 1.1, 0)
|
32
|
+
assert_equal 1, c.saturation
|
33
|
+
end
|
34
|
+
|
35
|
+
should "force luminance >= 0" do
|
36
|
+
c = ColorMath::HSL.new(0, 0, -1)
|
37
|
+
assert_equal 0, c.luminance
|
38
|
+
end
|
39
|
+
|
40
|
+
should "force luminance <= 1" do
|
41
|
+
c = ColorMath::HSL.new(0, 0, 1.1)
|
42
|
+
assert_equal 1, c.luminance
|
43
|
+
end
|
44
|
+
end
|
data/test/rgb_test.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require "test/unit"
|
3
|
+
require "shoulda"
|
4
|
+
require "colormath"
|
5
|
+
|
6
|
+
class RGBTest < Test::Unit::TestCase
|
7
|
+
should "be equal if initialized with same values" do
|
8
|
+
assert_equal ColorMath::RGB.new(0.3, 0.5, 0.7), ColorMath::RGB.new(0.3, 0.5, 0.7)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "not be equal if initialized with different values" do
|
12
|
+
assert_not_equal ColorMath::RGB.new(0.5, 0.4, 0.8), ColorMath::RGB.new(0.3, 0.5, 0.7)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "force red >= 0" do
|
16
|
+
c = ColorMath::HSL.new(-2, 0, 0)
|
17
|
+
assert_equal 0, c.red
|
18
|
+
end
|
19
|
+
|
20
|
+
should "force red <= 1" do
|
21
|
+
c = ColorMath::RGB.new(1.1, 0, 0)
|
22
|
+
assert_equal 1, c.red
|
23
|
+
end
|
24
|
+
|
25
|
+
should "force green >= 0" do
|
26
|
+
c = ColorMath::RGB.new(0, -1, 0)
|
27
|
+
assert_equal 0, c.green
|
28
|
+
end
|
29
|
+
|
30
|
+
should "force green <= 1" do
|
31
|
+
c = ColorMath::RGB.new(0, 1.1, 0)
|
32
|
+
assert_equal 1, c.green
|
33
|
+
end
|
34
|
+
|
35
|
+
should "force blue >= 0" do
|
36
|
+
c = ColorMath::RGB.new(0, 0, -1)
|
37
|
+
assert_equal 0, c.blue
|
38
|
+
end
|
39
|
+
|
40
|
+
should "force blue <= 1" do
|
41
|
+
c = ColorMath::RGB.new(0, 0, 1.1)
|
42
|
+
assert_equal 1, c.blue
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: threedaymonk-colormath
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Battley
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-09 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: pbattley@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- test/blend_test.rb
|
36
|
+
- test/conversion_test.rb
|
37
|
+
- test/hex_decoding_test.rb
|
38
|
+
- test/hsl_test.rb
|
39
|
+
- test/rgb_test.rb
|
40
|
+
- lib/colormath
|
41
|
+
- lib/colormath/blend.rb
|
42
|
+
- lib/colormath/color
|
43
|
+
- lib/colormath/color/hsl.rb
|
44
|
+
- lib/colormath/color/rgb.rb
|
45
|
+
- lib/colormath/color.rb
|
46
|
+
- lib/colormath/version.rb
|
47
|
+
- lib/colormath.rb
|
48
|
+
has_rdoc: false
|
49
|
+
homepage:
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.2.0
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Colour manipulation library for Ruby
|
74
|
+
test_files: []
|
75
|
+
|