Blue Skies

Patrick Perini
The App Cookbook
Published in
4 min readAug 26, 2015

Wednesday, August 19th, 2015

Ingredient

Flight Anxiety. As a sufferer from flight anxiety, Alec often spends time focusing on flight radar websites as a cross between a meditation tool and comforting reminder of the number of planes safely in flight.

Given that many apps already present real-time flight radar information, we decided to focus on using the flight-in-motion animation as a focus tool, and pair it with a typical anxiety-relief breathing exercise.

Recipes

Paper Planes, in flight between Real Airports

Paper planes and a minimal map create a relaxing visual that is heavily divergent from utilitarian flight-tracking apps.

A calming and subtle blue color palette entices the user to relax through the experience.

All airports, seen as pulsing dots, are the locations of actual airports, and are algorithmically chosen based on proximity. The airport data was sourced from the OpenFlights project. The minimalistic map was designed in Mapbox Studio, and hosted by Mapbox. To use it, we created an MKMapView subclass, like so:

private let urlTemplate = "https://api.mapbox.com/v4/\(mapID)/{z}/{x}/{y}.png?access_token=\(token)"required init(coder: aDecoder: NSCoder) {
// ... setup
let tileOverlay = MKTileOverlay(URLTemplate: urlTemplate)
tileOverlay.canReplaceMapContent = true
self.addOverlay(tileOverlay, level: .AboveLabels)
}

The animation is all based on the UIView.animateWithDuration() methods, taking advantage of the fact that an MKAnnotation’s coordinate property is inherently animatable.

To create a single method that would animate all of the necessary properties to create a plane in flight, first we had to expose our AnnotationView’s Annotation’s coordinate as an animatable property on the AnnotationView.

class PlaneView: MKAnnotationView {
// Assumes annotation is `Plane: MKAnnotation`.
var coordinate: CLLocationCoordinate2D {
get { return self.annotation.coordinate }
set { (self.annotation as! Plane).coordinate = newValue }
}
}

Then, within the PlaneView, we were free to create a method that would animate a series of properties in concert. To create the desired effect, we had to animate:

  1. The coordinate of the PlaneView, from start to finish, over 100% of the duration.
  2. The scale of the PlaneView, increasing over 50% of the duration, peaking in the middle, then decreasing over the remaining 50%. This created an arcing effect, visually.
  3. The opacity of the PlaneView, increasing over the initial ~33% of the duration, remaining at full opacity for ~33% of the duration, and then decreasing over the final ~33% descent.

We also had to angle the PlaneView’s rotation so that it would always be headed toward its destination airport. To determine the correct heading, we used this geometrical snippet:

extension CLLocation {
function headingToLocation(location: CLLocation) -> CLLocationDirection {
let lat1 = CGFloat(self.coordinate.latitude) *
CGFloat(M_PI) / 180.0
let lon2 = CGFloat(self.coordinate.longitude) *
CGFloat(M_PI) / 180.0
let lat2 = CGFloat(location.coordinate.latitude) *
CGFloat(M_PI) / 180.0
let lon2 = CGFloat(location.coordinate.longitude) *
CGFloat(M_PI) / 180.0
let latDiff = lat2 - lat1
let lonDiff = lon2 - lon1
var angle = atan2(lonDiff, latDiff) * CGFloat(180.0 / M_PI)
if angle < 0 {
angle += 360.0
}
return CLLocationDirection(angle)
}
}

An Exercise in Breathing

The most common response to flight anxiety that we could find was controlled breathing exercises. Progressively longer guided breathing cycles calm the mind and relax the body. Many apps which achieve this do so by showing a countdown to each inhale & exhale, which seemed to us counter-intuitive.

Blue Skies opts for less explicit timer, and guides you through your breathing cycles in time with the flights. Users breath in during a flight’s ascent, and out during its descent. With each flight, we increase the time gradually, to slow users’ breathing.

As a flourish on the experience, relaxing music plays slowly in the background.

Calming Airport Facts

At the end of each cycle, Blue Skies presents a calming fact about anxiety, flight, and airports. It presents some reassuring statistical facts, all designed to be presented positively. For example, “There is a 1-in-11-million chance of dying in a flight” was restructured to be “Fewer than 0.000003% of all flights have resulted in an accident. All is well.”

Challenges

Just Fake It

Early on, we sought access to a real-time dataset of flight information. Some cursory research proved that this existed, but was priced obtusely and access seemed to be reserved for corporate entities only. After a quick consultation, we decided to push forward with design and development, and, if needed, fake the data until release.

Pick a Path

This turned out to be an ideal approach, because we soon after approached a fork in our design process. We agreed that we could either design a beautiful and accurate flight tracker or a well-defined anti-flight-anxiety tool, but a compromise would be subpar. To make a decision, we consulted with some potential users, and decided that a focus on breathing was more important than accurate flight data, and so we opted to build the latter.

Make it Work, then Make it Fast

Map loading always tends toward the slow-side, especially when using a custom tileset. Since there was no way of drastically increasing speed, and the drop-loading that plagues MapKit was too jarring an experience for a zen-focused app, we decided to add a cross-fade between flights, to allow the map to load.

Chefs’ Notes

We were overall very happy with the results. However some planes seem to fly in reverse and we promise, no commercial airlines do so.

--

--