# Combining Colors

Ever wanted that color but a bit darker? Or to combine one color with another?

That’s what we’ll learn to do now

## What is color to a computer?

The color of a pixel is described by the amount of red, green and blue light it emits.

In case you didn’t already know there are thousands of tiny colored lights/LEDs on the screen you are using to read this article. Under a microscope your screen looks like this:

The computer only knows how much electricity to give to each one of the 3 LEDs that represent a pixel. So if a pixel is red the green and blue lights get low or no electricity and the red one gets a lot.

## RGB Color Model

The RGB color model (stands for Red Green Blue) is an additive color model in which red, green and blue light are added together in various ways to reproduce a broad spectrum of colors.

You might remember from school that red, blue and yellow are primary colors. And that is still true!

But there are two different things:

1) how colors combine if they reflect light
2) how colors combine if they emit light

When you use paint light either from the sun or from another source hits the paint and then reflcts in to your eyes. When you use pixels on a screen light is emitted from the screen and then hits your retina

To encode a color in RGB you need three numebrs between `0` and `255` or between `0.0` and `1.0`. If you use the floating point representation it will still get converted to the discrete representation from `0` to `255` where `0` means the light is not turned on for that color and `255` that it’s turned on at the maximum level.

One thing to keep in mind is that any display only shows colors in RGB.

## RGBA Color Space

RGBA(stands for red greeb blue alpha) extends the RGB color model with an extra layer of information for opacity. This is the color we actually use in our software. But if the screen does not have a alpha LED, what does it do with that information?

The alpha channel describes how much light can pass trough. So if the opacity is set to `100%` the color will get shown on the screen exactly as the RGB part of the model describes it. If alpha is `0%` then the pixel is fully transparent.

3 circles – each one has a primary color and `50%` opacity.

The inventors named alpha after the Greek letter in the classic linear interpolation formula `(1 - α) * A + α * B`.

## Let’s turn some lights on!

In iOS colors are represented by the `UIColor` class. To create a new color you have to pass the values of the color components encoded as the floating points:

`let color = UIColor(red: 1, green: 0.5, blue: 1, alpha: 1)`

That will give this pinkish color:

Making all values `1` will give white. And if you make the rgb part `0` and alpha `1` you get black.

## How to combine colors?

A simple way to combine colors is by using the linear interpolation formula mentioned before:

```func lerp(from a: CGFloat, to b: CGFloat, alpha: CGFloat) -> CGFloat {
return (1 - alpha) * a + alpha * b
}```

`lerp` stands for linear interpolation and is the usual name this function is given. If you ever seen some code where there was a lot of lerping now you know what that means

If you want to learn more about linear interpolation you can try the lessons from Khan Academy or if you are lazy like me you can watch this amazing talk by Steven Wittens – he has more cool videos on his website:

Let’s lerp some colors:

The first thing we need to do is get the color components back from a `UIColor` unfortunately there are no `red` , `green`, `blue`, `alpha` properties:

```extension UIColor {
func components() -> (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0

getRed(&r, green: &g, blue: &b, alpha: &a)

return (r, g, b, a)
}
}```

Now we can lerp colors:

```extension UIColor {
...

func combine(with color: UIColor, amount: CGFloat) -> UIColor {
let fromComponents = components()

let toComponents = color.components()

let redAmount = lerp(from: fromComponents.red,
to: toComponents.red,
alpha: amount)
let greenAmount = lerp(from: fromComponents.green,
to: toComponents.green,
alpha: amount)
let blueAmount = lerp(from: fromComponents.blue,
to: toComponents.blue,
alpha: amount)

let color = UIColor(red: redAmount,
green: greenAmount,
blue: blueAmount,
alpha: 1)

return color
}
}```

To make a lighter shade of that pink we made before we can call:

`color.combine(with: .white, amount: 0.2)`
Before After

## OK, now let’s have some fun with what we’ve learned!

Let’s make a color picker that also show lighter and darker shades so we can browse the color space more efficiently:

### Step 1: Create a new Playground

Open Xcode and create a new Playground, set the platform to iOS.

### Step 2: Create a View Controller

Create a subclass of `UIViewController` and initialize it’s view with:

