Skip to content

Commit ccb0525

Browse files
committed
Docs: Rework harmony visualization and adjust wording of harmony docs
- Rework the harmony visualization to be a function that can be called within a playground. - Tweak harmony visualization styling. - Adjust some of the documentation to phrase things better.
1 parent 0d08cb4 commit ccb0525

File tree

15 files changed

+231
-194
lines changed

15 files changed

+231
-194
lines changed

docs/src/markdown/.snippets/info-container.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

docs/src/markdown/colors/ryb.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ Name | Range
2222
////
2323

2424

25-
```py play wheel
26-
Color('ryb', [1, 0, 0]).harmony('wheel', space='ryb')
25+
```py play
26+
Wheel(Color('ryb', [1, 0, 0]).harmony('wheel', space='ryb'))
2727
```
28+
2829
//// figure-caption
2930
The RYB color wheel.
3031
////

docs/src/markdown/harmonies.md

Lines changed: 64 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,89 @@
11
# Color Harmonies
22

3-
In color theory, color harmony refers to the property that certain aesthetically pleasing color combinations have.
4-
Modern day color theory probably starts with the first color wheel created by Isaac Newton. Based on his observations of
5-
light with prisms, he formed one the first color wheels. From there, many others built upon this work, sometimes with
6-
opposing ideas.
3+
Isaac Newton, based on his observations of light interacting with prisms, constructed the first known color wheel. From
4+
there, many others built upon this work, sometimes with opposing ideas, but his original work is where color harmony got
5+
its start.
76

87
The original color wheel, while inspired by what was observed by light, was created based on experiments with pigments
9-
as well. As most know, in paint, red, yellow, and blue are considered primary colors. Newton thought this translated to
10-
light as well and stated they were also the primary colors of light. While this isn't actually true, his work was very
11-
important in reshaping how people viewed color.
8+
as well. In paints, red, yellow, and blue are often taught to be primary colors. This idea originates from Newton's
9+
work as through his experiments, he came to the conclusions that all colors could be made from red, yellow, and blue,
10+
and assumed this was true for light as well. While this isn't exactly true, his work was very important in reshaping how
11+
people viewed color.
1212

1313
Over time, the color wheel was refined. The traditional model, which we will call an RYB color model, defined 12 colors
1414
that made up the wheel: the primary colors, the secondary colors, and the tertiary colors. The secondary colors are
1515
created by evenly mixing the primary colors, and the tertiary colors are created by evenly mixing those primary colors
1616
with the secondary colors.
1717

18-
```py play wheel
19-
Color('ryb', [1, 0, 0]).harmony('wheel', space='ryb')
18+
```py play
19+
Wheel(Color('ryb', [1, 0, 0]).harmony('wheel', space='ryb'))
2020
```
2121

22-
The idea of color harmonies originates from the idea that colors, based on their relative position on the wheel, can
23-
form more pleasing color combinations.
22+
The concept of color harmonies was formulated on the idea that colors, based on specific, relative position on the
23+
wheel, can form more pleasing color combinations.
2424

2525
## Which Color Space is Best for Color Harmonies?
2626

27-
As we know, these days, there are many color spaces out there: subtractive models, additive models, perceptually
28-
uniform models, high dynamic range models, etc. Many color spaces trying to solve specific issues based on the knowledge
29-
at the time.
27+
These days, there are many color spaces and models out there: subtractive models, additive models, perceptually
28+
uniform models, high dynamic range models, etc. But which space/model is the best for color harmonies?
29+
30+
The concept of primary colors stems from the idea that there are a set of pure colors from which all colors can be made
31+
from. The primary colors of electronic screens use red, green, and blue light to display its full gamut of color.
32+
Interestingly, electronic screens were modeled after the human eye that have three cones, each sensitive to wavelengths
33+
close to red, green, and blue. From what the three cones in the eye detect, our brain perceive all the various colors.
3034

31-
It should be noted, that the idea of primary colors stems from the idea that there are a set of pure colors from which
32-
all colors can be made from. If you've spent any time with paint, you will know that not all colors can be made from
33-
red, yellow, and blue. There are colors like `#!color cyan` and `#!color magenta` that cannot be made with the
34-
traditional primary colors. The early work that helped create the first color wheels was done with the limited paints
35-
that was available at the time, and the color harmony concepts were built upon the early RYB color model. Modern
36-
printers actually use primary colors of `#!color magenta`, `#!color yellow`, and `#!color cyan`.
35+
Paints and inks on the other hand can alter the light that comes back to our eye depending on the medium's light
36+
absorption and scattering properties. These physical properties of the medium can alter what light is reflected back to
37+
our eyes causing how our eyes perceive the mixing of colors in paint. This mixing behavior in pigments can seem different
38+
when compared to how pure light mixes.
3739

