Class: Color

Inherits:
Object show all
Defined in:
lib/iron/web/color.rb

Overview

Implements a color (r,g,b + a) with conversion to/from web format (eg #aabbcc), and with a number of utilities to lighten, darken and blend values.

Constant Summary collapse

HEXVAL =

Table for conversion to hex

(('0'..'9').to_a).concat(('A'..'F').to_a).freeze
BRIGHTNESS_DEFAULT =

Default value for #darken, #lighten etc.

0.2
WHITE =

Some constants for general use

Color.new(255,255,255).freeze
BLACK =
Color.new(0,0,0).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Color

Construct ourselves from whatever is passed in



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/iron/web/color.rb', line 15

def initialize(*args)
  @r = 255
  @g = 255
  @b = 255
  @a = 255

  if args.size.between?(3,4)
    self.r = args[0]
    self.g = args[1]
    self.b = args[2]
    self.a = args[3] if args[3]
  else
    set(*args)
  end
end

Instance Attribute Details

#aObject

Basic attributes - holds each channel as 0-255 fixnum



7
8
9
# File 'lib/iron/web/color.rb', line 7

def a
  @a
end

#bObject

Basic attributes - holds each channel as 0-255 fixnum



7
8
9
# File 'lib/iron/web/color.rb', line 7

def b
  @b
end

#gObject

Basic attributes - holds each channel as 0-255 fixnum



7
8
9
# File 'lib/iron/web/color.rb', line 7

def g
  @g
end

#rObject

Basic attributes - holds each channel as 0-255 fixnum



7
8
9
# File 'lib/iron/web/color.rb', line 7

def r
  @r
end

Class Method Details

.average(col1, col2) ⇒ Object



229
230
231
# File 'lib/iron/web/color.rb', line 229

def self.average(col1, col2)
  self.blend(col1, col2, 0.5)
end

.blend(col1, col2, amt) ⇒ Object



223
224
225
226
227
# File 'lib/iron/web/color.rb', line 223

def self.blend(col1, col2, amt)
  col1 = Color.parse(col1)
  col2 = Color.parse(col2)
  col1.blend(col2, amt)
end

.lookup_callbackObject

Get the lookup callback, if any



65
66
67
# File 'lib/iron/web/color.rb', line 65

def self.lookup_callback
  @lookup_callback
end

.lookup_callback=(callback) ⇒ Object

Assigns a callback lambda to convert symbols into parse-able values. Sample usage:

Color.lookup_callback = lambda {|val| Settings[:site][:colors].get!(val) }
rgb(:off_white)  # => '#f8f0ee'


60
61
62
# File 'lib/iron/web/color.rb', line 60

def self.lookup_callback=(callback)
  @lookup_callback = callback
end

.parse(*args) ⇒ Object

Attempt to read in a string and parse it into values



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/iron/web/color.rb', line 70

def self.parse(*args)
  case args.size

  when 0 then
    return nil

  when 1 then
    val = args[0]

    # Trivial parse... :-)
    return val if val.is_a?(Color)

    # Lookup site settings if symbol
    if val.is_a?(Symbol)
      callback = Color.lookup_callback
      return callback.nil? ? nil : self.parse(callback.call(val))
    end

    # Single value, assume grayscale
    return Color.new(val, val, val) if val.is_a?(Fixnum)

    # Assume string
    str = val.to_s.upcase
    str = str[/[0-9A-F]{3,8}/] || ''
    case str.size
    when 3, 4 then
      r, g, b, a = str.scan(/[0-9A-F]/)
    when 6, 8 then
      r, g, b, a = str.scan(/[0-9A-F]{2}/)
    else
      return nil
    end
    a = 255 if a.nil?

    return Color.new(r,g,b,a)

  when 3,4 then
    return Color.new(*args)

  end
  nil
end

Instance Method Details

#==(val) ⇒ Object

Test for equality, accepts string vals as well, eg Color.new(‘aaa’) == ‘#AAAAAA’ => true



44
45
46
47
48
# File 'lib/iron/web/color.rb', line 44

def ==(val)
  val = Color.parse(val)
  return false if val.nil?
  return r == val.r && g == val.g && b == val.b && a == val.a
end

#blend(other, amt) ⇒ Object

Blend to a color amt % towards another color value



207
208
209
210
211
212
213
214
215
216
# File 'lib/iron/web/color.rb', line 207

def blend(other, amt)
  other = Color.parse(other)
  return Color.new(self) if amt <= 0 || other.nil?
  return Color.new(other) if amt >= 1.0
  val = Color.new(self)
  val.r += ((other.r - val.r)*amt).to_i
  val.g += ((other.g - val.g)*amt).to_i
  val.b += ((other.b - val.b)*amt).to_i
  val
end

#blend!(other, amt) ⇒ Object



218
219
220
221
# File 'lib/iron/web/color.rb', line 218

def blend!(other, amt)
  set(blend(other, amt))
  self
end

#brightnessObject

Compute our overall brightness, using perception-based weighting, from 0.0 to 1.0



189
190
191
# File 'lib/iron/web/color.rb', line 189

def brightness
  (0.2126 * self.r + 0.7152 * self.g + 0.0722 * self.b) / 255.0
end

#contrast(amt = BRIGHTNESS_DEFAULT) ⇒ Object

Go towards middle of brightness scale, based on whether color is dark or light.



174
175
176
# File 'lib/iron/web/color.rb', line 174

def contrast(amt = BRIGHTNESS_DEFAULT)
  dark? ? lighten(amt) : darken(amt)
end

#contrast!(amt = BRIGHTNESS_DEFAULT) ⇒ Object



178
179
180
181
# File 'lib/iron/web/color.rb', line 178

def contrast!(amt = BRIGHTNESS_DEFAULT)
  set(contrast(amt))
  self
end

#dark?Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/iron/web/color.rb', line 193

def dark?
  brightness < 0.5
end

#darken(amt = BRIGHTNESS_DEFAULT) ⇒ Object

Darken color by amt



158
159
160
161
162
163
164
165
166
# File 'lib/iron/web/color.rb', line 158

def darken(amt = BRIGHTNESS_DEFAULT)
  return self if amt <= 0
  return BLACK if amt >= 1.0
  val = Color.new(self)
  val.r -= (val.r * amt).to_i
  val.g -= (val.g * amt).to_i
  val.b -= (val.b * amt).to_i
  val
end

#darken!(amt = BRIGHTNESS_DEFAULT) ⇒ Object



168
169
170
171
# File 'lib/iron/web/color.rb', line 168

def darken!(amt = BRIGHTNESS_DEFAULT)
  set(darken(amt))
  self
end

#grayscaleObject

Convert to grayscale



184
185
186
# File 'lib/iron/web/color.rb', line 184

def grayscale
  Color.new(self.brightness)
end

#grayscale!Object



201
202
203
204
# File 'lib/iron/web/color.rb', line 201

def grayscale!
  set(grayscale)
  self
end

#grayscale?Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/iron/web/color.rb', line 137

def grayscale?
  @r == @g && @g == @b
end

#inspectObject



113
114
115
# File 'lib/iron/web/color.rb', line 113

def inspect
  to_s
end

#light?Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/iron/web/color.rb', line 197

def light?
  !dark?
end

#lighten(amt = BRIGHTNESS_DEFAULT) ⇒ Object

Lighten color by amt



142
143
144
145
146
147
148
149
150
# File 'lib/iron/web/color.rb', line 142

def lighten(amt = BRIGHTNESS_DEFAULT)
  return self if amt <= 0
  return WHITE if amt >= 1.0
  val = Color.new(self)
  val.r += ((255-val.r) * amt).to_i
  val.g += ((255-val.g) * amt).to_i
  val.b += ((255-val.b) * amt).to_i
  val
end

#lighten!(amt = BRIGHTNESS_DEFAULT) ⇒ Object



152
153
154
155
# File 'lib/iron/web/color.rb', line 152

def lighten!(amt = BRIGHTNESS_DEFAULT)
  set(lighten(amt))
  self
end

#opaque?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/iron/web/color.rb', line 129

def opaque?
  @a == 255
end

#set(*args) ⇒ Object

All-purpose setter - pass in another Color, ‘#000000’, rgb vals… whatever



32
33
34
35
36
37
38
39
40
41
# File 'lib/iron/web/color.rb', line 32

def set(*args)
  val = Color.parse(*args)
  unless val.nil?
    self.r = val.r
    self.g = val.g
    self.b = val.b
    self.a = val.a
  end
  self
end

#to_rgb(add_hash = true) ⇒ Object



121
122
123
# File 'lib/iron/web/color.rb', line 121

def to_rgb(add_hash = true)
  (add_hash ? '#' : '') + to_hex(r) + to_hex(g) + to_hex(b)
end

#to_rgba(add_hash = true) ⇒ Object



125
126
127
# File 'lib/iron/web/color.rb', line 125

def to_rgba(add_hash = true)
  to_rgb(add_hash) + to_hex(a)
end

#to_s(add_hash = true) ⇒ Object



117
118
119
# File 'lib/iron/web/color.rb', line 117

def to_s(add_hash = true)
  trans? ? to_rgba(add_hash) : to_rgb(add_hash)
end

#trans?Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/iron/web/color.rb', line 133

def trans?
  @a != 255
end