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.
A hash from color names to `[red, green, blue]` value arrays.
A hash from `[red, green, blue, alpha]` value arrays to color names.
Create a new color from a valid CSS hex string.
The leading hash is optional.
@return [Color]
# File lib/sass/script/value/color.rb, line 277 def self.from_hex(hex_string, alpha = nil) unless hex_string =~ /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/ || hex_string =~ /^#?([0-9a-f])([0-9a-f])([0-9a-f])$/ raise ArgumentError.new("#{hex_string.inspect} is not a valid hex color.") end red = $1.ljust(2, $1).to_i(16) green = $2.ljust(2, $2).to_i(16) blue = $3.ljust(2, $3).to_i(16) hex_string = '##{hex_string}' unless hex_string[0] == ## attrs = {:red => red, :green => green, :blue => blue, :representation => hex_string} attrs[:alpha] = alpha if alpha new(attrs) end
@private
Convert a ruby integer to a rgba components @param color [Fixnum] @return [Array<Fixnum>] Array of 4 numbers representing r,g,b and alpha
# File lib/sass/script/value/color.rb, line 22 def self.int_to_rgba(color) rgba = (0..3).map {|n| color >> (n << 3) & 0xff}.reverse rgba[-1] = rgba[-1] / 255.0 rgba end
Constructs an RGB or HSL color object, optionally with an alpha channel.
RGB values are clipped within 0 and 255. Saturation and lightness values are clipped within 0 and 100. The alpha value is clipped within 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, and a `:representation` key indicating the original representation of the color that the user wrote in their stylesheet. @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, [representation])
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 @param representation [String] The original representation of the color that the user wrote in their stylesheet. @raise [ArgumentError] if not enough attributes are specified
# File lib/sass/script/value/color.rb, line 227 def initialize(attrs, representation = nil, allow_both_rgb_and_hsl = false) super(nil) if attrs.is_a?(Array) unless (3..4).include?(attrs.size) raise ArgumentError.new("Color.new(array) expects a three- or four-element array") end red, green, blue = attrs[0...3].map {|c| c.to_i} @attrs = {:red => red, :green => green, :blue => blue} @attrs[:alpha] = attrs[3] ? attrs[3].to_f : 1 @representation = representation else attrs = attrs.reject {|k, v| v.nil?} hsl = [:hue, :saturation, :lightness] & attrs.keys rgb = [:red, :green, :blue] & attrs.keys if !allow_both_rgb_and_hsl && !hsl.empty? && !rgb.empty? raise ArgumentError.new("Color.new(hash) may not have both HSL and RGB keys specified") elsif hsl.empty? && rgb.empty? raise ArgumentError.new("Color.new(hash) must have either HSL or RGB keys specified") elsif !hsl.empty? && hsl.size != 3 raise ArgumentError.new("Color.new(hash) must have all three HSL values specified") elsif !rgb.empty? && rgb.size != 3 raise ArgumentError.new("Color.new(hash) must have all three RGB values specified") end @attrs = attrs @attrs[:hue] = 360 if @attrs[:hue] @attrs[:alpha] ||= 1 @representation = @attrs.delete(:representation) end [:red, :green, :blue].each do |k| next if @attrs[k].nil? @attrs[k] = Sass::Util.restrict(@attrs[k].to_i, 0..255) end [:saturation, :lightness].each do |k| next if @attrs[k].nil? @attrs[k] = Sass::Util.restrict(@attrs[k], 0..100) end @attrs[:alpha] = Sass::Util.restrict(@attrs[:alpha], 0..1) end
The alpha channel (opacity) of the color. This is 1 unless otherwise defined.
@return [Fixnum]
# File lib/sass/script/value/color.rb, line 344 def alpha @attrs[:alpha].to_f end
Returns whether this color object is translucent; that is, whether the alpha channel is non-1.
@return [Boolean]
# File lib/sass/script/value/color.rb, line 352 def alpha? alpha < 1 end
The blue component of the color.
@return [Fixnum]
# File lib/sass/script/value/color.rb, line 311 def blue hsl_to_rgb! @attrs[:blue] 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.
{Value} : See {Value::Base#div}.
@param other [Value] 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/value/color.rb, line 526 def div(other) if other.is_a?(Sass::Script::Value::Number) || other.is_a?(Sass::Script::Value::Color) piecewise(other, :/) else super end end
The SassScript `==` operation. **Note that this returns a {Sass::Script::Value::Bool} object, not a Ruby boolean**.
@param other [Value] The right-hand side of the operator @return [Bool] True if this value is the same as the other,
false otherwise
# File lib/sass/script/value/color.rb, line 395 def eq(other) Sass::Script::Value::Bool.new( other.is_a?(Color) && rgb == other.rgb && alpha == other.alpha) end
The green component of the color.
@return [Fixnum]
# File lib/sass/script/value/color.rb, line 303 def green hsl_to_rgb! @attrs[:green] end
# File lib/sass/script/value/color.rb, line 400 def hash [rgb, alpha].hash 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
# File lib/sass/script/value/color.rb, line 376 def hsl [hue, saturation, lightness].freeze end
Returns the hue, saturation, lightness, and alpha components of the color.
@return [Array<Fixnum>] A frozen four-element array of the hue,
saturation, lightness, and alpha values (respectively) of the color
# File lib/sass/script/value/color.rb, line 384 def hsla [hue, saturation, lightness].freeze end
The hue component of the color.
@return [Numeric]
# File lib/sass/script/value/color.rb, line 319 def hue rgb_to_hsl! @attrs[:hue] end
Returns a string representation of the color.
@return [String] The hex value
# File lib/sass/script/value/color.rb, line 572 def inspect alpha? ? rgba_str : hex_str end
The lightness component of the color.
@return [Numeric]
# File lib/sass/script/value/color.rb, line 335 def lightness rgb_to_hsl! @attrs[:lightness] 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.
{Value} : See {Value::Base#minus}.
@param other [Value] 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/value/color.rb, line 483 def minus(other) if other.is_a?(Sass::Script::Value::Number) || other.is_a?(Sass::Script::Value::Color) piecewise(other, :-) else super end 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
# File lib/sass/script/value/color.rb, line 547 def mod(other) if other.is_a?(Sass::Script::Value::Number) || other.is_a?(Sass::Script::Value::Color) piecewise(other, :%) else raise NoMethodError.new(nil, :mod) end end
Returns the color’s name, if it has one.
@return [String, nil]
# File lib/sass/script/value/color.rb, line 579 def name COLOR_NAMES_REVERSE[rgba] 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.
{Value} : See {Value::Base#plus}.
@param other [Value] 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/value/color.rb, line 460 def plus(other) if other.is_a?(Sass::Script::Value::Number) || other.is_a?(Sass::Script::Value::Color) piecewise(other, :+) else super end end
The red component of the color.
@return [Fixnum]
# File lib/sass/script/value/color.rb, line 295 def red hsl_to_rgb! @attrs[:red] 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
# File lib/sass/script/value/color.rb, line 360 def rgb [red, green, blue].freeze end
Returns the red, green, blue, and alpha components of the color.
@return [Array<Fixnum>] A frozen four-element array of the red, green,
blue, and alpha values (respectively) of the color
# File lib/sass/script/value/color.rb, line 368 def rgba [red, green, blue, alpha].freeze end
The saturation component of the color.
@return [Numeric]
# File lib/sass/script/value/color.rb, line 327 def saturation rgb_to_hsl! @attrs[:saturation] 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
# File lib/sass/script/value/color.rb, line 503 def times(other) if other.is_a?(Sass::Script::Value::Number) || other.is_a?(Sass::Script::Value::Color) piecewise(other, :*) else raise NoMethodError.new(nil, :times) end 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
# File lib/sass/script/value/color.rb, line 561 def to_s(opts = {}) return smallest if options[:style] == :compressed return representation if representation return name if name alpha? ? rgba_str : hex_str 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
# File lib/sass/script/value/color.rb, line 423 def with(attrs) attrs = attrs.reject {|k, v| v.nil?} hsl = !([:hue, :saturation, :lightness] & attrs.keys).empty? rgb = !([:red, :green, :blue] & attrs.keys).empty? if hsl && rgb raise ArgumentError.new("Cannot specify HSL and RGB values for a color at the same time") end if hsl [:hue, :saturation, :lightness].each {|k| attrs[k] ||= send(k)} elsif rgb [:red, :green, :blue].each {|k| attrs[k] ||= send(k)} else # If we're just changing the alpha channel, # keep all the HSL/RGB stuff we've calculated attrs = @attrs.merge(attrs) end attrs[:alpha] ||= alpha Color.new(attrs, nil, :allow_both_rgb_and_hsl) end
Generated with the Darkfish Rdoc Generator 2.