Included Modules

Class Index [+]

Quicksearch

Sass::Script::Color

A SassScript object representing a CSS color.

A color may be represented internally as RGBA, HSLA, or both. It’s originally represented as whatever its input is; if it’s created with RGB values, it’s represented as RGBA, and if it’s created with HSL values, it’s represented as HSLA. Once a property is accessed that requires the other representation — for example, {#red} for an HSL color — that component is calculated and cached.

The alpha channel of a color is independent of its RGB or HSL representation. It’s always stored, as 1 if nothing else is specified. If only the alpha channel is modified using {#with}, the cached RGB and HSL values are retained.

Constants

HTML4_COLORS

A hash from color names to `[red, green, blue]` value arrays.

HTML4_COLORS_REVERSE

A hash from `[red, green, blue]` value arrays to color names.

Public Class Methods

new(attrs, allow_both_rgb_and_hsl = false) click to toggle source

Constructs an RGB or HSL color object, optionally with an alpha channel.

The RGB values must be between 0 and 255. The saturation and lightness values must be between 0 and 100. The alpha value must be between 0 and 1.

@raise [Sass::SyntaxError] if any color value isn’t in the specified range

@overload initialize(attrs)

  The attributes are specified as a hash.
  This hash must contain either `:hue`, `:saturation`, and `:value` keys,
  or `:red`, `:green`, and `:blue` keys.
  It cannot contain both HSL and RGB keys.
  It may also optionally contain an `:alpha` key.

  @param attrs [{Symbol => Numeric}] A hash of color attributes to values
  @raise [ArgumentError] if not enough attributes are specified,
    or both RGB and HSL attributes are specified

@overload initialize(rgba)

  The attributes are specified as an array.
  This overload only supports RGB or RGBA colors.

  @param rgba [Array<Numeric>] A three- or four-element array
    of the red, green, blue, and optionally alpha values (respectively)
    of the color
  @raise [ArgumentError] if not enough attributes are specified
     # File lib/sass/script/color.rb, line 71
 71:     def initialize(attrs, allow_both_rgb_and_hsl = false)
 72:       super(nil)
 73: 
 74:       if attrs.is_a?(Array)
 75:         unless (3..4).include?(attrs.size)
 76:           raise ArgumentError.new("Color.new(array) expects a three- or four-element array")
 77:         end
 78: 
 79:         red, green, blue = attrs[0...3].map {|c| c.to_i}
 80:         @attrs = {:red => red, :green => green, :blue => blue}
 81:         @attrs[:alpha] = attrs[3] ? attrs[3].to_f : 1
 82:       else
 83:         attrs = attrs.reject {|k, v| v.nil?}
 84:         hsl = [:hue, :saturation, :lightness] & attrs.keys
 85:         rgb = [:red, :green, :blue] & attrs.keys
 86:         if !allow_both_rgb_and_hsl && !hsl.empty? && !rgb.empty?
 87:           raise ArgumentError.new("Color.new(hash) may not have both HSL and RGB keys specified")
 88:         elsif hsl.empty? && rgb.empty?
 89:           raise ArgumentError.new("Color.new(hash) must have either HSL or RGB keys specified")
 90:         elsif !hsl.empty? && hsl.size != 3
 91:           raise ArgumentError.new("Color.new(hash) must have all three HSL values specified")
 92:         elsif !rgb.empty? && rgb.size != 3
 93:           raise ArgumentError.new("Color.new(hash) must have all three RGB values specified")
 94:         end
 95: 
 96:         @attrs = attrs
 97:         @attrs[:hue] = 360 if @attrs[:hue]
 98:         @attrs[:alpha] ||= 1
 99:       end
100: 
101:       [:red, :green, :blue].each do |k|
102:         next if @attrs[k].nil?
103:         @attrs[k] = @attrs[k].to_i
104:         next if (0..255).include?(@attrs[k])
105:         raise Sass::SyntaxError.new("#{k.to_s.capitalize} value must be between 0 and 255")
106:       end
107: 
108:       [:saturation, :lightness].each do |k|
109:         next if @attrs[k].nil?
110:         @attrs[k] = 0 if @attrs[k] < 0.00001 && @attrs[k] > 0.00001
111:         @attrs[k] = 100 if @attrs[k] - 100 < 0.00001 && @attrs[k] - 100 > 0.00001
112:         next if (0..100).include?(@attrs[k])
113:         raise Sass::SyntaxError.new("#{k.to_s.capitalize} must be between 0 and 100")
114:       end
115: 
116:       unless (0..1).include?(@attrs[:alpha])
117:         raise Sass::SyntaxError.new("Alpha channel must between 0 and 1")
118:       end
119:     end

Public Instance Methods

alpha() click to toggle source

The alpha channel (opacity) of the color. This is 1 unless otherwise defined.

@return [Fixnum]

     # File lib/sass/script/color.rb, line 173
173:     def alpha
174:       @attrs[:alpha]
175:     end
alpha?() click to toggle source

Returns whether this color object is translucent; that is, whether the alpha channel is non-1.

@return [Boolean]

     # File lib/sass/script/color.rb, line 181
181:     def alpha?
182:       alpha < 1
183:     end
blue() click to toggle source

The blue component of the color.

@return [Fixnum]

     # File lib/sass/script/color.rb, line 140
140:     def blue
141:       hsl_to_rgb!
142:       @attrs[:blue]
143:     end
div(other) click to toggle source

The SassScript `/` operation. Its functionality depends on the type of its argument:

{Number} : Divides each of the RGB color channels by the number.

{Color} : Divides each of this color’s RGB color channels by the other color’s.

{Literal} : See {Literal#div}.

@param other [Literal] The right-hand side of the operator @return [Color] The resulting color @raise [Sass::SyntaxError] if `other` is a number with units

     # File lib/sass/script/color.rb, line 346
346:     def div(other)
347:       if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
348:         piecewise(other, :/)
349:       else
350:         super
351:       end
352:     end
eq(other) click to toggle source

The SassScript `==` operation. **Note that this returns a {Sass::Script::Bool} object, not a Ruby boolean**.

@param other [Literal] The right-hand side of the operator @return [Bool] True if this literal is the same as the other,

  false otherwise
     # File lib/sass/script/color.rb, line 219
219:     def eq(other)
220:       Sass::Script::Bool.new(
221:         other.is_a?(Color) && rgb == other.rgb && alpha == other.alpha)
222:     end
green() click to toggle source

The green component of the color.

@return [Fixnum]

     # File lib/sass/script/color.rb, line 132
132:     def green
133:       hsl_to_rgb!
134:       @attrs[:green]
135:     end
hsl() click to toggle source

Returns the hue, saturation, and lightness components of the color.

@return [Array] A frozen three-element array of the

  hue, saturation, and lightness values (respectively) of the color
     # File lib/sass/script/color.rb, line 208
208:     def hsl
209:       [hue, saturation, lightness].freeze
210:     end
hue() click to toggle source

The hue component of the color.

@return [Numeric]

     # File lib/sass/script/color.rb, line 148
148:     def hue
149:       rgb_to_hsl!
150:       @attrs[:hue]
151:     end
inspect() click to toggle source

Returns a string representation of the color.

@return [String] The hex value

     # File lib/sass/script/color.rb, line 390
390:     def inspect
391:       alpha? ? rgba_str : hex_str
392:     end
lightness() click to toggle source

The lightness component of the color.

@return [Numeric]

     # File lib/sass/script/color.rb, line 164
164:     def lightness
165:       rgb_to_hsl!
166:       @attrs[:lightness]
167:     end
minus(other) click to toggle source

The SassScript `-` operation. Its functionality depends on the type of its argument:

{Number} : Subtracts the number from each of the RGB color channels.

{Color} : Subtracts each of the other color’s RGB color channels from this color’s.

{Literal} : See {Literal#minus}.

@param other [Literal] The right-hand side of the operator @return [Color] The resulting color @raise [Sass::SyntaxError] if `other` is a number with units

     # File lib/sass/script/color.rb, line 303
303:     def minus(other)
304:       if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
305:         piecewise(other, :-)
306:       else
307:         super
308:       end
309:     end
mod(other) click to toggle source

The SassScript `%` operation. Its functionality depends on the type of its argument:

{Number} : Takes each of the RGB color channels module the number.

{Color} : Takes each of this color’s RGB color channels modulo the other color’s.

@param other [Number, Color] The right-hand side of the operator @return [Color] The resulting color @raise [Sass::SyntaxError] if `other` is a number with units

     # File lib/sass/script/color.rb, line 366
366:     def mod(other)
367:       if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
368:         piecewise(other, :%)
369:       else
370:         raise NoMethodError.new(nil, :mod)
371:       end
372:     end
plus(other) click to toggle source

The SassScript `+` operation. Its functionality depends on the type of its argument:

{Number} : Adds the number to each of the RGB color channels.

{Color} : Adds each of the RGB color channels together.

{Literal} : See {Literal#plus}.

@param other [Literal] The right-hand side of the operator @return [Color] The resulting color @raise [Sass::SyntaxError] if `other` is a number with units

     # File lib/sass/script/color.rb, line 280
280:     def plus(other)
281:       if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
282:         piecewise(other, :+)
283:       else
284:         super
285:       end
286:     end
red() click to toggle source

The red component of the color.

@return [Fixnum]

     # File lib/sass/script/color.rb, line 124
124:     def red
125:       hsl_to_rgb!
126:       @attrs[:red]
127:     end
rgb() click to toggle source

Returns the red, green, and blue components of the color.

@return [Array] A frozen three-element array of the red, green, and blue

  values (respectively) of the color
     # File lib/sass/script/color.rb, line 200
200:     def rgb
201:       [red, green, blue].freeze
202:     end
saturation() click to toggle source

The saturation component of the color.

@return [Numeric]

     # File lib/sass/script/color.rb, line 156
156:     def saturation
157:       rgb_to_hsl!
158:       @attrs[:saturation]
159:     end
times(other) click to toggle source

The SassScript `*` operation. Its functionality depends on the type of its argument:

{Number} : Multiplies the number by each of the RGB color channels.

{Color} : Multiplies each of the RGB color channels together.

@param other [Number, Color] The right-hand side of the operator @return [Color] The resulting color @raise [Sass::SyntaxError] if `other` is a number with units

     # File lib/sass/script/color.rb, line 323
323:     def times(other)
324:       if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
325:         piecewise(other, :*)
326:       else
327:         raise NoMethodError.new(nil, :times)
328:       end
329:     end
to_s(opts = {}) click to toggle source

Returns a string representation of the color. This is usually the color’s hex value, but if the color has a name that’s used instead.

@return [String] The string representation

     # File lib/sass/script/color.rb, line 379
379:     def to_s(opts = {})
380:       return rgba_str if alpha?
381:       return smallest if options[:style] == :compressed
382:       return HTML4_COLORS_REVERSE[rgb] if HTML4_COLORS_REVERSE[rgb]
383:       hex_str
384:     end
Also aliased as: to_sass
to_sass(opts = {}) click to toggle source
Alias for: to_s
value() click to toggle source

@deprecated This will be removed in version 3.2. @see #

     # File lib/sass/script/color.rb, line 187
187:     def value
188:       Haml::Util.haml_warn DEPRECATION WARNING:The Sass::Script::Color #value attribute is deprecated and will beremoved in version 3.2. Use the #rgb attribute instead.
189:       rgb
190:     end
with(attrs) click to toggle source

Returns a copy of this color with one or more channels changed. RGB or HSL colors may be changed, but not both at once.

For example:

    Color.new([10, 20, 30]).with(:blue => 40)
      #=> rgb(10, 40, 30)
    Color.new([126, 126, 126]).with(:red => 0, :green => 255)
      #=> rgb(0, 255, 126)
    Color.new([255, 0, 127]).with(:saturation => 60)
      #=> rgb(204, 51, 127)
    Color.new([1, 2, 3]).with(:alpha => 0.4)
      #=> rgba(1, 2, 3, 0.4)

@param attrs [{Symbol => Numeric}]

  A map of channel names (`:red`, `:green`, `:blue`,
  `:hue`, `:saturation`, `:lightness`, or `:alpha`) to values

@return [Color] The new Color object @raise [ArgumentError] if both RGB and HSL keys are specified

     # File lib/sass/script/color.rb, line 243
243:     def with(attrs)
244:       attrs = attrs.reject {|k, v| v.nil?}
245:       hsl = !([:hue, :saturation, :lightness] & attrs.keys).empty?
246:       rgb = !([:red, :green, :blue] & attrs.keys).empty?
247:       if hsl && rgb
248:         raise ArgumentError.new("Color#with may not have both HSL and RGB keys specified")
249:       end
250: 
251:       if hsl
252:         [:hue, :saturation, :lightness].each {|k| attrs[k] ||= send(k)}
253:       elsif rgb
254:         [:red, :green, :blue].each {|k| attrs[k] ||= send(k)}
255:       else
256:         # If we're just changing the alpha channel,
257:         # keep all the HSL/RGB stuff we've calculated
258:         attrs = @attrs.merge(attrs)
259:       end
260:       attrs[:alpha] ||= alpha
261: 
262:       Color.new(attrs, :allow_both_rgb_and_hsl)
263:     end

Private Instance Methods

hex_str() click to toggle source
     # File lib/sass/script/color.rb, line 407
407:     def hex_str
408:       red, green, blue = rgb.map { |num| num.to_s(16).rjust(2, '0') }
409:       "##{red}#{green}#{blue}"
410:     end
hsl_to_rgb!() click to toggle source
     # File lib/sass/script/color.rb, line 431
431:     def hsl_to_rgb!
432:       return if @attrs[:red] && @attrs[:blue] && @attrs[:green]
433: 
434:       h = @attrs[:hue] / 360.0
435:       s = @attrs[:saturation] / 100.0
436:       l = @attrs[:lightness] / 100.0
437: 
438:       # Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color.
439:       m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s
440:       m1 = l * 2 - m2
441:       @attrs[:red], @attrs[:green], @attrs[:blue] = [
442:         hue_to_rgb(m1, m2, h + 1.0/3),
443:         hue_to_rgb(m1, m2, h),
444:         hue_to_rgb(m1, m2, h - 1.0/3)
445:       ].map {|c| (c * 0xff).round}
446:     end
hue_to_rgb(m1, m2, h) click to toggle source
     # File lib/sass/script/color.rb, line 448
448:     def hue_to_rgb(m1, m2, h)
449:       h += 1 if h < 0
450:       h -= 1 if h > 1
451:       return m1 + (m2 - m1) * h * 6 if h * 6 < 1
452:       return m2 if h * 2 < 1
453:       return m1 + (m2 - m1) * (2.0/3 - h) * 6 if h * 3 < 2
454:       return m1
455:     end
piecewise(other, operation) click to toggle source
     # File lib/sass/script/color.rb, line 412
412:     def piecewise(other, operation)
413:       other_num = other.is_a? Number
414:       if other_num && !other.unitless?
415:         raise Sass::SyntaxError.new("Cannot add a number with units (#{other}) to a color (#{self}).") 
416:       end
417: 
418:       result = []
419:       for i in (0...3)
420:         res = rgb[i].send(operation, other_num ? other.value : other.rgb[i])
421:         result[i] = [ [res, 255].min, 0 ].max
422:       end
423: 
424:       if !other_num && other.alpha != alpha
425:         raise Sass::SyntaxError.new("Alpha channels must be equal: #{self} #{operation} #{other}")
426:       end
427: 
428:       with(:red => result[0], :green => result[1], :blue => result[2])
429:     end
rgb_to_hsl!() click to toggle source
     # File lib/sass/script/color.rb, line 457
457:     def rgb_to_hsl!
458:       return if @attrs[:hue] && @attrs[:saturation] && @attrs[:lightness]
459:       r, g, b = [:red, :green, :blue].map {|k| @attrs[k] / 255.0}
460: 
461:       # Algorithm from http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
462:       max = [r, g, b].max
463:       min = [r, g, b].min
464:       d = max - min
465: 
466:       h =
467:         case max
468:         when min; 0
469:         when r; 60 * (g-b)/d
470:         when g; 60 * (b-r)/d + 120
471:         when b; 60 * (r-g)/d + 240
472:         end
473: 
474:       l = (max + min)/2.0
475: 
476:       s =
477:         if max == min
478:           0
479:         elsif l < 0.5
480:           d/(2*l)
481:         else
482:           d/(2 - 2*l)
483:         end
484: 
485:       @attrs[:hue] = h % 360
486:       @attrs[:saturation] = s * 100
487:       @attrs[:lightness] = l * 100
488:     end
rgba_str() click to toggle source
     # File lib/sass/script/color.rb, line 403
403:     def rgba_str
404:       "rgba(#{rgb.join(', ')}, #{alpha % 1 == 0.0 ? alpha.to_i : alpha})"
405:     end
smallest() click to toggle source
     # File lib/sass/script/color.rb, line 396
396:     def smallest
397:       small_hex_str = hex_str.gsub(/^#(.)\11((.)\22((.)\33$$/, '#\1\2\3')
398:       return small_hex_str unless (color = HTML4_COLORS_REVERSE[rgb]) &&
399:         color.size <= small_hex_str.size
400:       return color
401:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.