Last active
February 12, 2019 18:47
-
-
Save ux/6519f85fb58a207e4e47ce11f56859ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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