Class Sass::Script::Color
In: lib/sass/script/color.rb
Parent: Literal

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.

Methods

alpha   alpha?   blue   div   eq   green   hsl   hue   inspect   lightness   minus   mod   new   plus   red   rgb   saturation   times   to_s   to_sass   value   with  

Included Modules

Haml::Util

Constants

HTML4_COLORS = map_vals({ 'black' => 0x000000, 'silver' => 0xc0c0c0, 'gray' => 0x808080, 'white' => 0xffffff, 'maroon' => 0x800000, 'red' => 0xff0000, 'purple' => 0x800080, 'fuchsia' => 0xff00ff, 'green' => 0x008000, 'lime' => 0x00ff00, 'olive' => 0x808000, 'yellow' => 0xffff00, 'navy' => 0x000080, 'blue' => 0x0000ff, 'teal' => 0x008080, 'aqua' => 0x00ffff   A hash from color names to `[red, green, blue]` value arrays.
HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}   A hash from `[red, green, blue]` value arrays to color names.

Public Class methods

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

[Source]

     # 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 be between 0 and 1")
118:       end
119:     end

Public Instance methods

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

@return [Fixnum]

[Source]

     # File lib/sass/script/color.rb, line 173
173:     def alpha
174:       @attrs[:alpha]
175:     end

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

@return [Boolean]

[Source]

     # File lib/sass/script/color.rb, line 181
181:     def alpha?
182:       alpha < 1
183:     end

The blue component of the color.

@return [Fixnum]

[Source]

     # File lib/sass/script/color.rb, line 140
140:     def blue
141:       hsl_to_rgb!
142:       @attrs[:blue]
143:     end

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

[Source]

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

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

[Source]

     # File lib/sass/script/color.rb, line 220
220:     def eq(other)
221:       Sass::Script::Bool.new(
222:         other.is_a?(Color) && rgb == other.rgb && alpha == other.alpha)
223:     end

The green component of the color.

@return [Fixnum]

[Source]

     # File lib/sass/script/color.rb, line 132
132:     def green
133:       hsl_to_rgb!
134:       @attrs[:green]
135:     end

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

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

  hue, saturation, and lightness values (respectively) of the color

[Source]

     # File lib/sass/script/color.rb, line 209
209:     def hsl
210:       [hue, saturation, lightness].freeze
211:     end

The hue component of the color.

@return [Numeric]

[Source]

     # File lib/sass/script/color.rb, line 148
148:     def hue
149:       rgb_to_hsl!
150:       @attrs[:hue]
151:     end

Returns a string representation of the color.

@return [String] The hex value

[Source]

     # File lib/sass/script/color.rb, line 391
391:     def inspect
392:       alpha? ? rgba_str : hex_str
393:     end

The lightness component of the color.

@return [Numeric]

[Source]

     # File lib/sass/script/color.rb, line 164
164:     def lightness
165:       rgb_to_hsl!
166:       @attrs[:lightness]
167:     end

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

[Source]

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

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

[Source]

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

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

[Source]

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

The red component of the color.

@return [Fixnum]

[Source]

     # File lib/sass/script/color.rb, line 124
124:     def red
125:       hsl_to_rgb!
126:       @attrs[:red]
127:     end

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

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

  values (respectively) of the color

[Source]

     # File lib/sass/script/color.rb, line 201
201:     def rgb
202:       [red, green, blue].freeze
203:     end

The saturation component of the color.

@return [Numeric]

[Source]

     # File lib/sass/script/color.rb, line 156
156:     def saturation
157:       rgb_to_hsl!
158:       @attrs[:saturation]
159:     end

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

[Source]

     # File lib/sass/script/color.rb, line 324
324:     def times(other)
325:       if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
326:         piecewise(other, :*)
327:       else
328:         raise NoMethodError.new(nil, :times)
329:       end
330:     end

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

[Source]

     # File lib/sass/script/color.rb, line 380
380:     def to_s(opts = {})
381:       return rgba_str if alpha?
382:       return smallest if options[:style] == :compressed
383:       return HTML4_COLORS_REVERSE[rgb] if HTML4_COLORS_REVERSE[rgb]
384:       hex_str
385:     end
to_sass(opts = {})

Alias for to_s

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

[Source]

     # File lib/sass/script/color.rb, line 187
187:     def value
188:       Haml::Util.haml_warn "DEPRECATION WARNING:\nThe Sass::Script::Color #value attribute is deprecated and will be\nremoved in version 3.2. Use the #rgb attribute instead.\n"
189:       rgb
190:     end

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

[Source]

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

[Validate]