Module: ColorContrastCalc::Utils

Extended by:
Hwb
Defined in:
lib/color_contrast_calc/utils.rb

Overview

Utility functions that provide basic operations on colors.

This module provides basic operations on colors given as RGB values (including their hex code presentations) or HSL values.

Defined Under Namespace

Modules: Hwb

Constant Summary collapse

MIN_OPACITY =
0
MAX_OPACITY =
1.0

Constants included from Hwb

Hwb::HWB_UPPER_LIMIT

Class Method Summary collapse

Methods included from Hwb

hex_to_hwb, hwb_to_hex, hwb_to_rgb, rgb_to_hwb, valid_hwb?

Class Method Details

.hex_to_hsl(hex_code) ⇒ Array<Float>

Convert hex color code to HSL value.

Parameters:

  • hex_code (String)

    Hex color code such as “#ffff00”

Returns:

  • (Array<Float>)

    HSL value represented as an array of numbers



180
181
182
# File 'lib/color_contrast_calc/utils.rb', line 180

def self.hex_to_hsl(hex_code)
  rgb_to_hsl(hex_to_rgb(hex_code))
end

.hex_to_rgb(hex_code) ⇒ Array<Integer>

Convert a hex color code string to a RGB value.

Parameters:

  • hex_code (String)

    Hex color code such as “#ffff00”

Returns:

  • (Array<Integer>)

    RGB value represented as an array of integers



32
33
34
35
36
37
38
39
40
41
# File 'lib/color_contrast_calc/utils.rb', line 32

def self.hex_to_rgb(hex_code)
  hex_part = hex_code.start_with?('#') ? hex_code[1..-1] : hex_code

  case hex_part.length
  when 3
    hex_part.chars.map {|c| c.hex * 17 }
  when 6
    [0, 2, 4].map {|i| hex_part[i, 2].hex }
  end
end

.hsl_to_hex(hsl) ⇒ String

Convert HSL value to hex color code.

Parameters:

  • hsl (Array<Float>)

    HSL value represented as an array of numbers

Returns:

  • (String)

    Hex color code such as “#ffff00”



110
111
112
# File 'lib/color_contrast_calc/utils.rb', line 110

def self.hsl_to_hex(hsl)
  rgb_to_hex(hsl_to_rgb(hsl))
end

.hsl_to_rgb(hsl) ⇒ Array<Integer>

Convert HSL value to RGB value.

Parameters:

  • hsl (Array<Float>)

    HSL value represented as an array of numbers

Returns:

  • (Array<Integer>)

    RGB value represented as an array of integers



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/color_contrast_calc/utils.rb', line 79

def self.hsl_to_rgb(hsl)
  # https://www.w3.org/TR/css3-color/#hsl-color
  h = hsl[0] / 360.0
  s = hsl[1] / 100.0
  l = hsl[2] / 100.0
  m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s
  m1 = l * 2 - m2
  [h + 1 / 3.0, h, h - 1 / 3.0].map do |adjusted_h|
    (hue_to_rgb(m1, m2, adjusted_h) * 255).round
  end
end

.normalize_hex(code, prefix = true) ⇒ String

Normalize a hex color code to a 6 digits, lowercased one.

Parameters:

  • code (String)

    Hex color code such as “#ffff00”, “#ff0” or “FFFF00”

  • prefix (true, false) (defaults to: true)

    If set to False, “#” at the head of result is removed

Returns:

  • (String)

    6-digit hexadecimal string in lowercase, with/without leading “#” depending on the value of prefix



52
53
54
55
56
57
58
59
60
61
# File 'lib/color_contrast_calc/utils.rb', line 52

def self.normalize_hex(code, prefix = true)
  if code.length < 6
    hex_part = code.start_with?('#') ? code[1..-1] : code
    code = hex_part.chars.map {|c| c * 2 }.join
  end

  lowered = code.downcase
  return lowered if prefix == lowered.start_with?('#')
  prefix ? "##{lowered}" : lowered[1..-1]
end

.rgb_to_hex(rgb) ⇒ String

Convert a RGB value to a hex color code.

Parameters:

  • rgb (Array<Integer>)

    RGB value represented as an array of integers

Returns:

  • (String)

    Hex color code such as “#ffff00”



69
70
71
# File 'lib/color_contrast_calc/utils.rb', line 69

def self.rgb_to_hex(rgb)
  format('#%02x%02x%02x', *rgb)
end

.rgb_to_hsl(rgb) ⇒ Array<Float>

Convert RGB value to HSL value.

Parameters:

  • rgb (Array<Integer>)

    RGB value represented as an array of integers

Returns:

  • (Array<Float>)

    HSL value represented as an array of numbers



120
121
122
# File 'lib/color_contrast_calc/utils.rb', line 120

def self.rgb_to_hsl(rgb)
  [rgb_to_hue(rgb), rgb_to_saturation(rgb), rgb_to_lightness(rgb)]
end

.same_hex_color?(hex1, hex2) ⇒ true, false

Check if given two hex color codes represent a same color.

Parameters:

  • hex1 (String)

    RGB value in hex color code such as “#ffff00”, “#ffff00”, “#FFFF00” or “#ff0”

  • hex2 (String)

    RGB value in hex color code such as “#ffff00”, “#ffff00”, “#FFFF00” or “#ff0”

Returns:

  • (true, false)

    true if given two colors are same



226
227
228
# File 'lib/color_contrast_calc/utils.rb', line 226

def self.same_hex_color?(hex1, hex2)
  normalize_hex(hex1) == normalize_hex(hex2)
end

.uppercase?(str) ⇒ true, false

Check if a given string is consists of uppercase letters.

Parameters:

  • str (String)

    string to be checked

Returns:

  • (true, false)

    true if letters in the passed string are all in uppercase.



237
238
239
# File 'lib/color_contrast_calc/utils.rb', line 237

def self.uppercase?(str)
  !/[[:lower:]]/.match?(str)
end

.valid_hex?(hex_code) ⇒ true, false

Check if a given string is a valid representation of RGB color.

Parameters:

  • hex_code (String)

    RGB value in hex color code such as “#ffff00”

Returns:

  • (true, false)

    true if a vaild hex color code is passed



213
214
215
# File 'lib/color_contrast_calc/utils.rb', line 213

def self.valid_hex?(hex_code)
  HEX_RE.match?(hex_code)
end

.valid_hsl?(hsl) ⇒ true, false

Check if a given array is a valid representation of HSL color.

Parameters:

  • hsl (Array<Float>)

    HSL value represented as an array of numbers

Returns:

  • (true, false)

    true if a valid HSL value is passed



201
202
203
204
205
# File 'lib/color_contrast_calc/utils.rb', line 201

def self.valid_hsl?(hsl)
  hsl.length == 3 && hsl.each_with_index.all? do |c, i|
    c.is_a?(Numeric) && c >= 0 && c <= HSL_UPPER_LIMIT[i]
  end
end

.valid_rgb?(rgb) ⇒ true, false

Check if a given array is a valid representation of RGB color.

Parameters:

  • rgb (Array<Integer>)

    RGB value represented as an array of integers

Returns:

  • (true, false)

    true if a valid RGB value is passed



190
191
192
193
# File 'lib/color_contrast_calc/utils.rb', line 190

def self.valid_rgb?(rgb)
  rgb.length == 3 &&
    rgb.all? {|c| c.is_a?(Integer) && c >= 0 && c <= 255 }
end