```class ViewController: UIViewController {
let width: CGFloat = 300
let height: CGFloat = 500

let screenSize = CGSize(width: width,
height: height)
let frame =
CGRect(origin: .zero,
size: screenSize)

view = UIView(frame: frame)
view.backgroundColor = .white
}
}```

### Step 3: Show the view in the Playground

The first thing we need to do is to import the `PlaygroundSupport` module:

```import PlaygroundSupport

class ColorPicker: UIViewController {
...
}```

Create a instance of `ColorPicker`

`let colorPicker = ColorPicker()`

Set it as the `liveView` of the current Playground page:

```PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = colorPicker.view```

Open the Assistand Editor by pressing `Command` + `Option` + `Return` (`⌘` + `⌥` + `↩`). You should be able to see a white rectangle in the right side of the playground window.

### Step 4: Basic UI

We need one sliders for each color component:

```class ColorPicker: UIViewController {
var redSlider: UISlider!
var greenSlider: UISlider!
var blueSlider: UISlider!

...

let sliderSize =
CGSize(width: width - 2 * padding,
height: 30)

let redSliderFrame =
size: sliderSize)

redSlider = UISlider(frame: redSliderFrame)
action: #selector(didMoveSlider(_:)),
for: .valueChanged)

let greenSliderFrame =
size: sliderSize)

greenSlider = UISlider(frame: greenSliderFrame)
action: #selector(didMoveSlider(_:)),
for: .valueChanged)

let blueSliderFrame =
size: sliderSize)

blueSlider = UISlider(frame: blueSliderFrame)
action: #selector(didMoveSlider(_:)),
for: .valueChanged)

}

func didMoveSlider(_ slider: UISlider) {

}
}```

Note that all sliders call the `didMoveSlider(_:)` method when their value changes. That’s because we have to do the same thing if any of them changes – update the color on the screen.

And if we mentioned that let’s make a view to display our color:

```class ColorPicker: UIViewController {
...

var colorView: UIView!

...

colorView = UIView(frame: colorViewFrame)
colorView.backgroundColor = .white
}
}```

The last line ads a border around the view so we can see the view even if it’s white.

```extension UIView {
layer.borderWidth = 0.5
}
}```

At this point the UI should look like this:

### Step 5: Update the color

```class ColorPicker: UIViewController {
...

func updateColor() {
let redAmount = CGFloat(redSlider.value)
let greenAmount = CGFloat(greenSlider.value)
let blueAmount = CGFloat(blueSlider.value)

let color = UIColor(red: redAmount,
green: greenAmount,
blue: blueAmount,
alpha: 1)

colorView.backgroundColor = color
}

func didMoveSlider(_ slider: UISlider) {
updateColor()
}
}```

`colorView` should update when you move a slider:

```class ColorPicker: UIViewController {
...

...

let totalWidth = width - 2 * padding

y: 430,

}
}
}```

Update shades when the color changes:

```class ColorPicker: UIViewController {
...

func updateColor() {
let redAmount = CGFloat(redSlider.value)
let greenAmount = CGFloat(greenSlider.value)
let blueAmount = CGFloat(blueSlider.value)

let color = UIColor(red: redAmount,
green: greenAmount,
blue: blueAmount,
alpha: 1)

colorView.backgroundColor = color

let t = CGFloat(i) / CGFloat(shadesCount)

color.combine(with: .white, amount: t)

color.combine(with: .black, amount: t)
}
}
}```

### Step 7: Initalize Sliders

Set the value of each slider to `0.5` so we can test if the shades are displayed correctly:

```class ColorPicker: UIViewController {
...

redSlider.value = 0.5
greenSlider.value = 0.5
blueSlider.value = 0.5

updateColor()
}
}```

The screen should look like this:

### Step 8: A finishing touch

Set the background color of the `ColorPicker` to a really white version of the selected color:

```class ColorPicker: UIViewController {
...

func updateColor() {
...

view.backgroundColor =
color.combine(with: .white, amount: 0.9)
}
}
```

## Exercises

1. Add two buttons. When you tap on one it should copy the current color. Add another view that shows color you get by adding equal amounts of the first and second button color
2. Instead of just one view for `0.5` amount show a list similar to how we show shades.
3. Show all colors on hex grid

## Conclusion

It’s easy and fun to create and combine colors and with a bit of common sence you can make pretty stuff