color_palette 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/color_palette.rb +28 -0
- data/lib/color_palette/color/rgb.rb +296 -0
- data/lib/color_palette/version.rb +3 -0
- data/spec/color_palette_spec.rb +26 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 235899892340cee9ffb5e918be86839bfe208d04
|
4
|
+
data.tar.gz: ed25701723e172dceec1747e3c704963f69b423a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3e348480f756482b569bcf3e4eca879ce7212cea5c8bb47476f16250a90e88742d27a31cb2794fee020393a7fd22d8d9cf159ea9d9ecdfed7f49fcdefb09c8d
|
7
|
+
data.tar.gz: 551fb57fe65b466934223ff6d72fe7c11a8c9a5bdccda3a5b8d6d9f9e2d1d8a4c4adde58f7d88e14c3741542da3a75b37861756d3615caca96ba4e0a422e0d3f
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module ColorPalette
|
3
|
+
|
4
|
+
def self.unidirectional(end_color, palette_size, start_color="#ffffff", return_color_strings=true)
|
5
|
+
start_color = ColorPalette::Color::RGB.from_string(start_color)
|
6
|
+
end_color = ColorPalette::Color::RGB.from_string(end_color)
|
7
|
+
|
8
|
+
delta_r = (end_color.r - start_color.r) / (palette_size - 1)
|
9
|
+
delta_g = (end_color.g - start_color.g) / (palette_size - 1)
|
10
|
+
delta_b = (end_color.b - start_color.b) / (palette_size - 1)
|
11
|
+
|
12
|
+
palette = []
|
13
|
+
palette_size.times do |i|
|
14
|
+
color = ColorPalette::Color::RGB.from_increment_in_other_color(start_color, i*delta_r, i*delta_g, i*delta_b)
|
15
|
+
palette << color
|
16
|
+
end
|
17
|
+
|
18
|
+
if return_color_strings
|
19
|
+
palette.map(&:to_s)
|
20
|
+
else
|
21
|
+
palette
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'color_palette/version'
|
28
|
+
require 'color_palette/color/rgb'
|
@@ -0,0 +1,296 @@
|
|
1
|
+
# Inspired by the work of 2005 Austin Ziegler (http://rubyforge.org/ruby-pdf/)
|
2
|
+
|
3
|
+
# An RGB colour object.
|
4
|
+
module ColorPalette::Color
|
5
|
+
class RGB
|
6
|
+
|
7
|
+
attr_accessor :r, :g, :b
|
8
|
+
|
9
|
+
# Creates an RGB colour object from percentages 0..100.
|
10
|
+
def self.from_percentages(r=0, g=0, b=0)
|
11
|
+
from_fractions(r/100.0, g/100.0, b/100.0)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Creates an RGB colour object from integer values 0..255.
|
15
|
+
def self.from_integers(r=0, g=0, b=0)
|
16
|
+
from_fractions(r/255.0, g/255.0, b/255.0)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Creates an RGB colour object from fractional values 0..1.
|
20
|
+
def self.from_fractions(r=0.0, g=0.0, b=0.0)
|
21
|
+
color = ColorPalette::Color::RGB.new
|
22
|
+
color.r = r
|
23
|
+
color.g = g
|
24
|
+
color.b = b
|
25
|
+
color
|
26
|
+
end
|
27
|
+
|
28
|
+
# Creates an RGB color object from a hex string (e.g.,
|
29
|
+
#
|
30
|
+
# Color::RGB.from_string("bef")
|
31
|
+
# Color::RGB.from_string("#bef")
|
32
|
+
# Color::RGB.from_string("#dabbec")
|
33
|
+
# Color::RGB.from_string("dabbec")
|
34
|
+
def self.from_string(color_string)
|
35
|
+
# remove hashtag if necessary
|
36
|
+
color_string = color_string.gsub(%r{[#;]}, '')
|
37
|
+
|
38
|
+
case color_string.size
|
39
|
+
when 3
|
40
|
+
colors = color_string.scan(/[0-9A-Fa-f]/).map { |color_value| (color_value * 2).to_i(16) }
|
41
|
+
when 6
|
42
|
+
colors = color_string.scan(/[0-9A-Fa-f]{2}/).map { |color_value| color_value.to_i(16) }
|
43
|
+
else
|
44
|
+
raise ArgumentError
|
45
|
+
end
|
46
|
+
|
47
|
+
from_integers(*colors)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.from_increment_in_other_color(other_color, r_increment, g_increment, b_increment)
|
51
|
+
color = from_fractions(other_color.r, other_color.g, other_color.b)
|
52
|
+
color.r = color.r + r_increment
|
53
|
+
color.g = color.g + g_increment
|
54
|
+
color.b = color.b + b_increment
|
55
|
+
color
|
56
|
+
end
|
57
|
+
|
58
|
+
# Compares the other colour to this one. This will report that two
|
59
|
+
# RGB colours are equivalent if all component values are within 1e-4
|
60
|
+
# (0.0001) of each other.
|
61
|
+
def ==(other_color)
|
62
|
+
# The other color will be converted to RGB before comparison. If there is no #to_rgb
|
63
|
+
# conversion, this will raise an exception.
|
64
|
+
other_color = other_color.to_rgb
|
65
|
+
|
66
|
+
if other_color.is_a?(ColorPalette::Color::RGB)
|
67
|
+
return ((@r - other_color.r).abs <= 1e-4) &&
|
68
|
+
((@g - other_color.g).abs <= 1e-4) &&
|
69
|
+
((@b - other_color.b).abs <= 1e-4)
|
70
|
+
end
|
71
|
+
|
72
|
+
return false
|
73
|
+
end
|
74
|
+
|
75
|
+
# Creates a black RGB colour object. Please use class methods from_* to create other colors.
|
76
|
+
def initialize
|
77
|
+
self.r = 0.0
|
78
|
+
self.g = 0.0
|
79
|
+
self.b = 0.0
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_s
|
83
|
+
r_integer = (r * 255).round
|
84
|
+
r_integer = 255 if r_integer > 255
|
85
|
+
|
86
|
+
g_integer = (g * 255).round
|
87
|
+
g_integer = 255 if g_integer > 255
|
88
|
+
|
89
|
+
b_integer = (b * 255).round
|
90
|
+
b_integer = 255 if b_integer > 255
|
91
|
+
|
92
|
+
"#%02x%02x%02x" % [ r_integer, g_integer, b_integer ]
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_rgb
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
# overload setters to garantee storing in floats and in range 0..1
|
100
|
+
def r=(red)
|
101
|
+
red = 1.0 if red > 1
|
102
|
+
red = 0.0 if red < 0
|
103
|
+
@r = red.to_f
|
104
|
+
end
|
105
|
+
|
106
|
+
def g=(green)
|
107
|
+
green = 1.0 if green > 1
|
108
|
+
green = 0.0 if green < 0
|
109
|
+
@g = green.to_f
|
110
|
+
end
|
111
|
+
|
112
|
+
def b=(blue)
|
113
|
+
blue = 1.0 if blue > 1
|
114
|
+
blue = 0.0 if blue < 0
|
115
|
+
@b = blue.to_f
|
116
|
+
end
|
117
|
+
|
118
|
+
# # Converts the RGB colour to CMYK. Most colour experts strongly suggest
|
119
|
+
# # that this is not a good idea (some even suggesting that it's a very
|
120
|
+
# # bad idea). CMYK represents additive percentages of inks on white
|
121
|
+
# # paper, whereas RGB represents mixed colour intensities on a black
|
122
|
+
# # screen.
|
123
|
+
# #
|
124
|
+
# # However, the colour conversion can be done. The basic method is
|
125
|
+
# # multi-step:
|
126
|
+
# #
|
127
|
+
# # 1. Convert the R, G, and B components to C, M, and Y components.
|
128
|
+
# # c = 1.0 – r
|
129
|
+
# # m = 1.0 – g
|
130
|
+
# # y = 1.0 – b
|
131
|
+
# # 2. Compute the minimum amount of black (K) required to smooth the
|
132
|
+
# # colour in inks.
|
133
|
+
# # k = min(c, m, y)
|
134
|
+
# # 3. Perform undercolour removal on the C, M, and Y components of the
|
135
|
+
# # colours because less of each colour is needed for each bit of
|
136
|
+
# # black. Also, regenerate the black (K) based on the undercolour
|
137
|
+
# # removal so that the colour is more accurately represented in ink.
|
138
|
+
# # c = min(1.0, max(0.0, c – UCR(k)))
|
139
|
+
# # m = min(1.0, max(0.0, m – UCR(k)))
|
140
|
+
# # y = min(1.0, max(0.0, y – UCR(k)))
|
141
|
+
# # k = min(1.0, max(0.0, BG(k)))
|
142
|
+
# #
|
143
|
+
# # The undercolour removal function and the black generation functions
|
144
|
+
# # return a value based on the brightness of the RGB colour.
|
145
|
+
# def to_cmyk
|
146
|
+
# c = 1.0 - @r.to_f
|
147
|
+
# m = 1.0 - @g.to_f
|
148
|
+
# y = 1.0 - @b.to_f
|
149
|
+
|
150
|
+
# k = [c, m, y].min
|
151
|
+
# k = k - (k * brightness)
|
152
|
+
|
153
|
+
# c = [1.0, [0.0, c - k].max].min
|
154
|
+
# m = [1.0, [0.0, m - k].max].min
|
155
|
+
# y = [1.0, [0.0, y - k].max].min
|
156
|
+
# k = [1.0, [0.0, k].max].min
|
157
|
+
|
158
|
+
# Color::CMYK.from_fraction(c, m, y, k)
|
159
|
+
# end
|
160
|
+
|
161
|
+
# # Returns the YIQ (NTSC) colour encoding of the RGB value.
|
162
|
+
# def to_yiq
|
163
|
+
# y = (@r * 0.299) + (@g * 0.587) + (@b * 0.114)
|
164
|
+
# i = (@r * 0.596) + (@g * -0.275) + (@b * -0.321)
|
165
|
+
# q = (@r * 0.212) + (@g * -0.523) + (@b * 0.311)
|
166
|
+
# Color::YIQ.from_fraction(y, i, q)
|
167
|
+
# end
|
168
|
+
|
169
|
+
# # Returns the HSL colour encoding of the RGB value.
|
170
|
+
# def to_hsl
|
171
|
+
# min = [ @r, @g, @b ].min
|
172
|
+
# max = [ @r, @g, @b ].max
|
173
|
+
# delta = (max - min).to_f
|
174
|
+
|
175
|
+
# lum = (max + min) / 2.0
|
176
|
+
|
177
|
+
# if delta <= 1e-5 # close to 0.0, so it's a grey
|
178
|
+
# hue = 0
|
179
|
+
# sat = 0
|
180
|
+
# else
|
181
|
+
# if (lum - 0.5) <= 1e-5
|
182
|
+
# sat = delta / (max + min).to_f
|
183
|
+
# else
|
184
|
+
# sat = delta / (2 - max - min).to_f
|
185
|
+
# end
|
186
|
+
|
187
|
+
# if @r == max
|
188
|
+
# hue = (@g - @b) / delta.to_f
|
189
|
+
# elsif @g == max
|
190
|
+
# hue = (2.0 + @b - @r) / delta.to_f
|
191
|
+
# elsif (@b - max) <= 1e-5
|
192
|
+
# hue = (4.0 + @r - @g) / delta.to_f
|
193
|
+
# end
|
194
|
+
# hue /= 6.0
|
195
|
+
|
196
|
+
# hue += 1 if hue < 0
|
197
|
+
# hue -= 1 if hue > 1
|
198
|
+
# end
|
199
|
+
# Color::HSL.from_fraction(hue, sat, lum)
|
200
|
+
# end
|
201
|
+
|
202
|
+
# # Mix the RGB hue with White so that the RGB hue is the specified
|
203
|
+
# # percentage of the resulting colour. Strictly speaking, this isn't a
|
204
|
+
# # darken_by operation.
|
205
|
+
# def lighten_by(percent)
|
206
|
+
# mix_with(White, percent)
|
207
|
+
# end
|
208
|
+
|
209
|
+
# # Mix the RGB hue with Black so that the RGB hue is the specified
|
210
|
+
# # percentage of the resulting colour. Strictly speaking, this isn't a
|
211
|
+
# # darken_by operation.
|
212
|
+
# def darken_by(percent)
|
213
|
+
# mix_with(Black, percent)
|
214
|
+
# end
|
215
|
+
|
216
|
+
# # Mix the mask colour (which must be an RGB object) with the current
|
217
|
+
# # colour at the stated opacity percentage (0..100).
|
218
|
+
# def mix_with(mask, opacity)
|
219
|
+
# opacity /= 100.0
|
220
|
+
# rgb = self.dup
|
221
|
+
|
222
|
+
# rgb.r = (@r * opacity) + (mask.r * (1 - opacity))
|
223
|
+
# rgb.g = (@g * opacity) + (mask.g * (1 - opacity))
|
224
|
+
# rgb.b = (@b * opacity) + (mask.b * (1 - opacity))
|
225
|
+
|
226
|
+
# rgb
|
227
|
+
# end
|
228
|
+
|
229
|
+
# # Returns the brightness value for a colour, a number between 0..1.
|
230
|
+
# # Based on the Y value of YIQ encoding, representing luminosity, or
|
231
|
+
# # perceived brightness.
|
232
|
+
# #
|
233
|
+
# # This may be modified in a future version of color-tools to use the
|
234
|
+
# # luminosity value of HSL.
|
235
|
+
# def brightness
|
236
|
+
# to_yiq.y
|
237
|
+
# end
|
238
|
+
|
239
|
+
# def to_grayscale
|
240
|
+
# Color::GrayScale.from_fraction(to_hsl.l)
|
241
|
+
# end
|
242
|
+
|
243
|
+
# alias to_greyscale to_grayscale
|
244
|
+
|
245
|
+
# # Returns a new colour with the brightness adjusted by the specified
|
246
|
+
# # percentage. Negative percentages will darken the colour; positive
|
247
|
+
# # percentages will brighten the colour.
|
248
|
+
# #
|
249
|
+
# # Color::RGB::DarkBlue.adjust_brightness(10)
|
250
|
+
# # Color::RGB::DarkBlue.adjust_brightness(-10)
|
251
|
+
# def adjust_brightness(percent)
|
252
|
+
# percent /= 100.0
|
253
|
+
# percent += 1.0
|
254
|
+
# percent = [ percent, 2.0 ].min
|
255
|
+
# percent = [ 0.0, percent ].max
|
256
|
+
|
257
|
+
# hsl = to_hsl
|
258
|
+
# hsl.l *= percent
|
259
|
+
# hsl.to_rgb
|
260
|
+
# end
|
261
|
+
|
262
|
+
# # Returns a new colour with the saturation adjusted by the specified
|
263
|
+
# # percentage. Negative percentages will reduce the saturation; positive
|
264
|
+
# # percentages will increase the saturation.
|
265
|
+
# #
|
266
|
+
# # Color::RGB::DarkBlue.adjust_saturation(10)
|
267
|
+
# # Color::RGB::DarkBlue.adjust_saturation(-10)
|
268
|
+
# def adjust_saturation(percent)
|
269
|
+
# percent /= 100.0
|
270
|
+
# percent += 1.0
|
271
|
+
# percent = [ percent, 2.0 ].min
|
272
|
+
# percent = [ 0.0, percent ].max
|
273
|
+
|
274
|
+
# hsl = to_hsl
|
275
|
+
# hsl.s *= percent
|
276
|
+
# hsl.to_rgb
|
277
|
+
# end
|
278
|
+
|
279
|
+
# # Returns a new colour with the hue adjusted by the specified
|
280
|
+
# # percentage. Negative percentages will reduce the hue; positive
|
281
|
+
# # percentages will increase the hue.
|
282
|
+
# #
|
283
|
+
# # Color::RGB::DarkBlue.adjust_hue(10)
|
284
|
+
# # Color::RGB::DarkBlue.adjust_hue(-10)
|
285
|
+
# def adjust_hue(percent)
|
286
|
+
# percent /= 100.0
|
287
|
+
# percent += 1.0
|
288
|
+
# percent = [ percent, 2.0 ].min
|
289
|
+
# percent = [ 0.0, percent ].max
|
290
|
+
|
291
|
+
# hsl = to_hsl
|
292
|
+
# hsl.h *= percent
|
293
|
+
# hsl.to_rgb
|
294
|
+
# end
|
295
|
+
end
|
296
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ColorPalette do
|
4
|
+
describe '.unidirectional' do
|
5
|
+
it 'should return an array of colors starting with white and ending with the specified color' do
|
6
|
+
colors = ColorPalette.unidirectional('#ff0000', 5)
|
7
|
+
expect(colors.size).to be == 5
|
8
|
+
expect(colors.first).to be == '#ffffff'
|
9
|
+
expect(colors.last).to be == '#ff0000'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should accept a color as start color' do
|
13
|
+
colors = ColorPalette.unidirectional('#ff0000', 5, '#000000')
|
14
|
+
expect(colors.size).to be == 5
|
15
|
+
expect(colors.first).to be == '#000000'
|
16
|
+
expect(colors.last).to be == '#ff0000'
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should accept many formats of color strings' do
|
20
|
+
expect { ColorPalette.unidirectional('#ff0000', 5, '#000000') }.to_not raise_error
|
21
|
+
expect { ColorPalette.unidirectional('#f00', 5, '#00F') }.to_not raise_error
|
22
|
+
expect { ColorPalette.unidirectional('ff0000', 5, '000000') }.to_not raise_error
|
23
|
+
expect { ColorPalette.unidirectional('f00', 5, '00F') }.to_not raise_error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: color_palette
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Henrique Gubert
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
description: This gem aims to be as simple as possible helping you to create palettes
|
56
|
+
dynamically. No more hard-coding a lot of colors in your ruby code!
|
57
|
+
email:
|
58
|
+
- guberthenrique@hotmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/color_palette.rb
|
64
|
+
- lib/color_palette/color/rgb.rb
|
65
|
+
- lib/color_palette/version.rb
|
66
|
+
- spec/color_palette_spec.rb
|
67
|
+
homepage: https://github.com/hsgubert/color_palette
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.8.0
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.4.1
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Simple gem to build palettes (sequence of colors) of various types based
|
91
|
+
on one or more reference colors.
|
92
|
+
test_files:
|
93
|
+
- spec/color_palette_spec.rb
|