         updateExclamationLayer()
     }
     
-    func updateExclamationLayer() {
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+        
+        if !hasAppeared {
+            actionScrubber = ActionScrubber(action: buildAction())
+        }
+    }
+    
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        hasAppeared = true
+    }
+    
+    // MARK: - Build Action
+    
+    fileprivate func buildAction() -> FiniteTimeAction {
+        
+        let rocketAction = InterpolationAction(from: 0.0, to: 1.0, duration: 2.0, easing: .linear) {
+            [unowned self] in
+            self.rocketView.setRocketAnimationPct(t: $0)
+        }
+        
+        let starsAction = InterpolationAction(from: 0.0, to: 1.0, duration: 2.0, easing: .linear) {
+            [unowned self] in
+            self.starsView.update(t: $0)
+        }
+        
+        let introAction = InterpolationAction(from: 0.0, to: 1.0, duration: 1.0, easing: .linear) {
+            [unowned self] in
+            self.introView.update(t: $0)
+        }
+        
+        return ActionGroup(actions:
+            [introAction,
+             rocketAction,
+             starsAction,
+             makeClockAction(),
+             makeTkAttributesAction(),
+             makeBackgroundColorsAction()]
+        )
+    }
+    
+    fileprivate func makeClockAction() -> FiniteTimeAction {
+        
+        // First page action (move clock on screen)
+        let firstPageAction = InterpolationAction(from: 0.0,
+                                               to: 1.0,
+                                               duration: 1.0,
+                                               easing: .linear) { [unowned self] in
+                                                self.clockView.onScreenAmount = $0
+        }
+        
+        // Second page action (move up and make small)
+        let secondPageChangeTime = InterpolationAction(from: 23.0,
+                                                       to: 24.0 + 4.0,
+                                                       duration: 1.0,
+                                                       easing: .linear) { [unowned self] in
+                                                        self.clockView.hours = $0
+        }
+        
+        let secondPageMoveClock = InterpolationAction(from: 1.0,
+                                                      to: 1.3,
+                                                      duration: 1.0,
+                                                      easing: .linear) { [unowned self] in
+            self.clockView.onScreenAmount = $0
+        }
+        
+        let secondPageChangeSize = InterpolationAction(from: 1.0,
+                                                       to: 0.5,
+                                                       duration: 1.0,
+                                                       easing: .linear) { [unowned self] in
+            self.clockView.size = $0
+        }
+        
+        let getClockPostion = RunBlockAction(handler: {
+            [unowned self] in
+            if self.exclamationOriginY == nil {
+                self.exclamationOriginY = self.clockView.clockRect.origin.y
+            }
+        })
+        
+        let secondPageAction = ActionSequence(actions:
+            [
+                ActionGroup(actions: secondPageChangeTime, secondPageMoveClock, secondPageChangeSize),
+                getClockPostion
+            ])
+                
+        // Third page action (move to bottom)
+        let thirdPageFillWhite = InterpolationAction(from: 0.0,
+                                                  to: 1.0,
+                                                  duration: 1.0,
+                                                  easing: .linear) { [unowned self] in
+                                                    self.clockView.fillOpacity = $0
+        }
+        
+        let thirdPageMoveClock = InterpolationAction(from: { [unowned self] in self.clockView.onScreenAmount },
+                                                     to: 0.55,
+                                                     duration: 1.0,
+                                                     easing: .linear) { [unowned self] in
+            self.clockView.onScreenAmount = $0
+            self.updateExclamationLayer()
+        }
+        
+        thirdPageMoveClock.onBecomeActive = { [unowned self] in
+            self.showExclamation = true
+        }
+        thirdPageMoveClock.onBecomeInactive = { [unowned self] in self.showExclamation = false }
+        
+        let thirdPageAction = ActionGroup(actions: thirdPageFillWhite, thirdPageMoveClock)
+       
+        
+        // Full action
+        let fullAction = ActionSequence(actions: firstPageAction, secondPageAction, thirdPageAction)
+        fullAction.onBecomeActive = { [unowned self] in self.clockView.isHidden = false }
+        fullAction.onBecomeInactive = { [unowned self] in self.clockView.isHidden = true }
+        
+        // Return full action with start delay
+        return ActionSequence(actions: DelayAction(duration: 1.0), fullAction)
+    }
+    
+    fileprivate func makeTkAttributesAction() -> FiniteTimeAction {
+        
+        let action = InterpolationAction(from: 0.0,
+                                         to: 1.0,
+                                         duration: 2,
+                                         easing: .linear) { [unowned self] in
+                                            self.tkAttributesView.update(pct: $0)
+        }
+        
+        let delay = DelayAction(duration: 2.0)
+        return ActionSequence(actions: delay, action)
+    }
+    
+    fileprivate func makeBackgroundColorsAction() -> FiniteTimeAction {
+        
+        let startColors = (UIColor.black, UIColor.black)
+        let spaceColors = (UIColor(red: 0.004, green: 0.000, blue: 0.063, alpha: 1.00),
+                           UIColor(red: 0.031, green: 0.035, blue: 0.114, alpha: 1.00))
+        let clockColors = (UIColor(red: 0.114, green: 0.110, blue: 0.337, alpha: 1.00),
+                           UIColor(red: 0.114, green: 0.110, blue: 0.337, alpha: 1.00))
+        let littleClockColors = (UIColor(red: 0.004, green: 0.251, blue: 0.631, alpha: 1.00),
+                                 UIColor(red: 0.298, green: 0.525, blue: 0.776, alpha: 1.00))
+        let exclamationColors = (UIColor(red: 0.149, green: 0.102, blue: 0.188, alpha: 1.00),
+                                 UIColor(red: 0.149, green: 0.102, blue: 0.188, alpha: 1.00))
+        
+        let colors: [(UIColor, UIColor)] = [
+            startColors,
+            spaceColors,
+            clockColors,
+            littleClockColors,
+            exclamationColors,
+            ]
+        
+        var actions = [FiniteTimeAction]()
+        
+        for (startColors, endColors) in zip(colors, colors.dropFirst()) {
+            
+            let action = InterpolationAction(from: 0.0,
+                                             to: 1.0,
+                                             duration: 1.0,
+                                             easing: .linear) {
+                                                [unowned self] in
+                                                let top = startColors.0.lerp(t: $0, end: endColors.0)
+                                                let bottom = startColors.1.lerp(t: $0, end: endColors.1)
+                                                self.backgroundColorView.setColors(top: top, bottom: bottom)
+            }
+            actions.append(action)
+        }
+        
+        return ActionSequence(actions: actions)
+    }
+    
+    // MARK: - Update ExclamationLayer
+    
+    fileprivate func updateExclamationLayer() {
         
         CATransaction.begin()
         CATransaction.setDisableActions(true)

import UIKit
import TweenKit

class OnboardingExampleViewController: UIViewController {
    
    // MARK: - Properties
    
    let cellTitles: [String] = [
        "",
        "This is a rocket",
        "This is a clock",

        return collectionView
    }()
    
    fileprivate let pageControl: UIPageControl = {
        let pageControl = UIPageControl(frame: .zero)
        return pageControl
    }()
