Class: Colorist::Color
- Inherits:
-
Object
- Object
- Colorist::Color
- Defined in:
- lib/colorist/color.rb
Overview
Color is the general class for storing and manipulating a color with the Colorist gem. It provides methods to add, subtract, and calculate aspects of the color based on W3C and other standards.
Constant Summary collapse
- CSS_COLOR_NAMES =
{ "maroon" => 0x800000, "red" => 0xff0000, "orange" => 0xffa500, "yellow" => 0xffff00, "olive" => 0x808000, "purple" => 0x800080, "fuchsia" => 0xff00ff, "white" => 0xffffff, "lime" => 0x00ff00, "green" => 0x008000, "navy" => 0x000080, "blue" => 0x0000ff, "aqua" => 0x00ffff, "teal" => 0x008080, "black" => 0x000000, "silver" => 0xc0c0c0, "gray" => 0x808080 }
Instance Attribute Summary collapse
-
#a ⇒ Object
Returns the value of attribute a.
-
#b ⇒ Object
Returns the value of attribute b.
-
#g ⇒ Object
Returns the value of attribute g.
-
#r ⇒ Object
Returns the value of attribute r.
Class Method Summary collapse
-
.from(some_entity) ⇒ Object
Create a new color from the provided object.
-
.from_hsv(hue, saturation, value) ⇒ Object
Initialize a colour based on HSV/HSB values.
- .from_hsva(hue, saturation, value, alpha) ⇒ Object
-
.from_rgb(r, g, b, options = {}) ⇒ Object
Initialize a color based on RGB values.
- .from_rgba(r, g, b, a, options = {}) ⇒ Object
-
.from_string(some_string) ⇒ Object
Converts a CSS hex string into a color.
Instance Method Summary collapse
-
#*(other) ⇒ Object
Multiply the individual RGB values of two colors together or against a Float.
-
#+(other_color) ⇒ Object
Add the individual RGB values of two colors together.
-
#-(other_color) ⇒ Object
Subtract the individual RGB values of the two colors together.
-
#/(other) ⇒ Object
Divide the individual RGB values of the two colors together or against a Float.
-
#<(other_color) ⇒ Object
Compares colors based on brightness.
-
#<=>(other_color) ⇒ Object
Compares colors based on brightness.
-
#==(other_color) ⇒ Object
Equal if the red, green, blue, and alpha values are identical.
-
#===(other_color) ⇒ Object
Equal if the brightnesses of the two colors are identical.
-
#>(other_color) ⇒ Object
Compares colors based on brightness.
-
#adjust(opts = {}) ⇒ Object
Adjusts any of H, S, V values with relative values:
opts[:h]
,opts[:s]
,opts[:v]
and returns adjusted value. -
#brightness(formula = :w3c) ⇒ Object
Returns the perceived brightness of the provided color on a scale of 0.0 to 1.0 based on the formula provided.
-
#contrast_with(other_color, formula = :w3c) ⇒ Object
Contrast this color with another color using the provided formula.
-
#dup ⇒ Object
Create a duplicate of this color.
-
#gradient_to(color, steps = 10) ⇒ Object
Uses a naive formula to generate a gradient between this color and the given color.
-
#initialize(color = 0x000000, alpha = 1.0) ⇒ Color
constructor
Creates a new color with the hex color provided as a number (i.e. 0x112233).
- #inspect ⇒ Object
-
#invert ⇒ Object
(also: #opposite)
Returns the opposite of the current color.
-
#text_color(threshold = 0.6, formula = :standard) ⇒ Object
Returns an appropriate text color (either black or white) based on the brightness of this color.
-
#to_grayscale(formula = :w3c) ⇒ Object
Converts the current color to grayscale using the brightness formula provided.
-
#to_hsv ⇒ Object
Returns an array of the hue, saturation and value of the color.
-
#to_s(format = :css) ⇒ Object
Outputs a string representation of the color in the desired format.
- #with(opts = {}) ⇒ Object
Constructor Details
#initialize(color = 0x000000, alpha = 1.0) ⇒ Color
Creates a new color with the hex color provided as a number (i.e. 0x112233)
27 28 29 30 31 32 33 |
# File 'lib/colorist/color.rb', line 27 def initialize(color = 0x000000, alpha = 1.0) string = "%.6x" % color @r = string[0..1].hex @g = string[2..3].hex @b = string[4..5].hex @a = alpha end |
Instance Attribute Details
#a ⇒ Object
Returns the value of attribute a.
6 7 8 |
# File 'lib/colorist/color.rb', line 6 def a @a end |
#b ⇒ Object
Returns the value of attribute b.
6 7 8 |
# File 'lib/colorist/color.rb', line 6 def b @b end |
#g ⇒ Object
Returns the value of attribute g.
6 7 8 |
# File 'lib/colorist/color.rb', line 6 def g @g end |
#r ⇒ Object
Returns the value of attribute r.
6 7 8 |
# File 'lib/colorist/color.rb', line 6 def r @r end |
Class Method Details
.from(some_entity) ⇒ Object
Create a new color from the provided object. Duplicates Color objects and attempts to call to_color
on other objects. Will raise an ArgumentError if it is unable to coerce the color.
109 110 111 112 113 114 115 116 117 |
# File 'lib/colorist/color.rb', line 109 def self.from(some_entity) case some_entity when Colorist::Color some_entity.dup else raise ArgumentError, "#{some_entity.class.to_s} cannot be coerced into a color.", caller unless some_entity.respond_to?(:to_color) some_entity.to_color end end |
.from_hsv(hue, saturation, value) ⇒ Object
Initialize a colour based on HSV/HSB values. Hue should be between 0 and 360 (inclusive), while saturation and value should be from 0.0 to 1.0.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/colorist/color.rb', line 57 def self.from_hsv(hue, saturation, value) saturation = 1 if saturation > 1 value = 1 if saturation > 1 # Conversion formula taken from wikipedia f = (hue / 60.0) - (hue / 60).floor p = value * (1 - saturation) q = value * (1 - (saturation * f)) t = value * (1 - (saturation * (1 - f))) r, g, b = case (hue / 60).floor % 6 when 0 then [ value, t, p ] when 1 then [ q, value, p ] when 2 then [ p, value, t ] when 3 then [ p, q, value ] when 4 then [ t, p, value ] when 5 then [ value, p, q ] end from_rgb(r, g, b, :percent => true) end |
.from_hsva(hue, saturation, value, alpha) ⇒ Object
81 82 83 84 85 |
# File 'lib/colorist/color.rb', line 81 def self.from_hsva(hue, saturation, value, alpha) color = from_hsv(hue, saturation, value) color.a = alpha color end |
.from_rgb(r, g, b, options = {}) ⇒ Object
Initialize a color based on RGB values. By default, the values should be between 0 and 255. If you use the option :percent => true
, the values should then be between 0.0 and 1.0.
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/colorist/color.rb', line 38 def self.from_rgb(r, g, b, = {}) color = new # convert from 0.0 to 1.0 to 0 to 255 if the :percent option is used if [:percent] color.r, color.g, color.b = (r * 255).round, (g * 255).round, (b * 255).round else color.r, color.g, color.b = r, g, b end color end |
.from_rgba(r, g, b, a, options = {}) ⇒ Object
49 50 51 52 53 |
# File 'lib/colorist/color.rb', line 49 def self.from_rgba(r, g, b, a, = {}) color = from_rgb(r, g, b, ) color.a = a color end |
.from_string(some_string) ⇒ Object
Converts a CSS hex string into a color. Works both with the full form (i.e. #ffffff
) and the abbreviated form (#fff
). Can also take any of the 16 named CSS colors.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/colorist/color.rb', line 90 def self.from_string(some_string) if matched = some_string.match(/\A#([0-9a-f]{3})\z/i) color = from_rgb(*matched[1].split(//).collect{|v| "#{v}#{v}".hex }) elsif matched = some_string.match(/\A#([0-9a-f]{6})\z/i) color = new color.r = matched[1][0..1].hex color.g = matched[1][2..3].hex color.b = matched[1][4..5].hex elsif CSS_COLOR_NAMES.key?(some_string) color = new(CSS_COLOR_NAMES[some_string]) else raise ArgumentError, "Must provide a valid CSS hex color or color name.", caller end color end |
Instance Method Details
#*(other) ⇒ Object
Multiply the individual RGB values of two colors together or against a Float. Colors divided in a way that is equivalent to each of the values being normalized to 0.0..1.0 prior to the operation
and normalized back to 0.0..255.0 after the operation.
You may also use an equivalent numeric or string color representation. The alpha value is kept from the original color (left-hand side).
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/colorist/color.rb', line 161 def *(other) color = self.dup if other.is_a? Float color.r *= other color.g *= other color.b *= other else other_color = self.class.from(other) color.r = color.r * other_color.r / 255.0 color.g = color.g * other_color.g / 255.0 color.b = color.b * other_color.b / 255.0 end color end |
#+(other_color) ⇒ Object
Add the individual RGB values of two colors together. You may also use an equivalent numeric or string color representation. The alpha value is kept from the original color (left-hand side).
Examples:
gray = Colorist::Color.new(0x333333)
gray + "#300" # => <Color #663333>
gray + 0x000000 # => <Color #333333>
white = "white".to_color
gray + white # => <Color #ffffff>
135 136 137 138 139 140 141 142 |
# File 'lib/colorist/color.rb', line 135 def +(other_color) other_color = self.class.from(other_color) color = self.dup color.r += other_color.r color.g += other_color.g color.b += other_color.b color end |
#-(other_color) ⇒ Object
Subtract the individual RGB values of the two colors together. You may also use an equivalent numeric or string color representation. The alpha value is kept from the original color (left-hand side).
147 148 149 150 151 152 153 154 |
# File 'lib/colorist/color.rb', line 147 def -(other_color) other_color = self.class.from(other_color) color = self.dup color.r -= other_color.r color.g -= other_color.g color.b -= other_color.b color end |
#/(other) ⇒ Object
Divide the individual RGB values of the two colors together or against a Float. Colors divided in a way that is equivalent to each of the values being normalized to 0.0..1.0 prior to the operation
and normalized back to 0.0..255.0 after the operation.
You may also use an equivalent numeric or string color representation. The alpha value is kept from the original color (left-hand side).
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/colorist/color.rb', line 183 def /(other) color = self.dup if other.is_a? Float color.r /= other color.g /= other color.b /= other else other_color = self.class.from(other) color.r = color.r / other_color.r * 255.0 color.g = color.g / other_color.g * 255.0 color.b = color.b / other_color.b * 255.0 end color end |
#<(other_color) ⇒ Object
Compares colors based on brightness.
207 208 209 210 |
# File 'lib/colorist/color.rb', line 207 def < (other_color) other_color = self.class.from(other_color) brightness < other_color.brightness end |
#<=>(other_color) ⇒ Object
Compares colors based on brightness.
201 202 203 204 |
# File 'lib/colorist/color.rb', line 201 def <=>(other_color) other_color = self.class.from(other_color) brightness <=> other_color.brightness end |
#==(other_color) ⇒ Object
Equal if the red, green, blue, and alpha values are identical.
219 220 221 222 |
# File 'lib/colorist/color.rb', line 219 def ==(other_color) other_color = self.class.from(other_color) other_color.r == self.r && other_color.g == self.g && other_color.b == self.b && other_color.a == self.a end |
#===(other_color) ⇒ Object
Equal if the brightnesses of the two colors are identical.
225 226 227 228 |
# File 'lib/colorist/color.rb', line 225 def ===(other_color) other_color = self.class.from(other_color) other_color.brightness == brightness end |
#>(other_color) ⇒ Object
Compares colors based on brightness.
213 214 215 216 |
# File 'lib/colorist/color.rb', line 213 def > (other_color) other_color = self.class.from(other_color) brightness > other_color.brightness end |
#adjust(opts = {}) ⇒ Object
Adjusts any of H, S, V values with relative values: opts[:h]
, opts[:s]
, opts[:v]
and returns adjusted value.
363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/colorist/color.rb', line 363 def adjust(opts = {}) unless [:h, :s, :v].any? { |part| opts.include? part } raise ArgumentError, "please specify at least one of :h, :s, or :v options" end h, s, v = *self.to_hsv h = (h + opts[:h]) % 360 if opts[:h] s = _clamp(s + opts[:s], 0..1) if opts[:s] v = _clamp(v + opts[:v], 0..1) if opts[:v] self.class.from_hsv(h, s, v) end |
#brightness(formula = :w3c) ⇒ Object
Returns the perceived brightness of the provided color on a scale of 0.0 to 1.0 based on the formula provided. The formulas available are:
-
:w3c
-((r * 299 + g * 587 + b * 114) / 1000 / 255
-
:standard
-sqrt(0.241 * r^2 + 0.691 * g^2 + 0.068 * b^2) / 255
294 295 296 297 298 299 300 301 |
# File 'lib/colorist/color.rb', line 294 def brightness(formula = :w3c) case formula when :standard Math.sqrt(0.241 * r**2 + 0.691 * g**2 + 0.068 * b**2) / 255 when :w3c ((r * 299 + g * 587 + b * 114) / 255000.0) end end |
#contrast_with(other_color, formula = :w3c) ⇒ Object
Contrast this color with another color using the provided formula. The available formulas are:
-
:w3c
-(max(r1 r2) - min(r1 r2)) + (max(g1 g2) - min(g1 g2)) + (max(b1 b2) - min(b1 b2))
307 308 309 310 311 312 313 314 315 |
# File 'lib/colorist/color.rb', line 307 def contrast_with(other_color, formula=:w3c) other_color = self.class.from(other_color) case formula when :w3c (([self.r, other_color.r].max - [self.r, other_color.r].min) + ([self.g, other_color.g].max - [self.g, other_color.g].min) + ([self.b, other_color.b].max - [self.b, other_color.b].min)) / 765.0 end end |
#dup ⇒ Object
Create a duplicate of this color.
120 121 122 |
# File 'lib/colorist/color.rb', line 120 def dup self.class.from_rgba(@r, @g, @b, @a) end |
#gradient_to(color, steps = 10) ⇒ Object
Uses a naive formula to generate a gradient between this color and the given color. Returns the array of colors that make the gradient, including this color and the target color. By default will return 10 colors, but this can be changed by supplying an optional steps parameter.
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/colorist/color.rb', line 328 def gradient_to(color, steps = 10) color_to = self.class.from(color) red = color_to.r - r green = color_to.g - g blue = color_to.b - b result = (1..(steps - 3)).to_a.collect do |step| percentage = step.to_f / (steps - 1) self.class.from_rgb(r + (red * percentage), g + (green * percentage), b + (blue * percentage)) end # Add first and last colors to result, avoiding uneccessary calculation and rounding errors result.unshift(self.dup) result.push(color.dup) result end |
#inspect ⇒ Object
284 285 286 |
# File 'lib/colorist/color.rb', line 284 def inspect "#<Color #{to_s(:css_rgba)}>" end |
#invert ⇒ Object Also known as: opposite
Returns the opposite of the current color.
318 319 320 |
# File 'lib/colorist/color.rb', line 318 def invert self.class.from_rgba(255 - r, 255 - g, 255 - b, a) end |
#text_color(threshold = 0.6, formula = :standard) ⇒ Object
Returns an appropriate text color (either black or white) based on the brightness of this color. The threshold
specifies the brightness cutoff point.
357 358 359 |
# File 'lib/colorist/color.rb', line 357 def text_color(threshold = 0.6, formula = :standard) brightness(formula) > threshold ? self.class.new(0x000000) : self.class.new(0xffffff) end |
#to_grayscale(formula = :w3c) ⇒ Object
Converts the current color to grayscale using the brightness formula provided. See #brightness for a description of the available formulas.
349 350 351 352 |
# File 'lib/colorist/color.rb', line 349 def to_grayscale(formula = :w3c) b = brightness(formula) self.class.from_rgb(255 * b, 255 * b, 255 * b) end |
#to_hsv ⇒ Object
Returns an array of the hue, saturation and value of the color. Hue will range from 0-359, hue and saturation will be between 0 and 1.
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/colorist/color.rb', line 265 def to_hsv red, green, blue = *[r, g, b].collect {|x| x / 255.0} max = [red, green, blue].max min = [red, green, blue].min if min == max hue = 0 elsif max == red hue = 60 * ((green - blue) / (max - min)) elsif max == green hue = 60 * ((blue - red) / (max - min)) + 120 elsif max == blue hue = 60 * ((red - green) / (max - min)) + 240 end saturation = (max == 0) ? 0 : (max - min) / max [hue % 360, saturation, max] end |
#to_s(format = :css) ⇒ Object
Outputs a string representation of the color in the desired format. The available formats are:
-
:css
- As a CSS hex string (i.e.#ffffff
) (default) -
:css_rgb
- As a CSS RGB value string (i.e.rgb(255, 255, 255)
) -
:css_rgba
- As a CSS RGBA value string (i.e.rgb(255, 255, 255, 1.0)
) -
:rgb
- As an RGB triplet (i.e.1.0, 1.0, 1.0
) -
:rgba
- As an RGBA quadruplet (i.e.1.0, 1.0, 1.0, 1.0
)
247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/colorist/color.rb', line 247 def to_s(format=:css) case format when :css "#%.2x%.2x%.2x" % [r, g, b] when :css_rgb "rgb(%d, %d, %d)" % [r, g, b] when :css_rgba "rgba(%d, %d, %d, %.3f)" % [r, g, b, a] when :rgb "%.3f, %.3f, %.3f" % [r / 255, g / 255, b / 255] when :rgba "%.3f, %.3f, %.3f, %.3f" % [r / 255, g / 255, b / 255, a / 255] end end |
#with(opts = {}) ⇒ Object
379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/colorist/color.rb', line 379 def with(opts = {}) unless [:r, :g, :b, :a].any? { |part| opts.include? part } raise ArgumentError, "please specify at least one of :r, :g, :b, or :a options" end color = self.dup color.r = opts[:r] if opts[:r] color.g = opts[:g] if opts[:g] color.b = opts[:b] if opts[:b] color.a = opts[:a] if opts[:a] color end |