38-
In modern TVs and monitors, the RYB color model is not used. Paint has subtractive properties, but light has additive
39-
properties. Electronic screens create all their colors with light based methods that mix red, green, and blue lights. In
40-
addition, the human eye perceives colors using red, green, and blue light as well. As far as light is concerned, the
41-
primary colors are red, green, and blue.
40+
The work that helped create the first color wheel was done with the limited paints that were available at the time, and
41+
influenced by the light scattering and absorption properties of those paints. Because of this, the original color wheel
42+
is built on the RYB color model which uses red, yellow, and blue as the primary colors. The question though, is would
43+
our theories on color harmony be different today if early theorists had a better understanding of light and color?
4244

43-
In reality, we could create a color wheel from any of the various color spaces out there and end up with different
44-
results. If we were to compose a color wheel based on the common sRGB color space, we could base it off the 3 primary
45-
colors of light. Starting with red (0˚), we could extract the colors at evenly spaced degrees, 30˚ to be exact. This
46-
would give us our 12 colors for the sRGB color space.
45+
In reality, we can create a color wheel from any of the various color spaces out there and end up with different
46+
results based on how color is spaced and oriented within those spaces. As an example, we could create one directly from
47+
the sRGB color space. The sRGB space is an additive color space that was modeled on light behavior, so its primary
48+
colors are red, green, and blue. We can simply select the most red, green, and blue colors in its gamut, and transform
49+
them into a polar space such as HSL. Here, these colors are evenly spaced and if we mixed these colors evenly, and those
50+
colors evenly, we will get 12 colors whose hues are evenly spaced at 30˚.
4751

4852
```py play
4953
Steps([Color('hsl', [x, 1, 0.5]) for x in range(0, 360, 30)])
5054
```
5155

5256
From this we can construct an sRGB color wheel.
5357

54-
```py play wheel
55-
Color('red').harmony('wheel', space='srgb')
58+
```py play
59+
Wheel(Color('red').harmony('wheel', space='srgb'))
5660
```
5761

58-
This is different from the RYB color wheel we showed earlier, and more accurate in relation to how light works, but does
59-
it yield better harmonies for colors?
62+
These results are different from the RYB color wheel we showed earlier, but are used to display all the colors you see
63+
on your screen right now. This is how light works when not scattered and absorbed by pigments, but does that mean that
64+
this color wheel yields better color harmonies?
6065

61-
The sRGB color space is additive, just like light, but pigments are subtractive. We can use CMY to generate a
62-
subtractive wheel with a far greater range that red, green blue creates by use magenta, yellow, and cyan. But does this
63-
create better harmonies?
66+
We can transform the RGB color model into a subtractive color space, something similar to what printers use when
67+
applying ink to paper. Printers use something closer to an RYB model and use magenta, yellow, and cyan.
6468

6569
```py play
66-
Steps(Color('magenta').harmony('wheel', space='cmy'))
67-
```
68-
69-
```py play wheel
70-
Color('magenta').harmony('wheel', space='cmy')
70+
Wheel(Color('magenta').harmony('wheel', space='cmy'))
7171
```
7272

73-
If we were to select the perceptually uniform OkLCh color space, and seed it with red's lightness and chroma, we'd get
74-
the wheel below.
73+
If we were to select the perceptually uniform OkLCh color space, and seed it with red's lightness and chroma, we'd once
74+
again get very different results in the color wheel. The results are more similar to when we used sRGB, but the exact
75+
hues may be different and lightness is kept more uniform when we construct the wheel. But does that mean this model is
76+
better?
7577

7678
```py play
77-
Steps(Color('red').harmony('wheel', space='oklch'))
79+
Wheel(Color('red').harmony('wheel', space='oklch'))
7880
```
7981

80-
```py play wheel
81-
Color('red').harmony('wheel', space='oklch')
82-
```
83-
84-
This produces colors with visually more uniform lightness, does that mean these are better?
85-
86-
The truth is, what is better or even harmonious can be largely subjective, and everyone has reasons for selecting
87-
certain color spaces for a specific task.
82+
The truth is that what is better or even harmonious can be largely subjective.
8883

89-
Many artists swear by the limited, classical color wheel, others are fine with using the RGB color wheel as it is easy
90-
to work with in CSS via the HSL color space, and there are still others that are more interested in perceptually uniform
91-
color spaces that aim for more consistent hues and predictable lightness.
84+
Many artists swear by the limited, classical RYB color wheel, and others are fine with using the sRGB color wheel as it
85+
is easy to work with in CSS via the HSL color space, and models closer to how the eye works. Additionally, there may be
86+
some that prefer a perceptually uniform approach that aims for more consistent hues and predictable lightness.
9287

9388
As far as ColorAide is concerned, we've chosen to use OkLCh as the color space in which we work in. This is based
9489
mainly on the fact that it keeps hue more consistent than some other options, and it allows us to support a wider gamut
@@ -100,7 +95,9 @@ Steps(Color.steps(['black', 'blue', 'white'], steps=11, space='hsl'))
10095
Steps(Color.steps(['black', 'blue', 'white'], steps=11, space='lch'))
10196
```
10297

103-
While OkLCh is the default, we understand that there are many reasons to use other spaces, so use what you like, we
98+
While OkLCh is the default, we make no assertions that this is better than using any other color space. If you are from
99+
the world of paint, you may strongly dislike this default and prefer a classical RYB approach, or maybe you just want to
100+
use the familiar sRGB approach. We understand that there are many reasons to use other spaces, so use what you like, we
104101
won't judge :smile:. If you are a color theory purist, you can use the classical RYB model.
105102

106103
```py play
@@ -115,14 +112,14 @@ harmonies, make sure you are working directly within RYB to ensure you are not o
115112
///
116113

117114
/// tip
118-
`harmony()` can output the results in any color space you need by setting `out_space`.
115+
Regardless of what color space `harmony()` operates in, it can output the results in any color space you need by setting
116+
`out_space`.
119117

120118
```py play
121119
Steps(Color('red').harmony('complement', out_space='srgb'))
122120
```
123121
///
124122

125-
126123
## Supported Harmonies
127124

128125
ColorAide currently supports 7 theorized color harmonies: [monochromatic](#monochromatic),
@@ -224,17 +221,13 @@ Steps(Color('red').harmony('rectangle'))
224221
### Others
225222

226223
If you have a particular configuration that you are after that is not covered with the default harmonies, you can use
227-
`harmony` to calculate your own via `wheel`. The `wheel` harmony that can generate a color wheel of any size. Simply use
228-
a color to seed the wheel, specify the space in which to generate the wheel, and optionally, provide the desired number
229-
of colors in the color wheel via the `count` argument. With this, we can generate a wheel for any color (assuming the
230-
color space can properly handle the color). We can even generate an extended color wheel if so desired. This can allow
231-
you to select hues at any interval you need.
232-
233-
```py play wheel
234-
Color('ryb', [1, 0, 0]).harmony('wheel', space='ryb', count=48)
235-
```
224+
`harmony` to calculate your own via `wheel`. The `wheel` harmony that can generate a wheel of evenly spaced colors of
225+
any size. From this, additional harmonies could be calculated. Simply use a color to seed the wheel, specify the space
226+
in which to generate the wheel, and optionally, provide the desired number of colors in the color wheel via the `count`
227+
argument. With this, we can generate a wheel of any size for any color.
236228

237229
```py play
230+
Wheel(Color('ryb', [1, 0, 0]).harmony('wheel', space='ryb', count=48))
238231
Steps(Color('ryb', [1, 0, 0]).harmony('wheel', space='ryb', count=48))
239232
```
240233

@@ -246,14 +239,14 @@ Non-cylindrical space support was added in 2.7.
246239

247240
If you'd like to change the `#!py3 Color()` class's default harmony color space, it can be done with
248241
[class override](./color.md#override-default-settings). Simply derive a new `#!py3 Color()` class from the original and
249-
override the `HARMONY` property with the name of a suitable color space. Color spaces must be either a cylindrical
250-
space, a Lab-like color space, or what we will call a regular, rectangular space. By "regular" we mean a normal 3
251-
channel color space _usually_ with a range of [0, 1]. Afterwards, all color harmony calculations will use the specified
252-
color space unless overridden via the method's `space` parameter.
242+
override the `HARMONY` property with the name of a suitable color space. Color spaces must be a registered color space
243+
of either a cylindrical space, a Lab-like color space, or what we will call a regular, rectangular space. By "regular"
244+
we mean a normal 3 channel color space _usually_ with a range of [0, 1] (think RGB). Afterwards, all color harmony
245+
calculations will use the specified color space unless overridden via the method's `space` parameter.
253246

254247
```py play
255248
class Custom(Color):
256-
HARMONY = 'hsl'
249+
HARMONY = 'ryb'
257250

258251
Steps(Custom('red').harmony('split'))
259252
```

0 commit comments

Comments
 (0)