Using Logic to Control Animations in Pixate


Pixate is fantastic. Since its launch, we’ve been using it to create dynamic interactions and prototypes for clients. We presented our first demo to a client two days after we first created an account, which is a testament to just how easy it is to learn.

Prototyping complex interactions is Pixate’s wheelhouse. One-to-one interaction, custom dynamic animations, and gestures are very quick and easy to set up. Conditionals also allow for some more programmatic behavior. Prototypes can act differently in different “states.”

Figure 1.1 | The finished prototype in action.

In this blog post, we will demonstrate creating an iOS-like multitasker to switch between three apps, using conditionals to sort the apps by most recent.

Setting Up

First, we’ll set up all of the layers for the prototype. The basic interaction will be as follows:

  • A list of three apps is presented
  • You can scroll through the list and pick an app by tapping it
  • That app will zoom full screen, and you can drag up anywhere to shrink the app back down
  • The most recent app will go to the beginning of the list

There are two main components of this prototype: the tray of apps which you select from and the app screen which scales to full screen.

Let’s first focus on the tray of apps.

You can see our Pixate comp in the screenshot below. There is a layer labeled “Scroll Layer” with a Scroll interaction; Clipping is turned off and Paging is turned on. We made it just larger than a zoomed out app and placed it in the center of the screen. Inside that, we added a layer named “Snapper” containing the three apps, each Scaled to 0.48x.

Figure 1.2 | The “Snapper” layer is pictured in green so that it’s visible, the “Scroll Layer” is outlined in yellow. The measurements below are important for conditionals later.

There are three apps and three positions for apps in the switcher. By default, the first app is in position 1, which has an x value of -80pt, “app2″ has an x value of 80pt, and “app3″ has an x value of 240pt.

Sorting the apps

It would be pretty easy to have these apps Scale up on Tap and call it a day. However, in cases like a multitasker, the order of elements is an important part of the interaction. Conditionals will help us sort the apps.

First off, we add a Tap interaction to each app in the tray, then add a Move animation to each app for all of the Taps.

If an app is Tapped, it is now the most recent app; no matter where it is, it should move to the first position. So to each of the apps we add a Move animation Based on its own Tap, and set Left to -80. Because these Moves will happen after the app finishes zooming full screen, we set the Duration to 0 and the Delay to 0.3, which will be the duration of the zoom.

When another app is Tapped (meaning an app that isn’t the one animating), there are two scenarios:

If the app being animated is in the first position, and the Tapped app is in the second position, the first app should move to second position. If this is confusing, look at the image below for clarification.

We add a second Move animation to “app1″ and add a Condition: “app1.x == -80″, setting Left to 80, which is the second position.

Figure 2.1 | Here we create a Move animation for “app1″ Based On “app2,” where “app1″ is in the first position

If the app is in the second position and an app in the third position is Tapped, then the first app should move to the third position. We click the “+ CONDITION” button at the bottom of the ANIMATIONS panel to add another condition. With this conditional, we need to verify that the app animating is in the second position and the Tapped app is in the third position: “app1.x == 80 && app2.x > -80″, and then set Left to 240, the third position.

Figure 2.2 | We are still animationg “app1.” “App1″ is in the second position and “app2″ is in the third position. “App2 ” gets Tapped, so “app1″ should move over to the third position.

Finally, if an app is in the third position and the app in the second position is Tapped, we do nothing! The only way for an app to leave the third position is getting Tapped itself.

Create Move animations for each layer based on its own Tap interaction, along with two other Move animations based on the other two apps’ Tap interactions. Keep track of the conditionals to make sure that they respond properly to each Tap, moving to the correct positions.

The screenshots below are from the ANIMATIONS panel of “app1.” The conditionals are almost identical for both of the apps that aren’t “app1.” The differences are highlighted in red.

Figure 2.3 | These screenshots are simplified to show only the Move values changed.

For “app2,” the second and third animations would be “Move App1″ and “Move App3.” “App3″ would have “Move App1″ and “Move App2″ animations which would look very similar. When this process is finished, each of the three app layers should have three Move animations, one to respond to Taps for each app.

There is one more detail: the “Snapper” layer needs to reset its position, since the user may have scrolled to any of the three positions. Unfortunately, Pixate doesn’t have a Scroll To animation yet. To get around this, we set the Left value to -1000, then delay a tenth of a second before a second Move to 0. It’s a bit of a hack, but it gets the job done.

Zooming

Now we are done sorting the apps, but they need to zoom full screen when they are tapped. We’ll add a layer and put each of the app screens in it. We then Fade in the correct screen when its corresponding app is Tapped. Here is the final structure of the layers:

Figure 3.1 | “Fullscreen App” is the container layer, the “Scaler” creates the zooming effect.

We added a vertical Drag interaction to the “Fullscreen App” for shrinking the app back down. The “Scaler” layer scales the screen layers on drag up of the “Fullscreen App” layer. We only want the apps to scale, not move up on drag, so we add a Move Continuously with rate animation to the “Scaler” layer. This moves the “Scaler” layer down at the same rate you drag the “Fullscreen App” layer up.

We then add a Scale animation to the “Scaler” layer to shrink the apps down as you drag up. We use Scale Continuously to final value with a final value of 0.48, the same scale as the app layers in the tray. The range is from 0 to -100. We also add Scale animations for Taps on each of the apps, going to 1x Scale with a Duration of 0.3s, matching the delay of the apps moving in the tray.

Figure 3.2 | “Fullscreen App” is colored blue so you can see it fade in and out. The app screen is the “Scaler” layer.

We add Fade animations for showing the “Fullscreen App” layer on Tap of each app in the tray. We also add a Fade for hiding on Drag release of “Fullscreen App” with a conditional that “fullscreen_app.y < -100.” This ensures that the zoomed app will disappear if the user drags up at least 100pt.

We also add Fade in animations to the app screens for the Taps on their respective apps in the tray, and Fade out animations on Drag release of the “Fullscreen App” with the same conditional, “fullscreen_app.y < -100.”

Loose Ends

The prototype is pretty functional at this point, but there are some loose ends that need to be tied up. The fullscreen apps need to return to fullscreen if the user doesn’t drag up far enough, and everything needs to reset. If you drag up and release before dragging up 100pt, the app screen should return to full size, and when you drag it far enough, it should animate the rest of the way on release.

Figure 4.1 | The app snaps to full screen if dragged less than 100pt up, otherwise it snaps down.

To finish these details, we add a Move animation to the “Fullscreen App” layer to snap the y position back to 0 on Drag release, with a conditional based on whether the app was shrunk enough to determine the timing. We also add a Scale animation to the “Scaler” layer based on Drag release of the “Fullscreen App” layer, using the same “fullscreen_app.y < -100″ conditional. Scale should be set to 0.48. We need to add another conditional in case the user didn’t drag far enough, so we hit the “+ CONDITIONAL” button and change Scale to 1.

After wrapping up these loose ends, the prototype works!

Figure 4.2 | You can see the apps reorder in the list. The last app becomes first, then the second becomes first.

Wrapup

Pixate isn’t a programming language, but you can achieve some convincing results using conditionals. Putting a functional prototype in the hands of your clients is extremely valuable. Conditionals take your prototypes to the next level by adding dynamic functionality beyond just visuals and animation.

To play with this prototype yourself, you can click this link on your phone (or tablet): http://pixt.io/p3a47dfe6567f

Tweet us @truthlabschi and show us your conditional-driven Pixate prototypes!

Originally published at blogs.truthlabs.com on January 9, 2015.