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.
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. |
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
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 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
# 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
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/color.rb, line 209 209: def hsl 210: [hue, saturation, lightness].freeze 211: 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
# 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
# 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
# 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 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
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 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
# 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
@deprecated This will be removed in version 3.2. @see rgb
# 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
# 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