Class: Rustle::Color
- Inherits:
-
Object
- Object
- Rustle::Color
- Defined in:
- lib/rustle/color.rb
Constant Summary collapse
- VALID_HEX_COLOR =
The Regex which verifies that a valid hex color code is supplied. It merely checks that a string is 6 characters long and consists of hexadecimal characters.
/^[0-9a-f]{6}$/i
Instance Attribute Summary collapse
-
#b ⇒ Fixnum
readonly
The blue value of the color.
-
#g ⇒ Fixnum
readonly
The green value of the color.
-
#r ⇒ Fixnum
readonly
The red value of the color.
Class Method Summary collapse
-
.hex(hex_value) ⇒ Color
Creates a new color object given a hexadecimal value.
-
.hsb(hue, sat, bri) ⇒ Color
Creates a new Color object given HSB color values.
-
.rgb(r, g, b) ⇒ Object
Creates a new Color object given RGB values.
Instance Method Summary collapse
-
#eql?(other) ⇒ Boolean
Checks if a color is equal to another color.
-
#initialize(r, g, b) ⇒ Color
constructor
Creates a new Color object given RGB values in the range
0..255
. -
#serialize ⇒ String
Serializes a color into a string of
chars
. -
#to_a ⇒ Array<Fixnum>
The Color’s RGB values as an array with the format [r, g, b].
-
#to_hsb ⇒ Array<Fixnum>
Converts the Color object to an array of HSB values in the format [hue, saturation, brightness].
-
#transition_to(other, amount) ⇒ Color
Creates an intermediate between the current Color object and another Color object.
Constructor Details
#initialize(r, g, b) ⇒ Color
Creates a new Color object given RGB values in the range 0..255
. Other values are accepted, but they will be coerced into this range (this is preferable to throwing exceptions, because there’s a slim chance that an internal method will have some rounding errors).
27 28 29 30 31 |
# File 'lib/rustle/color.rb', line 27 def initialize(r, g, b) @r = normalize_rgb_param(r) @g = normalize_rgb_param(g) @b = normalize_rgb_param(b) end |
Instance Attribute Details
#b ⇒ Fixnum (readonly)
Returns the blue value of the color.
10 11 12 |
# File 'lib/rustle/color.rb', line 10 def b @b end |
#g ⇒ Fixnum (readonly)
Returns the green value of the color.
7 8 9 |
# File 'lib/rustle/color.rb', line 7 def g @g end |
#r ⇒ Fixnum (readonly)
Returns the red value of the color.
4 5 6 |
# File 'lib/rustle/color.rb', line 4 def r @r end |
Class Method Details
.hex(hex_value) ⇒ Color
Creates a new color object given a hexadecimal value.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rustle/color.rb', line 85 def self.hex(hex_value) # Remove leading hash hex_value = hex_value[1..-1] if hex_value[0] == '#' # Convert f00 to ff0000 if hex_value.length == 3 hex_value = hex_value.split("").map { |s| s+s }.join end # Validate the format raise InvalidHexColorCode unless hex_value =~ VALID_HEX_COLOR self.new *( hex_value.scan(/.{2}/).map(&:hex) ) end |
.hsb(hue, sat, bri) ⇒ Color
Creates a new Color object given HSB color values.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/rustle/color.rb', line 107 def self.hsb(hue, sat, bri) hue = fit_within_range(hue, 0, 360) sat = fit_within_range(sat, 0, 1) bri = fit_within_range(bri, 0, 1) if sat == 0 r = g = b = bri else hh = hue % 360 hh /= 60.0 i = hh.to_i f = hh - i p = bri * (1 - sat) q = bri * (1 - sat * f) t = bri * (1 - sat * (1 - f)) case i when 0 r = bri g = t b = p when 1 r = q g = bri b = p when 2 r = p g = bri b = t when 3 r = p g = q b = bri when 4 r = t g = p b = bri else r = bri g = p b = q end end self.new *( [r, g, b].map { |c| (c * 255 + 0.5) } ) end |
.rgb(r, g, b) ⇒ Object
Creates a new Color object given RGB values. Equivalent to #initialize.
34 35 36 |
# File 'lib/rustle/color.rb', line 34 def self.rgb(r, g, b) self.new(r, g, b) end |
Instance Method Details
#eql?(other) ⇒ Boolean
Checks if a color is equal to another color.
66 67 68 |
# File 'lib/rustle/color.rb', line 66 def eql?(other) [:r, :g, :b].all? { |c| self.send(c) == other.send(c) } end |
#serialize ⇒ String
Serializes a color into a string of chars
. Note that each color is coerced into the range 0..254
, since our end-of-frame code is 255.
49 50 51 |
# File 'lib/rustle/color.rb', line 49 def serialize to_a.map { |c| self.class.fit_within_range(c, 0, 254).chr }.join end |
#to_a ⇒ Array<Fixnum>
Returns the Color’s RGB values as an array with the format [r, g, b].
40 41 42 |
# File 'lib/rustle/color.rb', line 40 def to_a [@r, @g, @b].map(&:floor) end |
#to_hsb ⇒ Array<Fixnum>
Converts the Color object to an array of HSB values in the format [hue, saturation, brightness].
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rustle/color.rb', line 159 def to_hsb r = @r / 255.0 g = @g / 255.0 b = @b / 255.0 max = [r, g, b].max min = [r, g, b].min delta = max - min hue = 0.0 brightness = max saturation = max == 0 ? 0 : (max - min) / max if delta != 0 if r == max hue = (g - b) / delta else if g == max hue = 2 + (b - r) / delta else hue = 4 + (r - g) / delta end end hue *= 60 hue += 360 if hue < 0 end [hue, saturation, brightness] end |
#transition_to(other, amount) ⇒ Color
Creates an intermediate between the current Color object and another Color object. It does so by simple linear RGB transitioning, which seems to work just fine when working with RGB LED strips (even though, in most) cases, HSB transitioning would be better, it is not worth the extra processing time).
204 205 206 207 208 209 210 211 |
# File 'lib/rustle/color.rb', line 204 def transition_to(other, amount) old_col = self.to_a new_col = other.to_a diff = old_col.each_with_index.map { |v, i| (new_col[i] - v) * amount } self.class.rgb *old_col.each_with_index.map { |v, i| v + diff[i] } end |