Skip to content

Instantly share code, notes, and snippets.

@ux
Last active February 12, 2019 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ux/6519f85fb58a207e4e47ce11f56859ff to your computer and use it in GitHub Desktop.
Save ux/6519f85fb58a207e4e47ce11f56859ff to your computer and use it in GitHub Desktop.
Color = Struct.new(:red, :green, :blue)
FONT_COLOR_ALPHA = 0.9
COLOR_COMPONENT_MAX_VALUE = 255
WHITE_COLOR = Color.new(COLOR_COMPONENT_MAX_VALUE, COLOR_COMPONENT_MAX_VALUE, COLOR_COMPONENT_MAX_VALUE).freeze
BLACK_COLOR = Color.new(0, 0, 0).freeze
def blend_color_components background_value, overlay_value, alpha
# https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
(overlay_value * alpha + background_value * (1 - alpha)).round
end
def blend_colors background_color, overlay_color, alpha
Color.new \
blend_color_components(background_color.red, overlay_color.red, alpha),
blend_color_components(background_color.green, overlay_color.green, alpha),
blend_color_components(background_color.blue, overlay_color.blue, alpha)
end
def color_component_value_for_relative_luminance value, max_value
relative_value = value.to_f / max_value
if relative_value <= 0.03928
relative_value / 12.92
else
((relative_value + 0.055) / 1.055) ** 2.4
end
end
def calculate_relative_luminance color, color_component_max_value = COLOR_COMPONENT_MAX_VALUE
# https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
0.2126 * color_component_value_for_relative_luminance(color.red, color_component_max_value) +
0.7152 * color_component_value_for_relative_luminance(color.green, color_component_max_value) +
0.0722 * color_component_value_for_relative_luminance(color.blue, color_component_max_value)
end
def calculate_contrast_ratio luminance_1, luminance_2
# https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
darker_luminance, lighter_luminance = [luminance_1, luminance_2].sort
(lighter_luminance + 0.05) / (darker_luminance + 0.05)
end
def determine_font_color background_color
light_color = blend_colors background_color, WHITE_COLOR, FONT_COLOR_ALPHA
dark_color = blend_colors background_color, BLACK_COLOR, FONT_COLOR_ALPHA
background_luminance = calculate_relative_luminance background_color
light_color_luminance = calculate_relative_luminance light_color
dark_color_luminance = calculate_relative_luminance dark_color
light_color_contrast_ratio = calculate_contrast_ratio background_luminance, light_color_luminance
dark_color_contrast_ratio = calculate_contrast_ratio background_luminance, dark_color_luminance
light_color_contrast_ratio > dark_color_contrast_ratio ? light_color : dark_color
end
# Usage:
determine_font_color WHITE_COLOR
# => #<struct Color red=25, green=25, blue=25>
determine_font_color BLACK_COLOR
# => #<struct Color red=230, green=230, blue=230>
determine_font_color Color.new(COLOR_COMPONENT_MAX_VALUE, 0, 0)
# => #<struct Color red=25, green=0, blue=0>
determine_font_color Color.new(0, COLOR_COMPONENT_MAX_VALUE, 0)
# => #<struct Color red=0, green=25, blue=0>
determine_font_color Color.new(0, 0, COLOR_COMPONENT_MAX_VALUE)
# => #<struct Color red=230, green=230, blue=255>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment