Fill a banner or an illustration with close neighbors of your color with .analogous(). You get count hues spread apart, centered on yours, all at your color's lightness.
Rectangle()
.fill(brand._400.analogous().proGradient(from: .leading, to: .trailing)) // 137°, 167° and 197°
.frame(height: 64)Pick your color below and change the count and spread. With the defaults, you get three hues 30° apart.
Every OKLCH hue at this color's lightness
let color = Color.proBlue._400.toColor()
color.analogous()More neighbors, closer together#
Raise count for more colors and lower spread to keep them close. Five hues 15° apart stay within 30° of yours either way:
let neighbors = brand._400.analogous(count: 5, spread: .degrees(15))Hues around the whole wheel#
A spread of 360° divided by count spaces the colors evenly around the wheel, with yours in the middle of the list. That gives five chart series as far apart as five hues can be:
let series = brand.analogous(count: 5, spread: .degrees(72)) // families at 23°, 95°, 167°, 239° and 311°Using tokens in charts shows which token each series takes.
How it behaves#
The colors come back from the most negative offset to the most positive, so yours sits in the middle: Color.proBlue.analogous() is cerulean, blue and iris. With an even count there is no middle, so your color isn't one of them: analogous(count: 2) gives the hues 15° either side.
A count below 1 counts as 1, which gives your color alone. Each color is turned with rotateHue(by:), so a palette color lands on the same stop at its new hue. On a ProTheme, you get whole families at the stop you started from. Gray has no hue, so its neighbors are all gray.
API#
public extension Color {
func analogous(count: Int = 3, spread: Angle = .degrees(30)) -> [Color]
}
public extension ProTheme {
func analogous(count: Int = 3, spread: Angle = .degrees(30)) -> [ProTheme]
}| Parameter | Type | Default | What other values do |
|---|---|---|---|
count | Int | 3 | How many colors. With an even count, yours isn't one of them. Below 1 counts as 1. |
spread | Angle | 30° | The gap between neighbors. 360° divided by count spaces them around the whole wheel. |
It returns count colors or families, centered on yours. It's the same as harmony(.analogous(count:spread:)).
Sources#
- ColorTokensKit source: Color+Harmonies.swift and ProTheme+Harmonies.swift, which define
analogous, and ColorHarmony.swift, which works out its hues.
See also
- Color theory Pair stops that always read, and pick secondary hues that match your brand, in both modes.
- .proGradient() Fill cards and buttons with gradients that stay vivid end to end, in light and dark mode.
- .triad Secondary and tertiary colors for tags and categories, at the same contrast as your brand.
- Gradient theory Add depth with gradients that stay vivid, from a single color or a recipe, in both modes.