Cover for src/colors/gradient.cr


Lines
39 / 39 (100.00%)

1
module Colors
2
  enum ValidColor
3
    Red
4
    Green
5
    Blue
6
  end
7

        
8
  class Gradient
9
    class SameColor < Exception
10
1
      def initialize(@color : ValidColor)
11
1
        super "gradient colors must be the different; got #{color} for both colors"
12
      end
13
    end
14

        
15
1
    property min
16
1
    property max
17
1
    getter low_color
18
1
    getter high_color
19
1
    property range : Range(Int64, Int64)
20
1
    property from
21
1
    property upto
22

        
23
    def initialize(
24
10
      @low_color : ValidColor = :red,
25
10
      @high_color : ValidColor = :green,
26
10
      @from : ColorValue | UInt8 = ColorValue.off,
27
10
      @upto : ColorValue | UInt8 = ColorValue.full,
28
10
      @max = 100_i64
29
    )
30
10
      check_colors
31
9
      @min = 0_i64
32
9
      @range = min...max
33
    end
34

        
35
    def initialize(
36
      range : Range(Int64, Int64),
37
1
      @low_color : ValidColor = :red,
38
1
      @high_color : ValidColor = :green,
39
1
      @from : ColorValue | UInt8 = ColorValue.off,
40
1
      @upto : ColorValue | UInt8 = ColorValue.full
41
    )
42
1
      check_colors
43
1
      @range = range
44
1
      @min = range.begin
45
1
      @max = range.end
46
    end
47

        
48
    def [](val) : Color
49
469
      value = val.to_f
50
469
      high_value = from + (((value - min) * (upto.to_u8 - from.to_u8)).to_f / (max - min))
51
469
      low_value = ColorValue.new(upto - high_value.to_u8 + from.to_u8)
52
      case @low_color
53
      when .red?
54
453
        case @high_color
55
        when .green?
56
449
          Color.new(
57
            red: ColorValue.new(low_value),
58
            green: ColorValue.new(high_value),
59
            blue: ColorValue.new(from)
60
          )
61
        else # :blue
62
4
          Color.new(
63
            red: ColorValue.new(low_value),
64
            green: ColorValue.new(from),
65
            blue: ColorValue.new(high_value)
66
          )
67
        end
68
      when .green?
69
8
        case @high_color
70
        when .red?
71
4
          Color.new(
72
            red: ColorValue.new(high_value),
73
            green: ColorValue.new(low_value),
74
            blue: ColorValue.new(from)
75
          )
76
        else # :blue
77
4
          Color.new(
78
            red: ColorValue.new(from),
79
            green: ColorValue.new(low_value),
80
            blue: ColorValue.new(high_value)
81
          )
82
        end
83
      else # :blue
84
8
        case @high_color
85
        when .red?
86
4
          Color.new(
87
            red: ColorValue.new(high_value),
88
            green: ColorValue.new(from),
89
            blue: ColorValue.new(low_value)
90
          )
91
        else # :green
92
4
          Color.new(
93
            red: ColorValue.new(from),
94
            green: ColorValue.new(high_value),
95
            blue: ColorValue.new(low_value)
96
          )
97
        end
98
      end
99
    end
100

        
101
    def check_colors
102
11
      raise SameColor.new @low_color if @low_color == @high_color
103
    end
104

        
105
    def each
106
200
      (min...max).each { |c| yield self[c] }
107
    end
108

        
109
    include Enumerable(Color)
110
  end
111
end
112