class Color::HSL

An HSL colour object. Internally, the hue (#h), saturation (#s), and luminosity/lightness (#l) values are dealt with as fractional values in the range 0..1.

Public Class Methods

new(h = 0, s = 0, l = 0, radix1 = 360.0, radix2 = 100.0, &block) click to toggle source

Creates an HSL colour object from the standard values of degrees and percentages (e.g., 145 deg, 30%, 50%).

# File lib/color/hsl.rb, line 22
def initialize(h = 0, s = 0, l = 0, radix1 = 360.0, radix2 = 100.0, &block) # :yields self:
  @h = Color.normalize(h / radix1)
  @s = Color.normalize(s / radix2)
  @l = Color.normalize(l / radix2)
  block.call if block
end

Public Instance Methods

brightness() click to toggle source

Returns the luminosity (#l) of the colour.

# File lib/color/hsl.rb, line 97
def brightness
  @l
end
coerce(other) click to toggle source

Coerces the other Color object into HSL.

# File lib/color/hsl.rb, line 16
def coerce(other)
  other.to_hsl
end
css_hsl() click to toggle source

Present the colour as an HSL HTML/CSS colour string (e.g., “hsl(180, 25%, 35%)”).

# File lib/color/hsl.rb, line 50
def css_hsl
  "hsl(%3.2f, %3.2f%%, %3.2f%%)" % [ hue, saturation, luminosity ]
end
css_hsla() click to toggle source

Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g., “hsla(180, 25%, 35%, 1)”).

# File lib/color/hsl.rb, line 56
def css_hsla
  "hsla(%3.2f, %3.2f%%, %3.2f%%, %3.2f)" % [ hue, saturation, luminosity, 1 ]
end
css_rgb() click to toggle source

Present the colour as an RGB HTML/CSS colour string (e.g., “rgb(0%, 50%, 100%)”). Note that this will perform a to_rgb operation using the default conversion formula.

# File lib/color/hsl.rb, line 37
def css_rgb
  to_rgb.css_rgb
end
css_rgba() click to toggle source

Present the colour as an RGBA (with alpha) HTML/CSS colour string (e.g., “rgb(0%, 50%, 100%, 1)”). Note that this will perform a to_rgb operation using the default conversion formula.

# File lib/color/hsl.rb, line 44
def css_rgba
  to_rgb.css_rgba
end
from_fraction(h = 0.0, s = 0.0, l = 0.0, &block) click to toggle source

Creates an HSL colour object from fractional values 0..1.

# File lib/color/hsl.rb, line 10
def from_fraction(h = 0.0, s = 0.0, l = 0.0, &block)
  new(h, s, l, 1.0, 1.0, &block)
end
h() click to toggle source

Returns the hue of the colour in the range 0.0 .. 1.0.

# File lib/color/hsl.rb, line 110
def h
  @h
end
h=(hh) click to toggle source

Sets the hue of the colour in the range 0.0 .. 1.0.

# File lib/color/hsl.rb, line 124
def h=(hh)
  @h = Color.normalize(hh)
end
html() click to toggle source

Present the colour as an HTML/CSS colour string.

# File lib/color/hsl.rb, line 30
def html
  to_rgb.html
end
hue() click to toggle source

Returns the hue of the colour in degrees.

# File lib/color/hsl.rb, line 106
def hue
  @h * 360.0
end
hue=(hh) click to toggle source

Sets the hue of the colour in degrees. Colour is perceived as a wheel, so values should be set properly even with negative degree values.

# File lib/color/hsl.rb, line 115
def hue=(hh)
  hh = hh / 360.0

  hh += 1.0 if hh < 0.0
  hh -= 1.0 if hh > 1.0

  @h = Color.normalize(hh)
end
inspect() click to toggle source
# File lib/color/hsl.rb, line 167
def inspect
  "HSL [%.2f deg, %.2f%%, %.2f%%]" % [ hue, saturation, luminosity ]
end
l() click to toggle source

Returns the luminosity of the colour in the range 0.0 .. 1.0.

# File lib/color/hsl.rb, line 150
def l
  @l
end
l=(ll) click to toggle source

Sets the luminosity of the colour in the ragne 0.0 .. 1.0.

# File lib/color/hsl.rb, line 159
def l=(ll)
  @l = Color.normalize(ll)
end
lightness()
Alias for: luminosity
lightness=(ll)
Alias for: luminosity=
luminosity() click to toggle source

Returns the percentage of luminosity of the colour.

# File lib/color/hsl.rb, line 145
def luminosity
  @l * 100.0
end
Also aliased as: lightness
luminosity=(ll) click to toggle source

Sets the percentage of luminosity of the colour.

# File lib/color/hsl.rb, line 154
def luminosity=(ll)
  @l = Color.normalize(ll / 100.0)
end
Also aliased as: lightness=
mix_with(color, mix_percent = 0.5) click to toggle source

Mix the mask colour (which will be converted to an HSL colour) with the current colour at the stated mix percentage as a decimal value.

NOTE

This differs from Color::RGB#mix_with.

# File lib/color/hsl.rb, line 175
def mix_with(color, mix_percent = 0.5)
  v = to_a.zip(coerce(color).to_a).map { |(x, y)|
    ((y - x) * mix_percent) + x
  }
  self.class.from_fraction(*v)
end
s() click to toggle source

Returns the saturation of the colour in the range 0.0 .. 1.0.

# File lib/color/hsl.rb, line 132
def s
  @s
end
s=(ss) click to toggle source

Sets the saturation of the colour in the ragne 0.0 .. 1.0.

# File lib/color/hsl.rb, line 140
def s=(ss)
  @s = Color.normalize(ss)
end
saturation() click to toggle source

Returns the percentage of saturation of the colour.

# File lib/color/hsl.rb, line 128
def saturation
  @s * 100.0
end
saturation=(ss) click to toggle source

Sets the percentage of saturation of the colour.

# File lib/color/hsl.rb, line 136
def saturation=(ss)
  @s = Color.normalize(ss / 100.0)
end
to_a() click to toggle source
# File lib/color/hsl.rb, line 182
def to_a
  [ h, s, l ]
end
to_cmyk() click to toggle source

Converts to RGB then CMYK.

# File lib/color/hsl.rb, line 92
def to_cmyk
  to_rgb.to_cmyk
end
to_grayscale()
Alias for: to_greyscale
to_greyscale() click to toggle source
# File lib/color/hsl.rb, line 100
def to_greyscale
  Color::GrayScale.from_fraction(@l)
end
Also aliased as: to_grayscale
to_hsl() click to toggle source
# File lib/color/hsl.rb, line 163
def to_hsl
  self
end
to_rgb(*) click to toggle source

Converting from HSL to RGB. As with all colour conversions, this is approximate at best. The code here is adapted from fvd and van Dam, originally found at [1] (implemented similarly at [2]).

This simplifies the calculations with the following assumptions:

  • Luminance values <= 0 always translate to Color::RGB::Black.

  • Luminance values >= 1 always translate to Color::RGB::White.

  • Saturation values <= 0 always translate to a shade of gray using luminance as a percentage of gray.

1

bobpowell.net/RGBHSB.aspx

2

support.microsoft.com/kb/29240

# File lib/color/hsl.rb, line 72
def to_rgb(*)
  if Color.near_zero_or_less?(l)
    Color::RGB::Black
  elsif Color.near_one_or_more?(l)
    Color::RGB::White
  elsif Color.near_zero?(s)
    Color::RGB.from_grayscale_fraction(l)
  else
    # Only needed for Ruby 1.8. For Ruby 1.9+, we can do:
    # Color::RGB.new(*compute_fvd_rgb, 1.0)
    Color::RGB.new(*(compute_fvd_rgb + [ 1.0 ]))
  end
end
to_yiq() click to toggle source

Converts to RGB then YIQ.

# File lib/color/hsl.rb, line 87
def to_yiq
  to_rgb.to_yiq
end

Private Instance Methods

compute_fvd_rgb() click to toggle source

This algorithm calculates based on a mixture of the saturation and luminance, and then takes the RGB values from the hue + 1/3, hue, and hue - 1/3 positions in a circular representation of colour divided into four parts (confusing, I know, but it's the way that it works). See hue_to_rgb for more information.

# File lib/color/hsl.rb, line 193
def compute_fvd_rgb
  t1, t2 = fvd_mix_sat_lum
  [ h + (1 / 3.0), h, h - (1 / 3.0) ].map { |v|
    hue_to_rgb(rotate_hue(v), t1, t2)
  }
end
fvd_mix_sat_lum() click to toggle source

Mix saturation and luminance for use in hue_to_rgb. The base value is different depending on whether luminance is <= 50% or > 50%.

# File lib/color/hsl.rb, line 202
def fvd_mix_sat_lum
  t = if Color.near_zero_or_less?(l - 0.5)
           l * (1.0 + s.to_f)
         else
           l + s - (l * s.to_f)
         end
  [ 2.0 * l - t, t ]
end
hue_to_rgb(h, t1, t2) click to toggle source

We calculate the interaction of the saturation/luminance mix (calculated earlier) based on the position of the hue in the circular colour space divided into quadrants. Our hue range is [0, 1), not [0, 360º).

  • The first quadrant covers the first 60º [0, 60º].

  • The second quadrant covers the next 120º (60º, 180º].

  • The third quadrant covers the next 60º (180º, 240º].

  • The fourth quadrant covers the final 120º (240º, 360º).

# File lib/color/hsl.rb, line 228
def hue_to_rgb(h, t1, t2)
  if Color.near_zero_or_less?((6.0 * h) - 1.0)
    t1 + ((t2 - t1) * h * 6.0)
  elsif Color.near_zero_or_less?((2.0 * h) - 1.0)
    t2
  elsif Color.near_zero_or_less?((3.0 * h) - 2.0)
    t1 + (t2 - t1) * ((2 / 3.0) - h) * 6.0
  else
    t1
  end
end
rotate_hue(h) click to toggle source

In HSL, hues are referenced as degrees in a colour circle. The flow itself is endless; therefore, we can rotate around. The only thing our implementation restricts is that you should not be > 1.0.

# File lib/color/hsl.rb, line 214
def rotate_hue(h)
  h += 1.0 if Color.near_zero_or_less?(h)
  h -= 1.0 if Color.near_one_or_more?(h)
  h
end