Class: Term::ANSIColor::HSLTriple

Inherits:
Object
  • Object
show all
Defined in:
lib/term/ansicolor/hsl_triple.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hue, saturation, lightness) ⇒ HSLTriple

Returns a new instance of HSLTriple.



73
74
75
76
77
# File 'lib/term/ansicolor/hsl_triple.rb', line 73

def initialize(hue, saturation, lightness)
  @hue        = Float(hue) % 360
  @saturation = Float(saturation).clamp(0, 100)
  @lightness  = Float(lightness).clamp(0, 100)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



160
161
162
163
164
165
166
# File 'lib/term/ansicolor/hsl_triple.rb', line 160

def method_missing(name, *args, &block)
  if Term::ANSIColor::RGBTriple.method_defined?(name)
    to_rgb_triple.send(name, *args, &block)
  else
    super
  end
end

Instance Attribute Details

#hueObject (readonly)

Returns the value of attribute hue.



79
80
81
# File 'lib/term/ansicolor/hsl_triple.rb', line 79

def hue
  @hue
end

#lightnessObject (readonly)

Returns the value of attribute lightness.



83
84
85
# File 'lib/term/ansicolor/hsl_triple.rb', line 83

def lightness
  @lightness
end

#saturationObject (readonly)

Returns the value of attribute saturation.



81
82
83
# File 'lib/term/ansicolor/hsl_triple.rb', line 81

def saturation
  @saturation
end

Class Method Details

.[](thing) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/term/ansicolor/hsl_triple.rb', line 60

def self.[](thing)
  case
  when thing.respond_to?(:to_hsl_triple) then thing.to_hsl_triple
  when thing.respond_to?(:to_hash)       then from_hash(thing.to_hash)
  when thing.respond_to?(:to_str)
    thing = thing.to_str
    from_css(thing.to_str) ||
      Term::ANSIColor::RGBTriple.from_html(thing).full?(:to_hsl_triple) ||
      Term::ANSIColor::RGBTriple.from_css(thing).full?(:to_hsl_triple)
  else raise ArgumentError, "cannot convert #{thing.inspect} into #{self}"
  end
end

.from_css(css) ⇒ Object



45
46
47
48
49
50
# File 'lib/term/ansicolor/hsl_triple.rb', line 45

def self.from_css(css)
  case css
  when /\A\s*hsl\(\s*([^,\s]+)\s*,\s*([^%\s]+)\s*%\s*,\s*([^%\s]+)\s*%\s*\)\z/
    new(Float($1), Float($2), Float($3))
  end
end

.from_hash(options) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/term/ansicolor/hsl_triple.rb', line 52

def self.from_hash(options)
  new(
    options[:hue].to_f,
    options[:saturation].to_f,
    options[:lightness].to_f
  )
end

.from_rgb_triple(rgb) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/term/ansicolor/hsl_triple.rb', line 4

def self.from_rgb_triple(rgb)
  ps = [ rgb.red / 255.0, rgb.green / 255.0, rgb.blue / 255.0 ]
  p_min = ps.min
  p_max = ps.max
  p_red, p_green, p_blue = ps

  diff = p_max - p_min
  l = (p_max + p_min) / 2

  if diff.zero?
    h = s = 0.0
  else
    if l < 0.5
      s = diff / (p_max + p_min)
    else
      s = diff / (2 - p_max - p_min)
    end

    diff_r = ( ( ( p_max - p_red ) / 6 )   + ( diff / 2 ) ) / diff
    diff_g = ( ( ( p_max - p_green ) / 6 ) + ( diff / 2 ) ) / diff
    diff_b = ( ( ( p_max - p_blue ) / 6 )  + ( diff / 2 ) ) / diff

    h = case p_max
        when p_red
          diff_b - diff_g
        when p_green
          (1 / 3.0) + diff_r - diff_b
        when p_blue
          (2 / 3.0) + diff_g - diff_r
        end

    h < 0 and h += 1
    h > 1 and h -= 1
  end
  from_hash(
    hue:        360 * h,
    saturation: 100 * s,
    lightness:  100 * l
  )
end

Instance Method Details

#==(other) ⇒ Object



156
157
158
# File 'lib/term/ansicolor/hsl_triple.rb', line 156

def ==(other)
  to_rgb_triple == other.to_rgb_triple
end

#adjust_hue(degree) ⇒ Object



101
102
103
# File 'lib/term/ansicolor/hsl_triple.rb', line 101

def adjust_hue(degree)
  self.class.new(@hue + degree, @saturation, @lightness)
end

#complementObject



109
110
111
# File 'lib/term/ansicolor/hsl_triple.rb', line 109

def complement
  adjust_hue(180)
end

#cssObject



152
153
154
# File 'lib/term/ansicolor/hsl_triple.rb', line 152

def css
  "hsl(%s,%s%%,%s%%)" % [ @hue, @saturation, @lightness ]
end

#darken(percentage) ⇒ Object



89
90
91
# File 'lib/term/ansicolor/hsl_triple.rb', line 89

def darken(percentage)
  self.class.new(@hue, @saturation, @lightness - percentage)
end

#desaturate(percentage) ⇒ Object



97
98
99
# File 'lib/term/ansicolor/hsl_triple.rb', line 97

def desaturate(percentage)
  self.class.new(@hue, @saturation - percentage, @lightness)
end

#grayscaleObject



105
106
107
# File 'lib/term/ansicolor/hsl_triple.rb', line 105

def grayscale
  self.class.new(@hue, 0, @lightness)
end

#lighten(percentage) ⇒ Object



85
86
87
# File 'lib/term/ansicolor/hsl_triple.rb', line 85

def lighten(percentage)
  self.class.new(@hue, @saturation, @lightness + percentage)
end

#saturate(percentage) ⇒ Object



93
94
95
# File 'lib/term/ansicolor/hsl_triple.rb', line 93

def saturate(percentage)
  self.class.new(@hue, @saturation + percentage, @lightness)
end

#to_hsl_tripleObject



148
149
150
# File 'lib/term/ansicolor/hsl_triple.rb', line 148

def to_hsl_triple
  self
end

#to_rgb_tripleObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/term/ansicolor/hsl_triple.rb', line 123

def to_rgb_triple
  h = @hue        / 360.0
  s = @saturation / 100.0
  l = @lightness  / 100.0

  if s.zero?
    r = 255 * l
    g = 255 * l
    b = 255 * l
  else
     if l < 0.5
       y = l * (1 + s)
     else
       y = (l + s) - (s * l)
     end

     x = 2 * l - y

     r = 255 * hue2rgb(x, y, h + (1 / 3.0))
     g = 255 * hue2rgb(x, y, h)
     b = 255 * hue2rgb(x, y, h - (1 / 3.0))
  end
  Term::ANSIColor::RGBTriple.new(r.round, g.round, b.round)
end