We may earn a commission for purchases using our links. Learn more.

Since BlackBerry 10 Cascades came out a little less than two years ago there have been three major releases of tools and APIs for developers to play around with. And I, like many weekend coders, have spent most of my time trying to use those tools for their somewhat obvious purposes. But as the tool releases have slowed and we have all had time to gain some mastery of the provided tools it’s time to for us developers to create some custom user interfaces and experiences.

We are already starting to see developers expand the native tools with some of their apps such as Blaq, Sochi 2014, and Tilt. A few weeks ago, I shared a sample code base to create a similar UI/UX to the Sochi 2014 app and today I have another sample that I call “Fancy Transitions.”

Before I go any further, I would like to warn everyone that this sample may not be for a novice developer. I have to use quite a bit of math and I am only showing about half of the code in this article. If you follow what I have posted in this blog, the parts I don’t show should make sense as well.

Fancy Transitions shakes up the typical navigation flow where one page slides over top the other page. Rather than a simple slide, I’ve changed it so the page the user is currently on slides to the left and goes back into the screen. At the same time, the new page appears to come up from the back and slides around the right side of old page and becomes the new top. As illustrated below this figure:

This is all accomplished using some well timed animations and a built-in function called swap(). Let’s first take a look at the animations involved. And let’s think of the red Container and blue Container independently. So first the red Container needs to go left, then right, and appear to fall back:

ParallelAnimation {     animations: [         ScaleTransition {             toX: 0.85             toY: 0.85             duration: 400         },         SequentialAnimation {             animations: [                 TranslateTransition {                     toX: -320                     duration: 400                     easingCurve: StockCurve.CubicInOut                 },                 TranslateTransition {                     toX: 0                     duration: 400                     easingCurve: StockCurve.CubicInOut                 }             ]           }     ] }

Then the blue Container needs to go right, then left, and appear to come forward:

ParallelAnimation {     animations: [         ScaleTransition {             toX: 1.0             toY: 1.0             duration: 700         },         SequentialAnimation {             animations: [                 TranslateTransition {                     toX: 400                     duration: 400                     easingCurve: StockCurve.CubicInOut                 },                 TranslateTransition {                     toX: 0                     duration: 400                     easingCurve: StockCurve.CubicInOut                 }             ]         }     ] }

A few more notes about the two code snippets, I have applied an easing curve to each to give a more fluid look to the animation. Also, notice that the duration of each animation line up. The blue scaling is the only one that doesn’t total 800ms to give a better “snap” effect. Feel free to tweak these to your own liking.

Now we need to have these two Containers swap places midway through the animations so the blue is on top of the red. I have accomplished this with a well-timed swap function inside a QTimer:

QTimer {     id: swapTime     interval: 500     onTimeout: {        mainCont.swap(0, 1)        swapTime.stop();      } }

This is a simple function that swaps the positions of two Containers. And since I have these two Containers in a DockLayout the swap changes their position relative to the screen depth.

So if we wanted to control this effect with a button we’d have something like:

 Button {     onClicked: {         swapTime.start();         redGoBackRight.play(); //assume red animation id was redGoBackRight         blueGoForwardRight.play() //assume blue animation id was blueGoForwardRight     } }

Tweaking these animations we can easily get the reverse effect, I have done that in the sample code so I won’t explain it here. But buttons in apps are not what BlackBerry 10 is all about, we use SWIPES! And since there is no built in swipe gesture, let’s go ahead and create one.

First at my main Page level I have defined two variables “startPosition” and “finalPosition”. And then in the main Container level I define an onTouch signal like the following:

onTouch: {             if (event.isDown()) {                 startPosition = event.windowX;                       }             if (event.isUp()) {                 finalPosition = event.windowX;                 var directionSwipe = finalPosition - startPosition;                 var enoughSwipe = Math.abs(directionSwipe)                 console.log(finalPosition + ", " + startPosition)                                  if (enoughSwipe > 150) {                     if (directionSwipe > 0) {                         console.log("back swipe occured")                         swapTime.start();                         redGoBackLeft.play();                         blueGoForwardLeft.play()                                          } else if (directionSwipe < 0) {                         console.log("forward swipe occured")                         swapTime.start();                         redGoBackRight.play();                         blueGoForwardRight.play()                     }                 }         } }

So what I have happening in this code is as soon as the user presses down on the screen the startPosition is recorded. Then as soon as the user lifts up their finger the finalPosition is recorded and some logic happens.

To determine the direction, I take the difference of the two positions. To determine if the user has moved their finger in a swiping like gesture, I take the absolute value of that difference. From there if the absolute value, the variable I named enoughSwipe, is greater than 150 pixels the logic continues. If not then not enough of a swipe occurred to register as a swipe. Now looking at the direction of the swipe, if the difference is greater than 0 the swipe is what we think of as a “back swipe” and if it is less than 0 it is what we would think of as a “forward swipe.”

Along the way I have a few console.log() so I can see what is happening in my console in Momentics. This onTouch needs to be a bit expanded to account for another swipe once the blue screen in on top (need different animations to occur) and if you take a look at the sample I have done that for you as well.

Finally, this brings me to what you see in the video at the top of this post. I have taken the methods explained above and applied them to a real user interface to show it off in a more realistic scenario. I hope you enjoyed this write up, please check out the sample in github, and as always feel free to ask questions or show some love in the comments below.

More information / Download Fancy Transitions Sample code from Github

Read more