File: color.rb

package info (click to toggle)
ruby-faker 3.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,360 kB
  • sloc: ruby: 20,654; makefile: 6; sh: 6
file content (150 lines) | stat: -rw-r--r-- 4,561 bytes parent folder | download
1
2
3
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# frozen_string_literal: true

module Faker
  class Color < Base
    class << self
      LIGHTNESS_LOOKUP = {
        light: 0.8,
        dark: 0.2
      }.freeze
      ##
      # Produces a hex color code.
      # Clients are able to specify the hue, saturation, or lightness of the required color.
      # Alternatively a client can simply specify that they need a light or dark color.
      #
      # @param args [Hash, Symbol] Allows the client to specify what color should be return
      #
      # @return [String]
      #
      # @example
      #   Faker::Color.hex_color #=> "#31a785"
      # @example
      #   Faker::Color.hex_color(hue: 118, saturation: 1, lightness: 0.53) #=> "#048700"
      # @example
      #   Faker::Color.hex_color(:light) #=> "#FFEE99"
      # @example
      #   Faker::Color.hex_color(:dark) #=> "#665500"
      #
      # @faker.version next
      def hex_color(args = nil)
        hsl_hash = {}
        hsl_hash = { lightness: LIGHTNESS_LOOKUP[args] } if %i[dark light].include?(args)
        hsl_hash = args if args.is_a?(Hash)
        hsl_to_hex(hsl_color(**hsl_hash))
      end

      ##
      # Produces the name of a color.
      #
      # @return [String]
      #
      # @example
      #   Faker::Color.color_name #=> "yellow"
      #
      # @faker.version 1.6.2
      def color_name
        fetch('color.name')
      end

      # @private
      def single_rgb_color
        sample((0..255).to_a)
      end

      ##
      # Produces an array of integers representing an RGB color.
      #
      # @return [Array(Integer, Integer, Integer)]
      #
      # @example
      #   Faker::Color.rgb_color #=> [54, 233, 67]
      #
      # @faker.version 1.5.0
      def rgb_color
        Array.new(3) { single_rgb_color }
      end

      ##
      # Produces an array of floats representing an HSL color.
      # The array is in the form of `[hue, saturation, lightness]`.
      #
      # @param hue [FLoat] Optional value to use for hue
      # @param saturation [Float] Optional value to use for saturation
      # @param lightness [Float] Optional value to use for lightness
      # @return [Array(Float, Float, Float)]
      #
      # @example
      #   Faker::Color.hsl_color #=> [69.87, 0.66, 0.3]
      # @example
      #   Faker::Color.hsl_color(hue: 70, saturation: 0.5, lightness: 0.8) #=> [70, 0.5, 0.8]
      # @example
      #   Faker::Color.hsl_color(hue: 70) #=> [70, 0.66, 0.6]
      # @example
      #   Faker::Color.hsl_color(saturation: 0.2) #=> [54, 0.2, 0.3]
      # @example
      #   Faker::Color.hsl_color(lightness: 0.6) #=> [69.87, 0.66, 0.6]
      #
      # @faker.version next
      def hsl_color(hue: nil, saturation: nil, lightness: nil)
        valid_hue = hue || sample((0..360).to_a)
        valid_saturation = saturation&.clamp(0, 1) || rand.round(2)
        valid_lightness = lightness&.clamp(0, 1) || rand.round(2)
        [valid_hue, valid_saturation, valid_lightness]
      end

      ##
      # Produces an array of floats representing an HSLA color.
      # The array is in the form of `[hue, saturation, lightness, alpha]`.
      #
      # @return [Array(Float, Float, Float, Float)]
      #
      # @example
      #   Faker::Color.hsla_color #=> [154.77, 0.36, 0.9, 0.2]
      #
      # @faker.version 1.5.0
      def hsla_color
        hsl_color << rand.round(1)
      end

      private

      ##
      # Produces a hex code representation of an HSL color
      #
      # @param a_hsl_color [Array(Float, Float, Float)] The array that represents the HSL color
      #
      # @return [String]
      #
      # @example
      #   hsl_to_hex([50, 100,80]) #=> #FFEE99
      #
      # @see https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB
      # @see https://github.com/jpmckinney/color-generator/blob/master/lib/color-generator.rb
      #
      def hsl_to_hex(a_hsl_color)
        h, s, l = a_hsl_color
        c = (1 - (2 * l - 1).abs) * s
        h_prime = h / 60
        x = c * (1 - (h_prime % 2 - 1).abs)
        m = l - 0.5 * c

        rgb = case h_prime.to_i
              when 0 # 0 <= H' < 1
                [c, x, 0]
              when 1 # 1 <= H' < 2
                [x, c, 0]
              when 2 # 2 <= H' < 3
                [0, c, x]
              when 3 # 3 <= H' < 4
                [0, x, c]
              when 4 # 4 <= H' < 5
                [x, 0, c]
              else # 5 <= H' < 6
                [c, 0, x]
              end.map { |value| ((value + m) * 255).round }

        format('#%02x%02x%02x', rgb[0], rgb[1], rgb[2])
      end
    end
  end
end