In the real world, as the sun rises and sets, the sky does not uniformly change color and brightness along with it. Instead, it tracks a wide range of colors and shades, from the full(ish) blue of day to the deep black of night.
It would be quite tedious, if not exceedingly difficult, to create multiple static gradient backgrounds, one for every stage of a sky's day, and then swap these throughout. And while this swapping operation wouldn't be tough to conceal, it would both require an inordinate number of images, and most likely, or more importantly, not appear terribly natural.
CGGradient constituted from a host of colors, themselves derived from predetermined RGB values, could be created on the fly, on the minute even, and updated across a day-long continuum.
There's a convenience init for
UIColor which gives one access to the RGB values as
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
Using the current time, and with as much granularity as one would like, the individual RGB values could be adjusted, new
UIColor's created, then those used to redraw a gradient, and the resulting texture applied to an
The sky gradient will need a top and bottom color and a transition point between the two, which for starters will be half the height of the scene.
The transition point can change position over time as well, so within the gradient the color mixing would move up and down.
There will need to be a master list of all the forty-eight (twenty-four per section of the gradient) colors and their corresponding red, green, and blue values. The
SkyBackground class will eventually need to reference this list to establish its colors at any particular moment.
0500 TOP: UIColor(r:0,g:110,b:0) BOTTOM: UIColor(r:0,g:110,b:0) 0600 TOP: UIColor(r:75,g:75,b:100) BOTTOM: UIColor(r:200,g:130,b:160) 0700 TOP: UIColor(r:120,g:120,b:190) BOTTOM: UIColor(r:230,g:175,b:210) 0800 TOP: UIColor(r:30,g:30,b:0) BOTTOM: UIColor(r:0,g:110,b:0) 0900 TOP: UIColor(r:60,g:60,b:92) BOTTOM: UIColor(r:0,g:110,b:0) and so on...
Ultimately, the master list of hours/colors will be a dictionary of tuples.
typealias RGBValue = (r: CGFloat, g: CGFloat, b: CGFloat) var topColors: [Int:RGBValue]!
So, if we have a color, composed of RGB values, assigned to the hour it is, and another color assigned to the hour that it will be, then we've got a start and a finish. Now, each RGB value for either
UIColor in the gradient, has some knowable distance to travel during the hour: between its current and next point.
These swatches of
bottomColor, variables which will be used in the gradient creation portion of the function
drawSkyTexture, demonstrate the difference between the RGB values at 6:00am and 7:00am.
And this composite shows the two resultant gradients of 6:00am 7:00am.
To walk through my understanding of the calculations needed, I'll start with some random colors.
thisHoursColor = UIColor(r:20,g:20,b:45) nextHoursColor = UIColor(r:50,g:60,b:90)
Over the course of the hour, all three values need to increase or decrease so as to arrive at the
r: 20 -> 50
g: 20 -> 60
b: 45 -> 90
Starting with red, we'd subtract the
currentValue from the
targetValue, in this case that would be 50 - 20 = 30. Then divide the difference by the number of minutes in an hour, 30 / 60 = 0.5, which results in the multiplier for any particular
If we take any minute of the hour (I'll use the 24th here), and multiply it by 0.5, then we'll have the correct amount by which to increment the current hour's red value.
24 * 0.5 = 12
20 + 12 = 32
32 / 255 = newRedValue
This will work backwards as well. If the
nextHoursColor happened to be 10 as opposed to 50?
r: 20 -> 10
10 - 20 = -10
-10 / 60 = -.16666667
00:24 -> 24 * -.16666667 = -4
20 + -4 = 16
16 / 255 = newRedValue
Now we'd run it all again with the remaining RGB values for
Onto the heavy lifting...