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

new(attrs, allow_both_rgb_and_hsl = false)

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

### Public Instance methods

alpha()

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

alpha?()

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

blue()

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

div(other)

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

eq(other)

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

green()

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

hsl()

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

hue()

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

inspect()

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

lightness()

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

minus(other)

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

mod(other)

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

plus(other)

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

red()

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

rgb()

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

saturation()

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

times(other)

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

to_s(opts = {})

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

value()

@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

with(attrs)

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]