rainbow_gradient 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 +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +7 -0
- data/example/data/gradient2.yml +74 -0
- data/example/data/gradient3.yml +147 -0
- data/example/gradient.png +0 -0
- data/example/gradient.rb +27 -0
- data/example/gradient2.rb +5 -0
- data/example/gradient3.rb +5 -0
- data/example/gradient_factory.rb +43 -0
- data/example/output/gradient.png +0 -0
- data/example/output/gradient2_1.png +0 -0
- data/example/output/gradient2_2.png +0 -0
- data/example/output/gradient2_3.png +0 -0
- data/example/output/gradient3_1.png +0 -0
- data/example/output/gradient3_2.png +0 -0
- data/example/output/gradient3_3.png +0 -0
- data/example/output/gradient3_4.png +0 -0
- data/example/psd/gradient.psd +0 -0
- data/example/psd/gradient2.psd +0 -0
- data/example/psd/gradient3.psd +0 -0
- data/lib/rainbow/color.rb +32 -0
- data/lib/rainbow/color_range.rb +161 -0
- data/lib/rainbow/gradient.rb +185 -0
- data/lib/rainbow/opacity.rb +23 -0
- data/lib/rainbow/opacity_range.rb +95 -0
- data/lib/rainbow/opacity_ranges.rb +41 -0
- data/lib/rainbow/version.rb +3 -0
- data/lib/rainbow.rb +14 -0
- data/rainbow.gemspec +26 -0
- data/test/lib/color_test.rb +35 -0
- data/test/lib/opacity_test.rb +24 -0
- data/test/test_helper.rb +5 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 46e4617e2a724ec1cdbb5561f8bf20b29645b965
|
4
|
+
data.tar.gz: 0c058b23f18f3c63119ae378712bf2cca0f17f2a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6dac57d8cf2cdb02be565cf15985bbbfc08c1b44021af5508e826cd927e7351b460d93e1d0712a0fca77239c7bedc717e6cf4cddcbfcba52e7a70fdb6ecae745
|
7
|
+
data.tar.gz: b3b50b115816cb4c97f22ffe1eaeb193a45f8e39058c7d696adb851e8b1dc1878e1ced023f43e558ffa0120cb33226157ded57f8d77ebf06bb7d9f0b485ac176
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Sophy Eung
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Rainbow
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'rainbow'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install rainbow
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( http://github.com/<my-github-username>/rainbow/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
gradient2_1:
|
2
|
+
reverse: true
|
3
|
+
color_ranges:
|
4
|
+
-
|
5
|
+
color1:
|
6
|
+
red: 0
|
7
|
+
green: 0
|
8
|
+
blue: 255
|
9
|
+
location: 0
|
10
|
+
color2:
|
11
|
+
red: 0
|
12
|
+
green: 255
|
13
|
+
blue: 0
|
14
|
+
location: 100
|
15
|
+
mid_point: 50
|
16
|
+
opacity_ranges:
|
17
|
+
-
|
18
|
+
opacity1:
|
19
|
+
value: 100
|
20
|
+
location: 0
|
21
|
+
opacity2:
|
22
|
+
value: 100
|
23
|
+
location: 100
|
24
|
+
mid_point: 50
|
25
|
+
|
26
|
+
gradient2_2:
|
27
|
+
reverse: false
|
28
|
+
color_ranges:
|
29
|
+
-
|
30
|
+
color1:
|
31
|
+
red: 255
|
32
|
+
green: 0
|
33
|
+
blue: 255
|
34
|
+
location: 20
|
35
|
+
color2:
|
36
|
+
red: 255
|
37
|
+
green: 255
|
38
|
+
blue: 0
|
39
|
+
location: 75
|
40
|
+
mid_point: 50
|
41
|
+
opacity_ranges:
|
42
|
+
-
|
43
|
+
opacity1:
|
44
|
+
value: 100
|
45
|
+
location: 30
|
46
|
+
opacity2:
|
47
|
+
value: 35
|
48
|
+
location: 85
|
49
|
+
mid_point: 50
|
50
|
+
|
51
|
+
gradient2_3:
|
52
|
+
reverse: false
|
53
|
+
color_ranges:
|
54
|
+
-
|
55
|
+
color1:
|
56
|
+
red: 0
|
57
|
+
green: 0
|
58
|
+
blue: 255
|
59
|
+
location: 0
|
60
|
+
color2:
|
61
|
+
red: 0
|
62
|
+
green: 255
|
63
|
+
blue: 0
|
64
|
+
location: 100
|
65
|
+
mid_point: 50
|
66
|
+
opacity_ranges:
|
67
|
+
-
|
68
|
+
opacity1:
|
69
|
+
value: 30
|
70
|
+
location: 30
|
71
|
+
opacity2:
|
72
|
+
value: 70
|
73
|
+
location: 70
|
74
|
+
mid_point: 50
|
@@ -0,0 +1,147 @@
|
|
1
|
+
gradient3_1:
|
2
|
+
color_ranges:
|
3
|
+
-
|
4
|
+
color1:
|
5
|
+
red: 0
|
6
|
+
green: 0
|
7
|
+
blue: 255
|
8
|
+
location: 0
|
9
|
+
color2:
|
10
|
+
red: 0
|
11
|
+
green: 255
|
12
|
+
blue: 0
|
13
|
+
location: 50
|
14
|
+
mid_point: 50
|
15
|
+
-
|
16
|
+
color1:
|
17
|
+
red: 0
|
18
|
+
green: 255
|
19
|
+
blue: 0
|
20
|
+
location: 50
|
21
|
+
color2:
|
22
|
+
red: 255
|
23
|
+
green: 255
|
24
|
+
blue: 0
|
25
|
+
location: 100
|
26
|
+
mid_point: 50
|
27
|
+
opacity_ranges:
|
28
|
+
-
|
29
|
+
opacity1:
|
30
|
+
value: 100
|
31
|
+
location: 0
|
32
|
+
opacity2:
|
33
|
+
value: 100
|
34
|
+
location: 50
|
35
|
+
mid_point: 50
|
36
|
+
-
|
37
|
+
opacity1:
|
38
|
+
value: 100
|
39
|
+
location: 50
|
40
|
+
opacity2:
|
41
|
+
value: 100
|
42
|
+
location: 100
|
43
|
+
mid_point: 50
|
44
|
+
|
45
|
+
gradient3_2:
|
46
|
+
color_ranges:
|
47
|
+
-
|
48
|
+
color1:
|
49
|
+
red: 255
|
50
|
+
green: 0
|
51
|
+
blue: 0
|
52
|
+
location: 20
|
53
|
+
color2:
|
54
|
+
red: 0
|
55
|
+
green: 255
|
56
|
+
blue: 0
|
57
|
+
location: 50
|
58
|
+
mid_point: 75
|
59
|
+
-
|
60
|
+
color1:
|
61
|
+
red: 0
|
62
|
+
green: 255
|
63
|
+
blue: 0
|
64
|
+
location: 50
|
65
|
+
color2:
|
66
|
+
red: 0
|
67
|
+
green: 0
|
68
|
+
blue: 0
|
69
|
+
location: 78
|
70
|
+
mid_point: 50
|
71
|
+
opacity_ranges:
|
72
|
+
-
|
73
|
+
opacity1:
|
74
|
+
value: 100
|
75
|
+
location: 0
|
76
|
+
opacity2:
|
77
|
+
value: 100
|
78
|
+
location: 50
|
79
|
+
mid_point: 50
|
80
|
+
-
|
81
|
+
opacity1:
|
82
|
+
value: 100
|
83
|
+
location: 50
|
84
|
+
opacity2:
|
85
|
+
value: 100
|
86
|
+
location: 100
|
87
|
+
mid_point: 50
|
88
|
+
|
89
|
+
gradient3_3:
|
90
|
+
color_ranges:
|
91
|
+
-
|
92
|
+
color1:
|
93
|
+
red: 255
|
94
|
+
green: 0
|
95
|
+
blue: 0
|
96
|
+
location: 20
|
97
|
+
color2:
|
98
|
+
red: 0
|
99
|
+
green: 255
|
100
|
+
blue: 0
|
101
|
+
location: 50
|
102
|
+
mid_point: 75
|
103
|
+
-
|
104
|
+
color1:
|
105
|
+
red: 0
|
106
|
+
green: 255
|
107
|
+
blue: 0
|
108
|
+
location: 50
|
109
|
+
color2:
|
110
|
+
red: 0
|
111
|
+
green: 0
|
112
|
+
blue: 255
|
113
|
+
location: 78
|
114
|
+
mid_point: 50
|
115
|
+
opacity_ranges:
|
116
|
+
-
|
117
|
+
opacity1:
|
118
|
+
value: 50
|
119
|
+
location: 10
|
120
|
+
opacity2:
|
121
|
+
value: 100
|
122
|
+
location: 90
|
123
|
+
mid_point: 30
|
124
|
+
|
125
|
+
gradient3_4:
|
126
|
+
color_ranges:
|
127
|
+
-
|
128
|
+
color1:
|
129
|
+
red: 255
|
130
|
+
green: 0
|
131
|
+
blue: 0
|
132
|
+
location: 0
|
133
|
+
color2:
|
134
|
+
red: 0
|
135
|
+
green: 255
|
136
|
+
blue: 0
|
137
|
+
location: 100
|
138
|
+
mid_point: 50
|
139
|
+
opacity_ranges:
|
140
|
+
-
|
141
|
+
opacity1:
|
142
|
+
value: 50
|
143
|
+
location: 10
|
144
|
+
opacity2:
|
145
|
+
value: 100
|
146
|
+
location: 90
|
147
|
+
mid_point: 50
|
Binary file
|
data/example/gradient.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require './lib/rainbow'
|
2
|
+
|
3
|
+
first_color = Rainbow::Color.new(ChunkyPNG::Color(255, 255, 255), 0)
|
4
|
+
second_color = Rainbow::Color.new(ChunkyPNG::Color(255, 255, 255), 100)
|
5
|
+
color_range = Rainbow::ColorRange.new(first_color, second_color, 50)
|
6
|
+
|
7
|
+
first_opacity = Rainbow::Opacity.new(100, 0)
|
8
|
+
second_opacity = Rainbow::Opacity.new(0, 100)
|
9
|
+
opacity_range = Rainbow::OpacityRange.new(first_opacity, second_opacity, 50)
|
10
|
+
|
11
|
+
filename = './example/output/gradient.png'
|
12
|
+
args = {
|
13
|
+
reverse: false,
|
14
|
+
opacity: 100,
|
15
|
+
scale: 53,
|
16
|
+
angle: 180,
|
17
|
+
|
18
|
+
style: 'linear',
|
19
|
+
gradient: {
|
20
|
+
color_ranges: [color_range],
|
21
|
+
opacity_ranges: [opacity_range]
|
22
|
+
}
|
23
|
+
}
|
24
|
+
gradient = Rainbow::Gradient.new(400, 50, args)
|
25
|
+
gradient.save_as_png(filename)
|
26
|
+
|
27
|
+
`open #{filename}`
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module GradientFactory
|
5
|
+
extend self
|
6
|
+
|
7
|
+
DATA_DIR = Pathname('example/data')
|
8
|
+
OUTPUT_DIR = Pathname('example/output')
|
9
|
+
|
10
|
+
def create_from_file(filename)
|
11
|
+
data = File.open(DATA_DIR.join(filename)) { |file| file.read }
|
12
|
+
data = YAML.load(data)
|
13
|
+
|
14
|
+
data.each_pair.inject([]) do |filenames, (filename, value)|
|
15
|
+
color_ranges = value['color_ranges'].inject([]) do |ranges, data|
|
16
|
+
h1, h2 = data['color1'], data['color2']
|
17
|
+
color1 = Rainbow::Color.new(ChunkyPNG::Color(h1['red'], h1['green'], h1['blue']), h1['location'])
|
18
|
+
color2 = Rainbow::Color.new(ChunkyPNG::Color(h2['red'], h2['green'], h2['blue']), h2['location'])
|
19
|
+
ranges << Rainbow::ColorRange.new(color1, color2, data['mid_point'])
|
20
|
+
ranges
|
21
|
+
end
|
22
|
+
|
23
|
+
opacity_ranges = value['opacity_ranges'].inject([]) do |ranges, data|
|
24
|
+
h1, h2 = data['opacity1'], data['opacity2']
|
25
|
+
opacity1 = Rainbow::Opacity.new(h1['value'], h1['location'])
|
26
|
+
opacity2 = Rainbow::Opacity.new(h2['value'], h2['location'])
|
27
|
+
ranges << Rainbow::OpacityRange.new(opacity1, opacity2, data['mid_point'])
|
28
|
+
end
|
29
|
+
|
30
|
+
args = {
|
31
|
+
reverse: value['reverse'],
|
32
|
+
style: 'linear',
|
33
|
+
gradient: {
|
34
|
+
color_ranges: color_ranges,
|
35
|
+
opacity_ranges: opacity_ranges
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
gradient = Rainbow::Gradient.new(400, 50, args)
|
40
|
+
filenames << gradient.save_as_png(OUTPUT_DIR.join("#{filename}.png"))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rainbow
|
2
|
+
class Color
|
3
|
+
attr_reader :color, :location
|
4
|
+
|
5
|
+
# color - Fixnum
|
6
|
+
# location - Fixnum (0-100)
|
7
|
+
def initialize(color, location)
|
8
|
+
@color = color
|
9
|
+
@location = location
|
10
|
+
|
11
|
+
assert_location!
|
12
|
+
end
|
13
|
+
|
14
|
+
def r
|
15
|
+
ChunkyPNG::Color.r(color)
|
16
|
+
end
|
17
|
+
|
18
|
+
def g
|
19
|
+
ChunkyPNG::Color.g(color)
|
20
|
+
end
|
21
|
+
|
22
|
+
def b
|
23
|
+
ChunkyPNG::Color.b(color)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def assert_location!
|
29
|
+
raise ArgumentError, 'location must be between 0 and 100' if location < 0 || location > 100
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module Rainbow
|
2
|
+
class ColorRange
|
3
|
+
attr_reader :from_color, :to_color, :mid_point, :gradient, :mid_color
|
4
|
+
attr_reader :current_x, :width, :first_width, :second_width
|
5
|
+
attr_reader :from_location_in_pixel, :to_location_in_pixel,
|
6
|
+
:mid_location_in_pixel, :leftover_width
|
7
|
+
attr_reader :tmp_current_x, :tmp_diff_r, :tmp_diff_g, :tmp_diff_b,
|
8
|
+
:tmp_from_color, :tmp_to_color, :tmp_distance_in_pixel
|
9
|
+
|
10
|
+
attr_accessor :opacity_ranges
|
11
|
+
|
12
|
+
def initialize(from_color, to_color, mid_point)
|
13
|
+
@from_color = from_color
|
14
|
+
@to_color = to_color
|
15
|
+
@mid_point = mid_point
|
16
|
+
|
17
|
+
@current_x = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def gradient=(gradient)
|
21
|
+
@gradient = gradient
|
22
|
+
compute_variables!
|
23
|
+
end
|
24
|
+
|
25
|
+
def current_x=(x)
|
26
|
+
set_color_variables(x)
|
27
|
+
set_opacity_variables(x)
|
28
|
+
|
29
|
+
@current_x = x
|
30
|
+
@tmp_opacity = compute_opacity(x)
|
31
|
+
end
|
32
|
+
|
33
|
+
def current_color
|
34
|
+
if less_than_scale_range?
|
35
|
+
ChunkyPNG::Color(from_color.r, from_color.g, from_color.b, @tmp_opacity)
|
36
|
+
elsif greater_than_scale_range?
|
37
|
+
ChunkyPNG::Color(to_color.r, to_color.g, to_color.b, @tmp_opacity)
|
38
|
+
else
|
39
|
+
ChunkyPNG::Color(color(:r), color(:g), color(:b), @tmp_opacity)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def color(method)
|
46
|
+
diff = __send__("tmp_diff_#{method}")
|
47
|
+
(tmp_from_color.send(method) + (tmp_current_x / tmp_distance_in_pixel) * diff).to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
def compute_opacity(x)
|
51
|
+
ratio = @tmp_opacity_current_x / @tmp_opacity_distance_in_pixel
|
52
|
+
opacity = (@tmp_opacity_from + ratio * @tmp_opacity_diff).round
|
53
|
+
|
54
|
+
opacity < 0 ? 0 : opacity
|
55
|
+
end
|
56
|
+
|
57
|
+
def compute_variables!
|
58
|
+
@mid_color = ChunkyPNG::Color(from_color.r + (to_color.r - from_color.r) / 2,
|
59
|
+
from_color.g + (to_color.g - from_color.g) / 2,
|
60
|
+
from_color.b + (to_color.b - from_color.b) / 2)
|
61
|
+
|
62
|
+
@width = gradient.width * (to_color.location - from_color.location) / 100
|
63
|
+
@first_width = @width * mid_point / 100
|
64
|
+
@second_width = @width - @first_width
|
65
|
+
|
66
|
+
@from_location_in_pixel = from_color.location * gradient.width / 100
|
67
|
+
@mid_location_in_pixel = @from_location_in_pixel + @first_width
|
68
|
+
@to_location_in_pixel = @from_location_in_pixel + @width
|
69
|
+
|
70
|
+
@leftover_width = (100 - to_color.location) * gradient.width / 100
|
71
|
+
end
|
72
|
+
|
73
|
+
def in_scale_range?
|
74
|
+
gradient.scale_start_location_in_pixel >= current_x && current_x <= gradient.scale_end_location_in_pixel
|
75
|
+
end
|
76
|
+
|
77
|
+
def less_than_scale_range?
|
78
|
+
current_x < gradient.scale_start_location_in_pixel
|
79
|
+
end
|
80
|
+
|
81
|
+
def greater_than_scale_range?
|
82
|
+
current_x > gradient.scale_end_location_in_pixel
|
83
|
+
end
|
84
|
+
|
85
|
+
def set_opacity_variables(x)
|
86
|
+
opacity_ranges.current_x = x
|
87
|
+
|
88
|
+
@tmp_opacity_current_x = opacity_ranges.tmp_current_x
|
89
|
+
@tmp_opacity_from = opacity_ranges.tmp_from
|
90
|
+
@tmp_opacity_to = opacity_ranges.tmp_to
|
91
|
+
@tmp_opacity_diff = opacity_ranges.tmp_diff
|
92
|
+
@tmp_opacity_distance_in_pixel = opacity_ranges.tmp_distance_in_pixel
|
93
|
+
end
|
94
|
+
|
95
|
+
def last_color_location_is_lesser_than_100(x)
|
96
|
+
x == to_location_in_pixel && to_color.location < 100
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_color_variables(x)
|
100
|
+
if x == 0 && from_color.location > 0
|
101
|
+
@tmp_current_x = 0.0
|
102
|
+
@tmp_from_color = from_color
|
103
|
+
@tmp_to_color = from_color
|
104
|
+
@tmp_distance_in_pixel = from_location_in_pixel
|
105
|
+
@tmp_diff_r = 0
|
106
|
+
@tmp_diff_g = 0
|
107
|
+
@tmp_diff_b = 0
|
108
|
+
elsif x == to_location_in_pixel && to_color.location < 100
|
109
|
+
@tmp_current_x = 0.0
|
110
|
+
@tmp_from_color = to_color
|
111
|
+
@tmp_to_color = to_color
|
112
|
+
@tmp_distance_in_pixel = leftover_width
|
113
|
+
@tmp_diff_r = 0
|
114
|
+
@tmp_diff_g = 0
|
115
|
+
@tmp_diff_b = 0
|
116
|
+
elsif x == from_location_in_pixel && gradient.scale_100?
|
117
|
+
@tmp_current_x = 0.0
|
118
|
+
@tmp_from_color = from_color
|
119
|
+
@tmp_to_color = Rainbow::Color.new(mid_color, 0)
|
120
|
+
@tmp_distance_in_pixel = first_width
|
121
|
+
@tmp_diff_r = @tmp_to_color.r - @tmp_from_color.r
|
122
|
+
@tmp_diff_g = @tmp_to_color.g - @tmp_from_color.g
|
123
|
+
@tmp_diff_b = @tmp_to_color.b - @tmp_from_color.b
|
124
|
+
elsif x == mid_location_in_pixel && gradient.scale_100?
|
125
|
+
@tmp_current_x = 0.0
|
126
|
+
@tmp_from_color = Rainbow::Color.new(mid_color, 0)
|
127
|
+
@tmp_to_color = to_color
|
128
|
+
@tmp_distance_in_pixel = second_width
|
129
|
+
@tmp_diff_r = @tmp_to_color.r - @tmp_from_color.r
|
130
|
+
@tmp_diff_g = @tmp_to_color.g - @tmp_from_color.g
|
131
|
+
@tmp_diff_b = @tmp_to_color.b - @tmp_from_color.b
|
132
|
+
elsif x == from_location_in_pixel && !gradient.scale_100?
|
133
|
+
@tmp_current_x = 0.0
|
134
|
+
@tmp_from_color = from_color
|
135
|
+
@tmp_to_color = from_color
|
136
|
+
@tmp_distance_in_pixel = 1
|
137
|
+
@tmp_diff_r = 0
|
138
|
+
@tmp_diff_g = 0
|
139
|
+
@tmp_diff_b = 0
|
140
|
+
elsif x == gradient.scale_start_location_in_pixel && !gradient.scale_100?
|
141
|
+
@tmp_current_x = 0.0
|
142
|
+
@tmp_from_color = from_color
|
143
|
+
@tmp_to_color = Rainbow::Color.new(mid_color, 0)
|
144
|
+
@tmp_distance_in_pixel = gradient.scale_half_distance_in_pixel
|
145
|
+
@tmp_diff_r = @tmp_to_color.r - @tmp_from_color.r
|
146
|
+
@tmp_diff_g = @tmp_to_color.g - @tmp_from_color.g
|
147
|
+
@tmp_diff_b = @tmp_to_color.b - @tmp_from_color.b
|
148
|
+
elsif x == gradient.scale_mid_location_in_pixel && !gradient.scale_100?
|
149
|
+
@tmp_current_x = 0.0
|
150
|
+
@tmp_from_color = Rainbow::Color.new(mid_color, 0)
|
151
|
+
@tmp_to_color = to_color
|
152
|
+
@tmp_distance_in_pixel = gradient.scale_half_distance_in_pixel
|
153
|
+
@tmp_diff_r = @tmp_to_color.r - @tmp_from_color.r
|
154
|
+
@tmp_diff_g = @tmp_to_color.g - @tmp_from_color.g
|
155
|
+
@tmp_diff_b = @tmp_to_color.b - @tmp_from_color.b
|
156
|
+
else
|
157
|
+
@tmp_current_x += 1
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
module Rainbow
|
2
|
+
class Gradient
|
3
|
+
|
4
|
+
attr_reader :width, :height, :args, :style, :color_ranges, :opacity_ranges
|
5
|
+
attr_reader :canvas
|
6
|
+
attr_reader :scale_start_location_in_pixel, :scale_mid_location_in_pixel,
|
7
|
+
:scale_end_location_in_pixel, :scale_half_distance_in_pixel
|
8
|
+
|
9
|
+
SUPPORTED_ANGLES = [0, 180]
|
10
|
+
|
11
|
+
# wdith - The gradient width
|
12
|
+
# height - The gradient height
|
13
|
+
# args - Hash that describes the property of the gradient
|
14
|
+
# {
|
15
|
+
# blend_mode: 'norm|diss|dark|...',
|
16
|
+
# dither: true|false,
|
17
|
+
# opacity: 0..100,
|
18
|
+
# gradient: {
|
19
|
+
# type: 'solid|noise',
|
20
|
+
# smoothness: 0..100,
|
21
|
+
# color_ranges: [],
|
22
|
+
# opacity_ranges: []
|
23
|
+
# },
|
24
|
+
# reverse: true|false,
|
25
|
+
# style: 'linear|radial|angle|reflected|diamond',
|
26
|
+
# align_with_layer: true|false,
|
27
|
+
# angle: 0..360,
|
28
|
+
# scale: 10..150
|
29
|
+
# }
|
30
|
+
def initialize(width, height, args)
|
31
|
+
@width = width
|
32
|
+
@height = height
|
33
|
+
@args = args
|
34
|
+
|
35
|
+
@style = args[:style]
|
36
|
+
@color_ranges = args[:gradient][:color_ranges]
|
37
|
+
@opacity_ranges = OpacityRanges.new(args[:gradient][:opacity_ranges], self)
|
38
|
+
|
39
|
+
assert_arguments!
|
40
|
+
compute_scale_variables!
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_canvas
|
44
|
+
@canvas = ChunkyPNG::Canvas.new(width, height, ChunkyPNG::Color::TRANSPARENT)
|
45
|
+
|
46
|
+
paint_canvas!(@canvas)
|
47
|
+
set_opacity!(@canvas) if opacity != 100
|
48
|
+
reverse!(@canvas) if reverse || angle == 180
|
49
|
+
end
|
50
|
+
|
51
|
+
def blend_mode
|
52
|
+
args.fetch(:blend_mode, 'norm')
|
53
|
+
end
|
54
|
+
|
55
|
+
def dither
|
56
|
+
args.fetch(:dither, false)
|
57
|
+
end
|
58
|
+
|
59
|
+
def opacity
|
60
|
+
args.fetch(:opacity, 100)
|
61
|
+
end
|
62
|
+
|
63
|
+
def type
|
64
|
+
args[:gradient][:type]
|
65
|
+
end
|
66
|
+
|
67
|
+
def smoothness
|
68
|
+
args[:gradient][:smoothness]
|
69
|
+
end
|
70
|
+
|
71
|
+
def reverse
|
72
|
+
args.fetch(:reverse, false)
|
73
|
+
end
|
74
|
+
|
75
|
+
def align_with_layer
|
76
|
+
args.fetch(:align_with_layer, true)
|
77
|
+
end
|
78
|
+
|
79
|
+
def angle
|
80
|
+
value = args.fetch(:angle, 0)
|
81
|
+
value % 360
|
82
|
+
end
|
83
|
+
|
84
|
+
def scale
|
85
|
+
args.fetch(:scale, 100)
|
86
|
+
end
|
87
|
+
|
88
|
+
def scale_100?
|
89
|
+
scale == 100
|
90
|
+
end
|
91
|
+
|
92
|
+
def save_as_png(path)
|
93
|
+
create_canvas unless canvas
|
94
|
+
canvas.save(path, :fast_rgba)
|
95
|
+
|
96
|
+
path
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def assert_arguments!
|
102
|
+
_opacity_ranges = args[:gradient][:opacity_ranges]
|
103
|
+
|
104
|
+
raise ArgumentError, 'args[:gradient][:color_ranges] cannot not be blank' if !color_ranges || color_ranges.size == 0
|
105
|
+
raise ArgumentError, 'args[:gradient][:opacity_ranges] cannot not be blank' if !_opacity_ranges || _opacity_ranges.size == 0
|
106
|
+
raise ArgumentError, 'args[:style] - Sorry, for now we support only linear gradient' if args[:style] != 'linear'
|
107
|
+
raise ArgumentError, 'args[:scale] must be between 10 and 150' if scale < 10 || scale > 150
|
108
|
+
raise ArgumentError, 'Sorry, we support only two colors stop if scale is not 100' if scale != 100 && color_ranges.size != 1
|
109
|
+
raise ArgumentError, 'Sorry, we support only 0° or 180° angle' unless SUPPORTED_ANGLES.include?(angle)
|
110
|
+
end
|
111
|
+
|
112
|
+
def compute_scale_variables!
|
113
|
+
scale_start = (100 - scale) / 2
|
114
|
+
scale_end = scale_start == 0 ? 100 : scale_start + scale
|
115
|
+
|
116
|
+
@scale_start_location_in_pixel = scale_start * width / 100
|
117
|
+
@scale_end_location_in_pixel = scale_end * width / 100
|
118
|
+
@scale_half_distance_in_pixel = (@scale_end_location_in_pixel - @scale_start_location_in_pixel) / 2
|
119
|
+
@scale_mid_location_in_pixel = @scale_start_location_in_pixel + @scale_half_distance_in_pixel
|
120
|
+
end
|
121
|
+
|
122
|
+
def reverse!(canvas)
|
123
|
+
canvas.flip_vertically!
|
124
|
+
end
|
125
|
+
|
126
|
+
def set_opacity!(canvas)
|
127
|
+
width.times.each do |x|
|
128
|
+
height.times.each do |y|
|
129
|
+
color = canvas[x, y]
|
130
|
+
red = ChunkyPNG::Color.r(color)
|
131
|
+
green = ChunkyPNG::Color.g(color)
|
132
|
+
blue = ChunkyPNG::Color.b(color)
|
133
|
+
new_alpha = ChunkyPNG::Color.a(color) * opacity / 100
|
134
|
+
canvas[x, y] = ChunkyPNG::Color.rgba(red, green, blue, new_alpha)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def paint_canvas!(canvas)
|
140
|
+
x_coverred = 0
|
141
|
+
color_ranges.each_with_index do |color_range, index|
|
142
|
+
color_range.gradient = self
|
143
|
+
color_range.opacity_ranges = opacity_ranges
|
144
|
+
|
145
|
+
# When the first color location is not 0
|
146
|
+
x_coverred += paint_prefix(canvas, color_range, x_coverred) if index == 0
|
147
|
+
|
148
|
+
x_coverred += paint_body(canvas, color_range, x_coverred)
|
149
|
+
|
150
|
+
# When the last color location is not 100
|
151
|
+
x_coverred += paint_suffix(canvas, color_range, x_coverred) if index + 1 == color_ranges.size
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def paint_prefix(canvas, color_range, x_coverred)
|
156
|
+
color_range.from_location_in_pixel.times do |x|
|
157
|
+
color_range.current_x = x
|
158
|
+
height.times { |y| canvas[x, y] = color_range.current_color }
|
159
|
+
end
|
160
|
+
|
161
|
+
color_range.from_location_in_pixel
|
162
|
+
end
|
163
|
+
|
164
|
+
def paint_body(canvas, color_range, x_coverred)
|
165
|
+
|
166
|
+
color_range.width.times do |x|
|
167
|
+
x += x_coverred
|
168
|
+
color_range.current_x = x
|
169
|
+
height.times { |y| canvas[x, y] = color_range.current_color }
|
170
|
+
end
|
171
|
+
|
172
|
+
color_range.width
|
173
|
+
end
|
174
|
+
|
175
|
+
def paint_suffix(canvas, color_range, x_coverred)
|
176
|
+
color_range.leftover_width.times do |x|
|
177
|
+
x += x_coverred
|
178
|
+
color_range.current_x = x
|
179
|
+
height.times { |y| canvas[x, y] = color_range.current_color }
|
180
|
+
end
|
181
|
+
|
182
|
+
color_range.leftover_width
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Rainbow
|
2
|
+
class Opacity
|
3
|
+
|
4
|
+
attr_reader :value, :location
|
5
|
+
|
6
|
+
# value - Fixnum (0-100)
|
7
|
+
# location - Fixnum (0-100)
|
8
|
+
def initialize(value, location)
|
9
|
+
@value_percentage = value
|
10
|
+
@value = (255.0 * value / 100).round
|
11
|
+
@location = location
|
12
|
+
|
13
|
+
assert_arguments!
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def assert_arguments!
|
19
|
+
raise ArgumentError, 'opacity must be between 0 and 100' if @value_percentage < 0 || @value_percentage > 100
|
20
|
+
raise ArgumentError, 'location must be between 0 and 100' if location < 0 || location > 100
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Rainbow
|
2
|
+
class OpacityRange
|
3
|
+
attr_reader :from_opacity, :to_opacity, :mid_point, :gradient, :mid_opacity
|
4
|
+
attr_reader :width, :first_width, :second_width, :leftover_width
|
5
|
+
attr_reader :from_location_in_pixel, :mid_location_in_pixel, :to_location_in_pixel
|
6
|
+
attr_reader :tmp_current_x, :tmp_diff, :tmp_from, :tmp_to, :tmp_distance_in_pixel
|
7
|
+
attr_reader :scale_start_in_pixel, :scale_end_in_pixel, :scale_mid_in_pixel
|
8
|
+
|
9
|
+
def initialize(from_opacity, to_opacity, mid_point)
|
10
|
+
@from_opacity = from_opacity
|
11
|
+
@to_opacity = to_opacity
|
12
|
+
@mid_point = mid_point
|
13
|
+
|
14
|
+
@mid_opacity = from_opacity.value + (to_opacity.value - from_opacity.value) / 2
|
15
|
+
end
|
16
|
+
|
17
|
+
def included?(x)
|
18
|
+
@from_location_in_pixel <= x && x <= @to_location_in_pixel
|
19
|
+
end
|
20
|
+
|
21
|
+
def gradient=(gradient)
|
22
|
+
@gradient = gradient
|
23
|
+
compute_variables
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_x=(x)
|
27
|
+
if x == 0 && from_opacity.location > 0
|
28
|
+
@tmp_current_x = 0.0
|
29
|
+
@tmp_diff = 0
|
30
|
+
@tmp_from = from_opacity.value
|
31
|
+
@tmp_to = from_opacity.value
|
32
|
+
@tmp_distance_in_pixel = from_location_in_pixel
|
33
|
+
elsif x == to_location_in_pixel && to_opacity.location < 100
|
34
|
+
@tmp_current_x = 0.0
|
35
|
+
@tmp_diff = 0
|
36
|
+
@tmp_from = to_opacity.value
|
37
|
+
@tmp_to = to_opacity.value
|
38
|
+
@tmp_distance_in_pixel = leftover_width
|
39
|
+
elsif x == from_location_in_pixel && gradient.scale_100?
|
40
|
+
@tmp_current_x = 0.0
|
41
|
+
@tmp_diff = mid_opacity - from_opacity.value
|
42
|
+
@tmp_from = from_opacity.value
|
43
|
+
@tmp_to = mid_opacity
|
44
|
+
@tmp_distance_in_pixel = first_width
|
45
|
+
elsif x == mid_location_in_pixel && gradient.scale_100?
|
46
|
+
@tmp_current_x = 0.0
|
47
|
+
@tmp_diff = to_opacity.value - mid_opacity
|
48
|
+
@tmp_from = mid_opacity
|
49
|
+
@tmp_to = to_opacity.value
|
50
|
+
@tmp_distance_in_pixel = second_width
|
51
|
+
elsif x == from_location_in_pixel && !gradient.scale_100?
|
52
|
+
@tmp_current_x = 0.0
|
53
|
+
@tmp_diff = 0
|
54
|
+
@tmp_from = from_opacity.value
|
55
|
+
@tmp_to = from_opacity.value
|
56
|
+
@tmp_distance_in_pixel = 1
|
57
|
+
elsif x == gradient.scale_start_location_in_pixel && !gradient.scale_100?
|
58
|
+
@tmp_current_x = 0.0
|
59
|
+
@tmp_diff = mid_opacity - from_opacity.value
|
60
|
+
@tmp_from = from_opacity.value
|
61
|
+
@tmp_to = from_opacity.value
|
62
|
+
@tmp_distance_in_pixel = gradient.scale_half_distance_in_pixel
|
63
|
+
elsif x == gradient.scale_mid_location_in_pixel && !gradient.scale_100?
|
64
|
+
@tmp_current_x = 0.0
|
65
|
+
@tmp_diff = to_opacity.value - mid_opacity
|
66
|
+
@tmp_from = mid_opacity
|
67
|
+
@tmp_to = to_opacity.value
|
68
|
+
@tmp_distance_in_pixel = gradient.scale_half_distance_in_pixel
|
69
|
+
else
|
70
|
+
@tmp_current_x += 1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def compute_variables
|
77
|
+
@width = (to_opacity.location - from_opacity.location) * gradient.width / 100
|
78
|
+
@first_width = @width * mid_point / 100
|
79
|
+
@second_width = @width - @first_width
|
80
|
+
|
81
|
+
@from_location_in_pixel = from_opacity.location * gradient.width / 100
|
82
|
+
@mid_location_in_pixel = @from_location_in_pixel + @first_width
|
83
|
+
@to_location_in_pixel = @from_location_in_pixel + @width
|
84
|
+
|
85
|
+
@leftover_width = (100 - to_opacity.location) * gradient.width / 100
|
86
|
+
|
87
|
+
scale_start = (100 - gradient.scale) / 2
|
88
|
+
scale_end = scale_start == 0 ? 100 : scale_start + gradient.scale
|
89
|
+
|
90
|
+
@scale_start_in_pixel = scale_start * gradient.width / 100
|
91
|
+
@scale_end_in_pixel = scale_end * gradient.width / 100
|
92
|
+
@scale_mid_in_pixel = @scale_start_in_pixel + (@scale_end_in_pixel - @scale_start_in_pixel) / 2
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Rainbow
|
2
|
+
class OpacityRanges
|
3
|
+
extend Forwardable
|
4
|
+
def_delegators :@current_range, :tmp_current_x, :tmp_from, :tmp_to, :tmp_diff, :tmp_distance_in_pixel
|
5
|
+
|
6
|
+
attr_reader :ranges, :gradient, :current_x
|
7
|
+
|
8
|
+
def initialize(opacity_ranges, gradient)
|
9
|
+
@ranges = opacity_ranges
|
10
|
+
@gradient = gradient
|
11
|
+
|
12
|
+
@ranges.each { |range| range.gradient = gradient }
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_x=(x)
|
16
|
+
@current_range = get_range_by_x(x)
|
17
|
+
@current_range.current_x = x
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def get_range_by_x(x)
|
23
|
+
# since x is started at 0
|
24
|
+
x += 1
|
25
|
+
|
26
|
+
range = ranges.find { |r| r.included?(x) }
|
27
|
+
return range if range
|
28
|
+
|
29
|
+
first_range = ranges.first
|
30
|
+
last_range = ranges.last
|
31
|
+
|
32
|
+
if first_range.from_opacity.location > 0 && first_range.from_location_in_pixel > x
|
33
|
+
ranges.first
|
34
|
+
elsif last_range.to_opacity.location < 100 && x > last_range.to_location_in_pixel
|
35
|
+
ranges.last
|
36
|
+
else
|
37
|
+
raise "Cannot find current opacity range! .(#{first_range.from_location_in_pixel} - #{last_range.to_location_in_pixel}); (#{x})"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/rainbow.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'chunky_png'
|
4
|
+
|
5
|
+
require 'rainbow/version'
|
6
|
+
require 'rainbow/color'
|
7
|
+
require 'rainbow/color_range'
|
8
|
+
require 'rainbow/opacity'
|
9
|
+
require 'rainbow/opacity_range'
|
10
|
+
require 'rainbow/opacity_ranges'
|
11
|
+
require 'rainbow/gradient'
|
12
|
+
|
13
|
+
module Rainbow
|
14
|
+
end
|
data/rainbow.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rainbow/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'rainbow_gradient'
|
8
|
+
spec.version = Rainbow::VERSION
|
9
|
+
spec.authors = ['Sophy Eung']
|
10
|
+
spec.email = ['ungsophy@gmail.com']
|
11
|
+
spec.summary = %q{A Ruby library to generate gradient.}
|
12
|
+
spec.description = %q{A Ruby library to generate gradient.}
|
13
|
+
spec.homepage = 'https://github.com/ungsophy/rainbow'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'chunky_png', '~> 1.3.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
24
|
+
spec.add_development_dependency 'minitest', '~> 5.3.0'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
describe Rainbow::Color do
|
4
|
+
let(:red) { 112 }
|
5
|
+
let(:green) { 95 }
|
6
|
+
let(:blue) { 25 }
|
7
|
+
let(:color_int) { ChunkyPNG::Color(red, green, blue) }
|
8
|
+
let(:color) { Rainbow::Color.new(color_int, 90) }
|
9
|
+
|
10
|
+
describe 'when location is not between 0 and 100' do
|
11
|
+
it 'raises ArgumentError' do
|
12
|
+
-> { Rainbow::Color.new(color_int, 110) }.must_raise ArgumentError
|
13
|
+
-> { Rainbow::Color.new(color_int, 101) }.must_raise ArgumentError
|
14
|
+
-> { Rainbow::Color.new(color_int, -1) }.must_raise ArgumentError
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#r' do
|
19
|
+
it 'returns red color code' do
|
20
|
+
color.r.must_equal red
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#g' do
|
25
|
+
it 'returns green color code' do
|
26
|
+
color.g.must_equal green
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#b' do
|
31
|
+
it 'returns blue color code' do
|
32
|
+
color.b.must_equal blue
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
describe Rainbow::Opacity do
|
4
|
+
describe 'when opacity is not between 0 and 100' do
|
5
|
+
it 'raises ArgumentError' do
|
6
|
+
-> { Rainbow::Opacity.new(101, 0) }.must_raise ArgumentError
|
7
|
+
-> { Rainbow::Opacity.new(-1, 0) }.must_raise ArgumentError
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'when location is not between 0 and 100' do
|
12
|
+
it 'raises ArgumentError' do
|
13
|
+
-> { Rainbow::Opacity.new(10, -1) }.must_raise ArgumentError
|
14
|
+
-> { Rainbow::Opacity.new(10, 101) }.must_raise ArgumentError
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#value' do
|
19
|
+
it 'returns value' do
|
20
|
+
opacity = Rainbow::Opacity.new(10, 50)
|
21
|
+
opacity.value.must_equal 26
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rainbow_gradient
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sophy Eung
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: chunky_png
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.3.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.3.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.3.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.3.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: A Ruby library to generate gradient.
|
70
|
+
email:
|
71
|
+
- ungsophy@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- example/data/gradient2.yml
|
82
|
+
- example/data/gradient3.yml
|
83
|
+
- example/gradient.png
|
84
|
+
- example/gradient.rb
|
85
|
+
- example/gradient2.rb
|
86
|
+
- example/gradient3.rb
|
87
|
+
- example/gradient_factory.rb
|
88
|
+
- example/output/gradient.png
|
89
|
+
- example/output/gradient2_1.png
|
90
|
+
- example/output/gradient2_2.png
|
91
|
+
- example/output/gradient2_3.png
|
92
|
+
- example/output/gradient3_1.png
|
93
|
+
- example/output/gradient3_2.png
|
94
|
+
- example/output/gradient3_3.png
|
95
|
+
- example/output/gradient3_4.png
|
96
|
+
- example/psd/gradient.psd
|
97
|
+
- example/psd/gradient2.psd
|
98
|
+
- example/psd/gradient3.psd
|
99
|
+
- lib/rainbow.rb
|
100
|
+
- lib/rainbow/color.rb
|
101
|
+
- lib/rainbow/color_range.rb
|
102
|
+
- lib/rainbow/gradient.rb
|
103
|
+
- lib/rainbow/opacity.rb
|
104
|
+
- lib/rainbow/opacity_range.rb
|
105
|
+
- lib/rainbow/opacity_ranges.rb
|
106
|
+
- lib/rainbow/version.rb
|
107
|
+
- rainbow.gemspec
|
108
|
+
- test/lib/color_test.rb
|
109
|
+
- test/lib/opacity_test.rb
|
110
|
+
- test/test_helper.rb
|
111
|
+
homepage: https://github.com/ungsophy/rainbow
|
112
|
+
licenses:
|
113
|
+
- MIT
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 2.2.2
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: A Ruby library to generate gradient.
|
135
|
+
test_files:
|
136
|
+
- test/lib/color_test.rb
|
137
|
+
- test/lib/opacity_test.rb
|
138
|
+
- test/test_helper.rb
|