Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue-2464: Add color luminosity options #2566

Merged
merged 11 commits into from
Sep 26, 2022
62 changes: 56 additions & 6 deletions lib/faker/default/color.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ class << self
##
# Produces a hex color code.
#
# @param lightness [Symbol] Allows the client to specify light or dark colors
#
# @return [String]
#
# @example
# Faker::Color.hex_color #=> "#31a785"
# @example
# Faker::Color.hex_color(:light) #=> "#FFEE99"
# @example
# Faker::Color.hex_color(:dark) #=> "#665500"
#
# @faker.version 1.5.0
def hex_color
format('#%06x', (rand * 0xffffff))
# @faker.version next
def hex_color(lightness = nil)
lightness_lookup = { light: 0.8, dark: 0.2 }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might become a constant?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A constant for this would be good

hsl_to_hex(hsl_color(lightness: lightness_lookup[lightness]))
end

##
Expand Down Expand Up @@ -51,14 +58,17 @@ def rgb_color
# Produces an array of floats representing an HSL color.
# The array is in the form of `[hue, saturation, lightness]`.
#
# @param lightness [Float] 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(lightness: 0.6) #=> [69.87, 0.66, 0.6]
#
# @faker.version 1.5.0
def hsl_color
[sample((0..360).to_a), rand.round(2), rand.round(2)]
# @faker.version next
def hsl_color(lightness: nil)
Zeragamba marked this conversation as resolved.
Show resolved Hide resolved
[sample((0..360).to_a), rand.round(2), lightness || rand.round(2)]
end

##
Expand All @@ -74,6 +84,46 @@ def hsl_color
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)
fbuys marked this conversation as resolved.
Show resolved Hide resolved
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
19 changes: 19 additions & 0 deletions test/faker/default/test_faker_color.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ def test_hex_color
assert_match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/, @tester.hex_color)
end

# @see https://www.rapidtables.com/convert/color/rgb-to-hsl.html
def helper_hex_lightness(hex_color)
Zeragamba marked this conversation as resolved.
Show resolved Hide resolved
result = hex_color.scan(/([A-Fa-f0-9]{2})/).flatten.map { |x| x.hex / 255.0 }
(result.max + result.min) / 2
end

def test_hex_color_light
assert_in_delta(0.8, helper_hex_lightness(@tester.hex_color(:light)))
end

def test_hex_color_dark
assert_in_delta(0.2, helper_hex_lightness(@tester.hex_color(:dark)))
end

def test_single_rgb_color
assert @tester.single_rgb_color.between?(0, 255)
end
Expand All @@ -38,6 +52,11 @@ def test_hsl_color
assert @result[2].between?(0.0, 1.0)
end

def test_hsl_color_with_a_speficied_lightness
@result = @tester.hsl_color(lightness: 0.5)
assert_in_delta(0.5, @result[2])
end

def test_hsla_color
@result = @tester.hsla_color
assert_equal(4, @result.length)
Expand Down