Motion is Emotion: Prototyping Microinteractions for Apple Watch with Framer Studio

Static wireframes are perfect for getting your information architected. But when it comes to bringing your app to life, you have to prototype the motion. Why? Because motion is emotion. And you can quote me on that.

Whether a coiling bar, a fluidic zoom, a physically realistic bounce, an amusing animation – movement brings apps to life. And interestingly enough, there are countless ways to design for even the simplest of interactions.

Prototyping microinteractions will be even more important when you’re designing for small interfaces like Apple Watch. And that became apparent to me the day we anxiously huddled around our conference room here at grandcentrix to watch Apple present its latest children to the world:

We conceived, designed and developed Apple Watch as a completely singular product. You know, you can’t determine a boundary between the physical object and the software.

So how do you blend the boundary between the physical and digital?

Forget about those ultra long text descriptions of complex transitions like this:

On load: The individual bars representing a degree fly into view from the left with such momentum that they spring back and forth until coming to rest in their final position. The appearance of each bar is staggered with the bottom bar appearing first in such a way that the entire column of bars moves like a Slinky.

Start using prototyping tools like Framer Studio or Origami with Quartz Composer or even Keynote to show what you mean.

By focussing on motion, you can

  • suggest hierarchy or relationship between elements or views
  • provide feedback for some tap, press, swipe or dial
  • show a state change
  • amuse the user

I took out Framer Studio for a test drive, devouring all the documentation and experimenting with the example projects.

But I’m no coding ninja. I told my colleague, Mark, about my plans and he got excited about the idea. He not only pulled out the big guns when it came to the fancy functions, he also gave me great tips for writing clean code.

This is what we prototyped.

Try it out here.

And this is how we did it:

Step 1: Ideate and feature-focus

Lately at grandcentrix, we’ve been working on Smart Home apps.

And as we tuned in to Apple's presentation of their Watch like a group of lottery ticket holders, I couldn’t help but imagine myself kicking back on my sofa at home on a cold Winter’s day and upping the heater with a few swipes of my Apple Watch.

So for the prototype, I formulated the following “mission statement”:

The TempControl Watch app lets you change the temperature in your home with a few swipes.

I had a few ideas and assumptions upon which I based my work:

  • In its most basic form, a physical thermostat just has two controls: on/off and temperature. Assuming Smart Home climate control is always on, all you need to show on your wrist is the actual programmed temperature.
  • The Digital Crown can be used to change the temperature. But swiping up to raise the temperature and swiping down to lower it seems intuitive enough.
  • Since the display is so small, swiping it to change the temperature means you’ll cover the display. That would make a slider control a bit pointless.

Step 2: Sketch / Wireframe

I wanted to keep the UI minimalistic, so I sketched out its two main components and thought about all the variation just those components could have:

  1. The temperature gauge: In number of degrees? With or without half degrees? With or without “C” or “F” to suggest celsius or fahrenheit? How big or small should the font be?

  2. A background image: Just the number of degrees alone might be a bit boring. I wanted to add visual appeal and provide interaction feedback with a sort of background coloring that corresponds to a temperature (blue for cold, red for hot). But should the background only display the actual temperature color or a gradient?

Step 3: Prepare basic assets

I quickly created a layout using Sketch and exported the background image as a PNG.

The temperature gauge is just a text element that would be easy enough to do in CSS:

labelLayer = new Layer  
labelLayer.backgroundColor = "transparent" = {  
    "font-family":"Helvetica Neue"
    "text-shadow":"3px 3px 15px black"

Step 4: Prototype primary interaction

First off, we tackled the primary interaction: swiping up to raise the temperature gauge by a degree or two, and swiping down to lower it. We based the swipe interaction on Framer Studio’s example of a swipe animation.

So we created an invisible layer that could react to our swipe gestures.

# Create hidden draggable layer
draggable = new Layer(watchFaceBounds)  
draggable.backgroundColor = "transparent"  
draggable.draggable.speedY = 10;  
draggable.draggable.speedX = 0;  

We declared some variables for the invisible draggable layer and the temperature gauge.

startY = 0  
temperature = 21  
movingTemp = 0  
maxTemp = 45  
minTemp = 8  

Then Mark wrote a function to update the displayed temperature and change the height of a semi-transparent overlay to fake the appearance of some of the background image fading out.

# Function to update the temperature display
updateTemperature = (temp) ->  
    labelLayer.html = temp + "°"
    percent = (temp - minTemp) / (maxTemp - minTemp)
    darkOverlay.height = (1 - percent) * watchHeight    
# Update the display

We wrote some basic events for the main swipe interaction. At first, the temperature kept rising whenever we swiped the invisible draggable layer. So Mark went analog and sketched out how the function should work before whipping up the following nifty lines of code for the dragging events corresponding to the swipe gesture. The gesture had to work only within the limits of the watch display and within a certain temperature range (I’ve never come across air conditioning that’ll shiver you up with 8° and a heater that’ll sweat ya up to 45°).

# Handle events
draggable.on Events.DragStart, ->  
    startY = event.y

draggable.on Events.DragMove, ->  
    if event.y > watchY && event.y < (watchY + watchHeight)
        distanceMoved = Math.round( (event.y - startY) / 50 )

        movingTemp = temperature - distanceMoved

        if movingTemp > maxTemp
            movingTemp = maxTemp

        if movingTemp < minTemp
            movingTemp = minTemp


draggable.on Events.DragEnd, ->  
              y: 194
          time: 0.1    
    startY = null
    temperature = movingTemp

So we got the main interaction working.

Try it out here.

Step 5: Experiment with secondary interactions

After our temperature gauge “felt” good, we turned our attention towards the background image.

At first, we got the semi-transparent layer raising and falling in sync with the temperature change.

Go ahead. Swipe it.

But the background image was static and kinda boring.

So we ditched that and took a look at Framer Studio’s example of a staggered animation.

We declared some variables for the appearance and animation of the background temperature “bars”.

rows = 29  
barSize = watchWidth  
barMargin = 10  
barCurve = "spring(600,10,60)"  
startDelta = watchY  
barColor = "#64eb66"  

Then we adapted the map function to our needs and tweaked the variables until we liked the animation.

bars = [1..rows].map (b) ->  
    bar = new View
        y: watchHeight - (b * barMargin - barMargin)
        x: -100
        width:  barSize 
        height: 4
        opacity: 0
        backgroundColor: barColor

    bar.states.add 'fadein',
        x: 0
        opacity: 1

    bar.states.animationOptions =
    curve: barCurve

    bar.states.animationOptions.delay = 0.05 * b
    bar.states.switch 'fadein'

And we ended up with this:

Obviously, there are tons of ways you can tweak the movement and appearance of the bars. And it's quick and easy enough to do in Framer with a little help from your friends.

A happy end

Building the prototype was a blast. It proved to me:

  • Code doesn’t have to be scary. If you don’t understand something, get help from someone who does.
  • Tweaking just a few variables and seeing instantaneous results without having to create a build saves so much time.
  • Prototyping microinteractions with Framer Studio is fast and fun.
  • Prototyping with a teammate is the best way to learn and grow.

Download sample files or view on GitHub.