colir 0.0.1
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.
- checksums.yaml +15 -0
- data/.gitignore +4 -0
- data/.travis.yml +14 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +2 -0
- data/LICENCE +19 -0
- data/README.md +186 -0
- data/Rakefile +15 -0
- data/VERSION +1 -0
- data/colir.gemspec +18 -0
- data/lib/colir.rb +357 -0
- data/lib/colir/hslrgb.rb +188 -0
- data/spec/colir_spec.rb +407 -0
- data/spec/helper.rb +10 -0
- data/spec/hslrgb/hsl_spec.rb +69 -0
- data/spec/hslrgb/rgb_spec.rb +80 -0
- data/spec/hslrgb_spec.rb +206 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTE0MzRiMWYxNmUzNjI2NWYwNjg1Mzk1MWEwOWIxYmY1OTUwZWE1Zg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZTJmYzZhOWQ3NWU2MzRiZWZlMmZiZDNmMGI5OTExMDJhZDE3MjE1YQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ODExMDk0MWI1NTMwNzZmMmIwZDk1ZmY0MjA5ODQ2MTlhZTJhNWIyNGM4ZmQ2
|
10
|
+
MDVjNmM0N2EwMDM0ZGE3ZTYxZTU2NjUzNGQ0ODg3MzM3ZGY4MzUyMGM3ZWRh
|
11
|
+
ZTdkYzhhMjYwNjdjZmM3NGQ2YjA4NzMwOGIxMjQ1MTRkZmU3ZmQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODNiOWQ4NDc5Njg2ZmRlMmUzM2JjMWZhMjQ4ODYwZjkzN2JiYzdjODI1ZmE3
|
14
|
+
NTMyZmZhMDA4YzZhNGUwZDRjYzM3ZTlkZGI2ZjY5MzI0YWM5ZGE4ZDQxOGQy
|
15
|
+
Zjc2Mjk2Y2E2ZDI2NzRhNzZiYWI1ZDIzZWNjYjc1YzkxZDI0Mzc=
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENCE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2013 Kyrylo Silin
|
2
|
+
|
3
|
+
This software is provided 'as-is', without any express or implied
|
4
|
+
warranty. In no event will the authors be held liable for any damages
|
5
|
+
arising from the use of this software.
|
6
|
+
|
7
|
+
Permission is granted to anyone to use this software for any purpose,
|
8
|
+
including commercial applications, and to alter it and redistribute it
|
9
|
+
freely, subject to the following restrictions:
|
10
|
+
|
11
|
+
1. The origin of this software must not be misrepresented; you must not
|
12
|
+
claim that you wrote the original software. If you use this software
|
13
|
+
in a product, an acknowledgment in the product documentation would be
|
14
|
+
appreciated but is not required.
|
15
|
+
|
16
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
17
|
+
misrepresented as being the original software.
|
18
|
+
|
19
|
+
3. This notice may not be removed or altered from any source distribution.
|
data/README.md
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
Colir
|
2
|
+
=====
|
3
|
+
|
4
|
+
[![Build Status][ci-badge]][ci-link]
|
5
|
+
|
6
|
+
* Repository: [https://github.com/kyrylo/colir][cr]
|
7
|
+
|
8
|
+
Description
|
9
|
+
-----------
|
10
|
+
|
11
|
+
This tiny library provides support for RGB colours and some simple manipulations
|
12
|
+
with them.
|
13
|
+
|
14
|
+
Installation
|
15
|
+
------------
|
16
|
+
|
17
|
+
gem install colir
|
18
|
+
|
19
|
+
Synopsis
|
20
|
+
--------
|
21
|
+
|
22
|
+
The name Colir means “colour” in Ukrainian (roughly). OK, enough of rant, let's
|
23
|
+
talk about the API instead.
|
24
|
+
|
25
|
+
###### Basics
|
26
|
+
|
27
|
+
You can create colours with human readable names. For example, the following
|
28
|
+
code would create opaque red colour (0xff000000).
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'colir'
|
32
|
+
|
33
|
+
# Create a new Colir.
|
34
|
+
red = Colir.red #=> #<Colir:...>
|
35
|
+
# Get a valid RGB colour, represented as an integer number.
|
36
|
+
red.hex #=> 16711680
|
37
|
+
# Why do you never trust me?
|
38
|
+
red.hex.to_s(16) #=> "ff0000"
|
39
|
+
|
40
|
+
# You can also get the same colour, but with alpha channel.
|
41
|
+
red.hexa #=> 4278190080
|
42
|
+
# Okay, okay!
|
43
|
+
red.hexa.to_s(16) #=> "ff000000"
|
44
|
+
```
|
45
|
+
|
46
|
+
The list of all human readable colour names can be found at [w3schools][w3].
|
47
|
+
Actually, you can create any valid RGB colours, not just the predefined ones.
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
# This is valid.
|
51
|
+
yup = Colir.new(0xff0000) #=> #<Colir:...>
|
52
|
+
# This isn't. There is no such RGB colour.
|
53
|
+
nope = Colir.new(0xff00001) #=> RangeError: out of allowed RGB values
|
54
|
+
```
|
55
|
+
|
56
|
+
###### Transparency
|
57
|
+
|
58
|
+
As you may have noticed, the library supports transparent colours.
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
# Shortcut methods have only 1 parameter, which is transparency. It must lie
|
62
|
+
# within the range of 0..1
|
63
|
+
red = Colir.red(0.3)
|
64
|
+
red.hexa #=> 4278190110
|
65
|
+
red.hexa.to_s(16) #=> "ff00001e"
|
66
|
+
red.transparency #=> 0.3
|
67
|
+
|
68
|
+
# With arbitrary colours you can pass the second parameter.
|
69
|
+
green = Colir.new(0x00ff00, 0.3)
|
70
|
+
green.hexa #=> 16711710
|
71
|
+
green.hexa.to_s(16) #=> "0x00ff001e"
|
72
|
+
green.transparency #=> 0.3
|
73
|
+
|
74
|
+
# The default transparency is 0.0
|
75
|
+
green = Colir.new(0x00ff00)
|
76
|
+
green.transparency #=> 0.0
|
77
|
+
```
|
78
|
+
|
79
|
+
It's possible to adjust a Colir's transparency.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# `#opaque!` and `#transparent!` set a Colir's transparency to `0.0`
|
83
|
+
# and `1.0` respectively.
|
84
|
+
blue = Colir.new(0x0000ff, 0.45)
|
85
|
+
blue.transparency #=> 0.3
|
86
|
+
blue.transparent! #=> (Colir: 0x00ff00e1)
|
87
|
+
blue.transparency #=> 0.0
|
88
|
+
blue.opaque! #=> (Colir: 0x00ff00ff)
|
89
|
+
blue.transparency #=> 1.0
|
90
|
+
|
91
|
+
# You can set your own transparency value.
|
92
|
+
blue.transparency = 0.9 #=> 0.9
|
93
|
+
blue.transparency #=> 0.9
|
94
|
+
|
95
|
+
# But be careful, as the valid value is anything in between 0 and 1.
|
96
|
+
blue.transparency = 1.01 #=> RangeError: ...
|
97
|
+
```
|
98
|
+
|
99
|
+
###### Shades
|
100
|
+
|
101
|
+
Last but not least, you can use colour shades.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
yellow = Colir.yellow
|
105
|
+
yellow.shade #=> 0
|
106
|
+
|
107
|
+
# Let's make it a bit darker.
|
108
|
+
yellow.darken #=> #<Colir:...>
|
109
|
+
yellow.shade #=> -1
|
110
|
+
yellow.hex #=> 13421568
|
111
|
+
|
112
|
+
# Hum, that's not dark enough. Let's do it one more time.
|
113
|
+
yellow.darken
|
114
|
+
yellow.shade #=> -2
|
115
|
+
yellow.hex #=> 10066176
|
116
|
+
|
117
|
+
# Actually, the previous shade was better!
|
118
|
+
yellow.lighten
|
119
|
+
yellow.shade #=> -1
|
120
|
+
yellow.hex #=> 13421568
|
121
|
+
```
|
122
|
+
|
123
|
+
The previous examples modify the Colir object (`#darken` and `#lighten`).
|
124
|
+
Hovewer, there are two other methods that return a new object: `#darker` and
|
125
|
+
`#lighter`.
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
# HEXes
|
129
|
+
orange = Colir.orange
|
130
|
+
orange.hex #=> 16753920
|
131
|
+
orange.darker.hex #=> 13403392
|
132
|
+
orange.hex #=> 16753920
|
133
|
+
|
134
|
+
# Shades
|
135
|
+
orange = Colir.orange
|
136
|
+
orange.shade #=> 0
|
137
|
+
orange.lighter.shade #=> 1
|
138
|
+
orange.shade #=> 0
|
139
|
+
```
|
140
|
+
|
141
|
+
There is a handy way to reset the shade level. Can you guess it? Of course, it's
|
142
|
+
the `#reset_shade` method!
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
indigo = Colir.indigo
|
146
|
+
indigo.lighten
|
147
|
+
indigo.lighten
|
148
|
+
indigo.lighten
|
149
|
+
indigo.lighten
|
150
|
+
indigo.lighten
|
151
|
+
indigo.shades #=> 5
|
152
|
+
indigo.reset_shade #=> #<Colir:...>
|
153
|
+
indigo.shade #=> 0
|
154
|
+
```
|
155
|
+
|
156
|
+
Limitations
|
157
|
+
-----------
|
158
|
+
|
159
|
+
### OS support
|
160
|
+
|
161
|
+
Colir is a cross-platform library.
|
162
|
+
|
163
|
+
### Rubies
|
164
|
+
|
165
|
+
* Ruby 1.9.3 and higher
|
166
|
+
* Rubinius 2.0.0rc1 and higher (mode 1.9 and higher)
|
167
|
+
|
168
|
+
Initially I wanted to supprot JRuby 1.7.3 (mode 1.9), but it has a [critical bug
|
169
|
+
in `BigDecimal` library](http://jira.codehaus.org/browse/JRUBY-7101), which
|
170
|
+
Colir actively utilises.
|
171
|
+
|
172
|
+
Credits
|
173
|
+
-------
|
174
|
+
|
175
|
+
* The first contributor badge goes to [kachick][kachick]
|
176
|
+
|
177
|
+
Licence
|
178
|
+
-------
|
179
|
+
|
180
|
+
The project uses Zlib licence. See LICENCE file for more information.
|
181
|
+
|
182
|
+
[cr]: https://github.com/kyrylo/colir
|
183
|
+
[ci-badge]: https://travis-ci.org/kyrylo/colir.png?branch=master "Build status"
|
184
|
+
[ci-link]: https://travis-ci.org/kyrylo/colir/ "Build history"
|
185
|
+
[w3]: http://www.w3schools.com/cssref/css_colornames.asp
|
186
|
+
[kachick]: https://github.com/kachick
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
def quiet
|
2
|
+
ENV['VERBOSE'] ? '' : '-q'
|
3
|
+
end
|
4
|
+
|
5
|
+
def test_files
|
6
|
+
paths = FileList['spec/**/*_spec.rb']
|
7
|
+
paths.shuffle!.join(' ')
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Run tests"
|
11
|
+
task :test do
|
12
|
+
exec "bacon -Ispec #{ quiet } #{ test_files }"
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => :test
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/colir.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'colir'
|
3
|
+
s.version = File.read('VERSION')
|
4
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
5
|
+
s.summary = 'Colir means colour in Ukrainan. In Ruby it means HEX colour'
|
6
|
+
s.description = 'This library is about HEX colours.'
|
7
|
+
s.author = 'Kyrylo Silin'
|
8
|
+
s.email = 'kyrylosilin@gmail.com'
|
9
|
+
s.homepage = 'https://github.com/kyrylo/colir'
|
10
|
+
s.licenses = 'zlib'
|
11
|
+
|
12
|
+
s.require_path = 'lib'
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
|
15
|
+
s.add_development_dependency 'bacon'
|
16
|
+
s.add_development_dependency 'rake'
|
17
|
+
s.add_development_dependency 'pry'
|
18
|
+
end
|
data/lib/colir.rb
ADDED
@@ -0,0 +1,357 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
require_relative 'colir/hslrgb'
|
4
|
+
|
5
|
+
# This tiny library provides support for RGB colours and some simple
|
6
|
+
# manipulations with them. See README.md for more information.
|
7
|
+
class Colir
|
8
|
+
|
9
|
+
# The VERSION file must be in the root directory of the library.
|
10
|
+
VERSION_FILE = File.expand_path('../../VERSION', __FILE__)
|
11
|
+
|
12
|
+
VERSION = File.exist?(VERSION_FILE) ?
|
13
|
+
File.read(VERSION_FILE).chomp : '(could not find VERSION file)'
|
14
|
+
|
15
|
+
# The list for human readable colour according to the HTML and CSS color
|
16
|
+
# specification. Does not include alpha channel.
|
17
|
+
COLIRS = {
|
18
|
+
alice_blue: 0xf0f8ff,
|
19
|
+
antique_white: 0xfaebd7,
|
20
|
+
aqua: 0x00ffff,
|
21
|
+
aquamarine: 0x7fffd4,
|
22
|
+
azure: 0xf0ffff,
|
23
|
+
beige: 0xf5f5dc,
|
24
|
+
bisque: 0xffe4c4,
|
25
|
+
black: 0x000000,
|
26
|
+
blanched_almond: 0xffebcd,
|
27
|
+
blue: 0x0000ff,
|
28
|
+
blue_violet: 0x8a2be2,
|
29
|
+
brown: 0xa52a2a,
|
30
|
+
burly_wood: 0xdeb887,
|
31
|
+
cadet_blue: 0x5f9ea0,
|
32
|
+
chartreuse: 0x7fff00,
|
33
|
+
chocolate: 0xd2691e,
|
34
|
+
coral: 0xff7f50,
|
35
|
+
cornflower_blue: 0x6495ed,
|
36
|
+
cornsilk: 0xfff8dc,
|
37
|
+
crimson: 0xdc143c,
|
38
|
+
cyan: 0x00ffff,
|
39
|
+
dark_blue: 0x00008b,
|
40
|
+
dark_cyan: 0x008b8b,
|
41
|
+
dark_golden_rod: 0xb8860b,
|
42
|
+
dark_gray: 0xa9a9a9,
|
43
|
+
dark_green: 0xa9a9a9,
|
44
|
+
dark_khaki: 0xbdb76b,
|
45
|
+
dark_magenta: 0x8b008b,
|
46
|
+
dark_olive_green: 0x556b2f,
|
47
|
+
dark_orange: 0xff8c00,
|
48
|
+
dark_orchid: 0x9932cc,
|
49
|
+
dark_red: 0x9932cc,
|
50
|
+
dark_salmon: 0xe9967a,
|
51
|
+
dark_sea_green: 0x8fbc8f,
|
52
|
+
dark_slate_blue: 0x483d8b,
|
53
|
+
dark_slate_gray: 0x2f4f4f,
|
54
|
+
dark_turquoise: 0x00ced1,
|
55
|
+
dark_violet: 0x9400d3,
|
56
|
+
deep_pink: 0xff1493,
|
57
|
+
deep_sky_blue: 0x00bfff,
|
58
|
+
dim_gray: 0x696969,
|
59
|
+
dim_grey: 0x696969,
|
60
|
+
dodger_blue: 0x1e90ff,
|
61
|
+
fire_brick: 0xb22222,
|
62
|
+
floral_white: 0xfffaf0,
|
63
|
+
forest_green: 0x228b22,
|
64
|
+
fuchsia: 0xff00ff,
|
65
|
+
gainsboro: 0xdcdcdc,
|
66
|
+
ghost_white: 0xf8f8ff,
|
67
|
+
gold: 0xffd700,
|
68
|
+
golden_rod: 0xdaa520,
|
69
|
+
gray: 0x808080,
|
70
|
+
green: 0x008000,
|
71
|
+
green_yellow: 0xadff2f,
|
72
|
+
honey_dew: 0xf0fff0,
|
73
|
+
hot_pink: 0xff69b4,
|
74
|
+
indian_red: 0xcd5c5c,
|
75
|
+
indigo: 0x4b0082,
|
76
|
+
ivory: 0xfffff0,
|
77
|
+
khaki: 0xf0e68c,
|
78
|
+
lavender: 0xe6e6fa,
|
79
|
+
lavender_blush: 0xfff0f5,
|
80
|
+
lawn_green: 0x7cfc00,
|
81
|
+
lemon_chiffon: 0xfffacd,
|
82
|
+
light_blue: 0xadd8e6,
|
83
|
+
light_coral: 0xf08080,
|
84
|
+
light_cyan: 0xe0ffff,
|
85
|
+
light_golden_rod_yellow: 0xfafad2,
|
86
|
+
light_gray: 0xd3d3d3,
|
87
|
+
light_green: 0x90ee90,
|
88
|
+
light_pink: 0xffb6c1,
|
89
|
+
light_salmon: 0xffa07a,
|
90
|
+
light_sea_green: 0x20b2aa,
|
91
|
+
light_sky_blue: 0x87cefa,
|
92
|
+
light_slate_gray: 0x778899,
|
93
|
+
light_steel_blue: 0xb0c4de,
|
94
|
+
light_yellow: 0xffffe0,
|
95
|
+
lime: 0x00ff00,
|
96
|
+
lime_green: 0x32cd32,
|
97
|
+
linen: 0xfaf0e6,
|
98
|
+
magenta: 0xff00ff,
|
99
|
+
maroon: 0x800000,
|
100
|
+
medium_aqua_marine: 0x66cdaa,
|
101
|
+
medium_blue: 0x0000cd,
|
102
|
+
medium_orchid: 0xba55d3,
|
103
|
+
medium_purple: 0x9370db,
|
104
|
+
medium_sea_green: 0x3cb371,
|
105
|
+
medium_slate_blue: 0x7b68ee,
|
106
|
+
medium_spring_green: 0x00fa9a,
|
107
|
+
medium_turquoise: 0x48d1cc,
|
108
|
+
medium_violet_red: 0xc71585,
|
109
|
+
midnight_blue: 0x191970,
|
110
|
+
mint_cream: 0xf5fffa,
|
111
|
+
misty_rose: 0xffe4e1,
|
112
|
+
moccasin: 0xffe4b5,
|
113
|
+
navajo_white: 0xffdead,
|
114
|
+
navy: 0x000080,
|
115
|
+
old_lace: 0xfdf5e6,
|
116
|
+
olive: 0x808000,
|
117
|
+
olive_drab: 0x6b8e23,
|
118
|
+
orange: 0xffa500,
|
119
|
+
orange_red: 0xff4500,
|
120
|
+
orchid: 0xda70d6,
|
121
|
+
pale_golden_rod: 0xeee8aa,
|
122
|
+
pale_green: 0x98fb98,
|
123
|
+
pale_turquoise: 0xafeeee,
|
124
|
+
pale_violet_red: 0xdb7093,
|
125
|
+
papaya_whip: 0xffefd5,
|
126
|
+
peach_puff: 0xffdab9,
|
127
|
+
peru: 0xcd853f,
|
128
|
+
pink: 0xffc0cb,
|
129
|
+
plum: 0xdda0dd,
|
130
|
+
powder_blue: 0xb0e0e6,
|
131
|
+
purple: 0x800080,
|
132
|
+
red: 0xff0000,
|
133
|
+
rosy_brown: 0xbc8f8f,
|
134
|
+
royal_blue: 0x4169e1,
|
135
|
+
saddle_brown: 0x8b4513,
|
136
|
+
salmon: 0xfa8072,
|
137
|
+
sandy_brown: 0xf4a460,
|
138
|
+
sea_green: 0x2e8b57,
|
139
|
+
sea_shell: 0xfff5ee,
|
140
|
+
sienna: 0xa0522d,
|
141
|
+
silver: 0xc0c0c0,
|
142
|
+
sky_blue: 0x87ceeb,
|
143
|
+
slate_blue: 0x6a5acd,
|
144
|
+
slate_gray: 0x708090,
|
145
|
+
snow: 0xfffafa,
|
146
|
+
spring_green: 0x00ff7f,
|
147
|
+
steel_blue: 0x468284,
|
148
|
+
tan: 0xd2b48c,
|
149
|
+
teal: 0x008080,
|
150
|
+
thistle: 0xd8bfd8,
|
151
|
+
tomato: 0xff6347,
|
152
|
+
turquoise: 0x40e0d0,
|
153
|
+
violet: 0xee82ee,
|
154
|
+
wheat: 0xf5debe,
|
155
|
+
white: 0x000000,
|
156
|
+
white_smoke: 0xf5f5f5,
|
157
|
+
yellow: 0xffff00,
|
158
|
+
yellow_green: 0x9acd32
|
159
|
+
}
|
160
|
+
|
161
|
+
class << self
|
162
|
+
# Dynamically define class methods. Each human readable colour turns into a
|
163
|
+
# method. It's useful if you don't care about precise colours or can't
|
164
|
+
# remember HEX codes for a colour.
|
165
|
+
#
|
166
|
+
# @example Accessing a colour
|
167
|
+
# Colir.wheat.hex #=> 0xf5debe00
|
168
|
+
#
|
169
|
+
# @example Transparency
|
170
|
+
# Colir.wheat(0.3).hex #=> 0xf5debee1
|
171
|
+
#
|
172
|
+
# @param [Float] transparency
|
173
|
+
#
|
174
|
+
# @return [Colir]
|
175
|
+
# @see Colir
|
176
|
+
COLIRS.each do |name, hex|
|
177
|
+
define_method(name) { |transparency = nil|
|
178
|
+
new(hex, transparency || TRANSPARENCY)
|
179
|
+
}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# The possible number of shades of a Colir in each direction.
|
184
|
+
SHADE_FACTOR = 5
|
185
|
+
|
186
|
+
# The default transparency (opaque).
|
187
|
+
TRANSPARENCY = 0.0
|
188
|
+
|
189
|
+
# The default shade assigned to any Colir.
|
190
|
+
SHADE = 0
|
191
|
+
|
192
|
+
# @see HSLRGB::HSL::L_RANGE
|
193
|
+
UPPER_LIMIT = BigDecimal(HSLRGB::HSL::L_RANGE.max.to_f.to_s)
|
194
|
+
|
195
|
+
# The mi
|
196
|
+
RGB_LOWER_LIMIT = 0x000000
|
197
|
+
|
198
|
+
RGB_UPPER_LIMIT = 0xffffff
|
199
|
+
|
200
|
+
# @return [Integer] the HEX colour without the alpha channel
|
201
|
+
attr_reader :hex
|
202
|
+
|
203
|
+
# @return [Float] the transparency. Lies within the range of [0, 1].
|
204
|
+
attr_reader :transparency
|
205
|
+
|
206
|
+
# @return [Integer] the current shade of the colour. Lies within the
|
207
|
+
# range of [-5, 5]
|
208
|
+
attr_reader :shade
|
209
|
+
|
210
|
+
# Creates a new HEXA colour, where the A states for "Alpha".
|
211
|
+
#
|
212
|
+
# @param [Integer] hex It's convenient to use Ruby's HEX notation: `0xaaff33`
|
213
|
+
# @param [Float] transparency Alpha channel. Must lie within the range
|
214
|
+
# of [0, 1].
|
215
|
+
# @raise [RangeError] if the transparency is a bad value
|
216
|
+
def initialize(hex, transparency = TRANSPARENCY)
|
217
|
+
validate_colir!(hex, transparency)
|
218
|
+
|
219
|
+
@hex = hex
|
220
|
+
@transparency = transparency
|
221
|
+
@shade = SHADE
|
222
|
+
@ld_seq = [:base]
|
223
|
+
end
|
224
|
+
|
225
|
+
# @return [Integer] the HEXA representation of the Colir
|
226
|
+
def hexa
|
227
|
+
hex = @hex.to_s(16).rjust(6, '0')
|
228
|
+
alpha = (transparency * 100).to_i.to_s(16).rjust(2, '0')
|
229
|
+
(hex + alpha).to_i(16)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Make the colour fully transparent.
|
233
|
+
# @return [self]
|
234
|
+
def transparent!
|
235
|
+
@transparency = 1.0
|
236
|
+
self
|
237
|
+
end
|
238
|
+
|
239
|
+
# Sets the new +transparency+.
|
240
|
+
#
|
241
|
+
# @return [Float] the new transparency
|
242
|
+
# @raise [RangeError] if transparency does not lie within the valid range
|
243
|
+
def transparency=(transparency)
|
244
|
+
validate_transparency!(transparency)
|
245
|
+
@transparency = transparency
|
246
|
+
end
|
247
|
+
|
248
|
+
# Make the colour fully opaque.
|
249
|
+
# @return [self]
|
250
|
+
def opaque!
|
251
|
+
@transparency = TRANSPARENCY
|
252
|
+
self
|
253
|
+
end
|
254
|
+
|
255
|
+
# Lightens `self` by 1 shade. The maximum number of positive shades is 5. The
|
256
|
+
# method stops increasing the shade levels when it reaches the limit and
|
257
|
+
# merely returns `self` without any changes. The final shade is white colour.
|
258
|
+
#
|
259
|
+
# @return [self] the lightened `self`
|
260
|
+
def lighten
|
261
|
+
if @shade < SHADE_FACTOR
|
262
|
+
calculate_new_hex { |hsl|
|
263
|
+
hsl[2] += if @ld_seq.last == :base || @ld_seq.last == :ltn
|
264
|
+
@ld_seq << :ltn
|
265
|
+
l_factor
|
266
|
+
else
|
267
|
+
@ld_seq.pop
|
268
|
+
d_factor
|
269
|
+
end
|
270
|
+
@shade += 1
|
271
|
+
hsl
|
272
|
+
}
|
273
|
+
end
|
274
|
+
self
|
275
|
+
end
|
276
|
+
|
277
|
+
# Darkens `self` by 1 shade. The maximum number of negative shades is -5. The
|
278
|
+
# method stops decreasing the shade levels when it reaches the limit and
|
279
|
+
# merely returns `self` without any changes. The final shade is black colour.
|
280
|
+
#
|
281
|
+
# @return [self] the darkened `self`
|
282
|
+
def darken
|
283
|
+
if SHADE_FACTOR * -1 < @shade
|
284
|
+
calculate_new_hex { |hsl|
|
285
|
+
hsl[2] -= if @ld_seq.last == :base || @ld_seq.last == :dkn
|
286
|
+
@ld_seq << :dkn
|
287
|
+
d_factor
|
288
|
+
else
|
289
|
+
@ld_seq.pop
|
290
|
+
l_factor
|
291
|
+
end
|
292
|
+
@shade -= 1
|
293
|
+
hsl
|
294
|
+
}
|
295
|
+
end
|
296
|
+
self
|
297
|
+
end
|
298
|
+
|
299
|
+
# Resets the `@shade` to the default value, restoring the `@hex` number.
|
300
|
+
# @return [self]
|
301
|
+
def reset_shade
|
302
|
+
@shade.abs.times { @ld_seq.last == :ltn ? darken : lighten }
|
303
|
+
self
|
304
|
+
end
|
305
|
+
|
306
|
+
# @return [Colir] a new Colir, but darker than `self` by 1 shade. It does not
|
307
|
+
# modify `self`
|
308
|
+
def darker
|
309
|
+
self.class.new(@hex, @transparency).darken
|
310
|
+
end
|
311
|
+
|
312
|
+
# @return [Colir] a new Colir, but lighter than `self` by 1 shade. It does not
|
313
|
+
# modify `self`
|
314
|
+
def lighter
|
315
|
+
self.class.new(@hex, @transparency).lighten
|
316
|
+
end
|
317
|
+
|
318
|
+
private
|
319
|
+
|
320
|
+
# @return [BigDecimal] the lightening factor
|
321
|
+
def l_factor
|
322
|
+
@l_factor ||= (UPPER_LIMIT - @hsl[2]) / SHADE_FACTOR
|
323
|
+
end
|
324
|
+
|
325
|
+
# @return [BigDecimal] the darkening factor
|
326
|
+
def d_factor
|
327
|
+
@d_factor ||= @hsl[2] / SHADE_FACTOR
|
328
|
+
end
|
329
|
+
|
330
|
+
# @yield [hsl]
|
331
|
+
# @yieldparam [Array<Integer,BigDecimal>] an HSL colour based on the
|
332
|
+
# current HEX
|
333
|
+
# @yieldreturn [Array<Integer,BigDecimal>] an HSL colour with
|
334
|
+
# corrected lightness
|
335
|
+
# @return [void]
|
336
|
+
def calculate_new_hex
|
337
|
+
@hsl ||= HSLRGB.rgb_to_hsl(*HSLRGB::RGB.int_bytes(@hex))
|
338
|
+
@hex = HSLRGB.hsl_to_rgb(*yield(@hsl)).map do |b|
|
339
|
+
b.to_s(16).rjust(2, '0')
|
340
|
+
end.join('').to_i(16)
|
341
|
+
end
|
342
|
+
|
343
|
+
def validate_colir!(hex, transparency)
|
344
|
+
unless HSLRGB::RGB::RGB_RANGE.cover?(hex)
|
345
|
+
raise RangeError, 'out of allowed RGB values (0x000000-0xffffff)'
|
346
|
+
end
|
347
|
+
|
348
|
+
validate_transparency!(transparency)
|
349
|
+
end
|
350
|
+
|
351
|
+
def validate_transparency!(transparency)
|
352
|
+
unless (0..1).cover?(transparency)
|
353
|
+
raise RangeError, 'out of allowed transparency values (0-1)'
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|