Class: Color::Palette::MonoContrast

Inherits:
Object
  • Object
show all
Defined in:
lib/color/palette/monocontrast.rb

Overview

Generates a monochromatic constrasting colour palette for background and foreground. What does this mean?

Monochromatic: A single colour is used to generate the base palette, and this colour is lightened five times and darkened five times to provide eleven distinct colours.

Contrasting: The foreground is also generated as a monochromatic colour palette; however, all generated colours are tested to see that they are appropriately contrasting to ensure maximum readability of the foreground against the background.

Constant Summary collapse

DEFAULT_MINIMUM_BRIGHTNESS_DIFF =
(125.0 / 255.0)
DEFAULT_MINIMUM_COLOR_DIFF =
(500.0 / 255.0)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(background, foreground = nil) ⇒ MonoContrast

Generate the initial palette.



73
74
75
76
77
# File 'lib/color/palette/monocontrast.rb', line 73

def initialize(background, foreground = nil)
  @minimum_brightness_diff = DEFAULT_MINIMUM_BRIGHTNESS_DIFF
  @minimum_color_diff = DEFAULT_MINIMUM_COLOR_DIFF
  regenerate(background, foreground)
end

Instance Attribute Details

#backgroundObject (readonly)

Hash of CSS background colour values.

This is always 11 values:

0

The starting colour.

1..5

Lighter colours.

-1..-5

Darker colours.



22
23
24
# File 'lib/color/palette/monocontrast.rb', line 22

def background
  @background
end

#foregroundObject (readonly)

Hash of CSS foreground colour values.

This is always 11 values:

0

The starting colour.

1..5

Lighter colours.

-1..-5

Darker colours.



30
31
32
# File 'lib/color/palette/monocontrast.rb', line 30

def foreground
  @foreground
end

#minimum_brightness_diffObject

The minimum brightness difference between the background and the foreground, and must be between 0..1. Setting this value will regenerate the palette based on the base colours. The default value for this is 125 / 255.0. If this value is set to nil, it will be restored to the default.



39
40
41
# File 'lib/color/palette/monocontrast.rb', line 39

def minimum_brightness_diff
  @minimum_brightness_diff
end

#minimum_color_diffObject

The minimum colour difference between the background and the foreground, and must be between 0..3. Setting this value will regenerate the palette based on the base colours. The default value for this is 500 / 255.0.



58
59
60
# File 'lib/color/palette/monocontrast.rb', line 58

def minimum_color_diff
  @minimum_color_diff
end

Instance Method Details

#brightness_diff(c1, c2) ⇒ Object

Returns the absolute difference between the brightness levels of two colours. This will be a decimal value between 0 and 1. W3C accessibility guidelines for colour contrast suggest that this value be at least approximately 0.49 (125 / 255.0) for proper contrast.



150
151
152
# File 'lib/color/palette/monocontrast.rb', line 150

def brightness_diff(c1, c2)
  (c1.brightness - c2.brightness).abs
end

#calculate_foreground(background, foreground) ⇒ Object

Given a background colour and a foreground colour, modifies the foreground colour so that it will have enough contrast to be seen against the background colour.

Uses #mininum_brightness_diff and #minimum_color_diff.



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
# File 'lib/color/palette/monocontrast.rb', line 118

def calculate_foreground(background, foreground)
  nfg = nil
  # Loop through brighter and darker versions of the foreground color. The
  # numbers here represent the amount of foreground color to mix with
  # black and white.
  [100, 75, 50, 25, 0].each do |percent|
    dfg = foreground.darken_by(percent)
    lfg = foreground.lighten_by(percent)

    dbd = brightness_diff(background, dfg)
    lbd = brightness_diff(background, lfg)

    if lbd > dbd
      nfg = lfg
      nbd = lbd
    else
      nfg = dfg
      nbd = dbd
    end

    ncd = color_diff(background, nfg)

    break if nbd >= @minimum_brightness_diff and ncd >= @minimum_color_diff
  end
  nfg
end

#color_diff(c1, c2) ⇒ Object

Returns the contrast between to colours, a decimal value between 0 and

  1. W3C accessibility guidelines for

contrast[www.w3.org/TR/AERT#color-contrast] suggest that this value be at least approximately 1.96 (500 / 255.0) for proper contrast.



158
159
160
161
162
163
# File 'lib/color/palette/monocontrast.rb', line 158

def color_diff(c1, c2)
  r = (c1.r - c2.r).abs
  g = (c1.g - c2.g).abs
  b = (c1.b - c2.b).abs
  r + g + b
end

#regenerate(background, foreground = nil) ⇒ Object

Generate the colour palettes.



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
# File 'lib/color/palette/monocontrast.rb', line 80

def regenerate(background, foreground = nil)
  foreground ||= background
  background = background.to_rgb
  foreground = foreground.to_rgb

  @background = {}
  @foreground = {}

  @background[-5] = background.darken_by(10)
  @background[-4] = background.darken_by(25)
  @background[-3] = background.darken_by(50)
  @background[-2] = background.darken_by(75)
  @background[-1] = background.darken_by(85)
  @background[ 0] = background
  @background[+1] = background.lighten_by(85)
  @background[+2] = background.lighten_by(75)
  @background[+3] = background.lighten_by(50)
  @background[+4] = background.lighten_by(25)
  @background[+5] = background.lighten_by(10)

  @foreground[-5] = calculate_foreground(@background[-5], foreground)
  @foreground[-4] = calculate_foreground(@background[-4], foreground)
  @foreground[-3] = calculate_foreground(@background[-3], foreground)
  @foreground[-2] = calculate_foreground(@background[-2], foreground)
  @foreground[-1] = calculate_foreground(@background[-1], foreground)
  @foreground[ 0] = calculate_foreground(@background[ 0], foreground)
  @foreground[+1] = calculate_foreground(@background[+1], foreground)
  @foreground[+2] = calculate_foreground(@background[+2], foreground)
  @foreground[+3] = calculate_foreground(@background[+3], foreground)
  @foreground[+4] = calculate_foreground(@background[+4], foreground)
  @foreground[+5] = calculate_foreground(@background[+5], foreground)
end