3. Sliding
Awesome work—our first animated transition is up and running! Let’s move on to the
next one: an extremely common mobile interaction for master-detail pages, such as our Spots and Stars listings. On mobile devices,
it’s common for the detail page to slide in from the right side of the screen, as if it
had been hiding there the whole time. When the user returns to the master page, the
transition works in reverse, providing the user with a clear visual model of the app’s
information hierarchy.
Creating a slide or “push” transition is very easy now that we’ve learned to fade—we
just need to update our CSS animations. To perform a push, we need to animate the current
page off the screen to the left while simultaneously moving the new page in from the
right. It’s a bit trickier than just fading, but only just.
First, we’ll create an animation for moving the current screen away. We’ll use
the -webkit-transform property to animate the <div> element’s horizontal location via the translateX command.
Note:
If you’re unfamiliar with CSS3 transforms, don’t worry. They’re simply an easy way
to act on the position and shape of an element as its rendered. In addition to the
translateX transform we’re using here, you also have access to translateY
(unsurprisingly), translate (for both X- and Y-axis translation), as well as rotate, skew, and scale
functions. For the full list and examples of how they can be used, check out the W3C’s CSS 2D
Transforms Module.
The screen starts at X=0 and then moves out of sight by translating to -100%. This is
a nifty trick. If we translate by a negative amount, the screen moves to the left. By
moving 100% to the left, the screen is gone. Once we’ve defined the keyframes, we can then
assign the animation to the .push.out selector (remember that our
existing <out>
<class> provides a default duration and timing function
for our animations):
listing 13. stylesheets/transitions.css (excerpt)
/* Screen pushes out to left */ @-webkit-keyframes outToLeft { from { -webkit-transform: translateX(0); } to { -webkit-transform: translateX(-100%); } } .push.out { -webkit-animation-name: outToLeft; }
|
Similarly, we’ll define an animation for the new screen to fly in from the right,
taking the place of the old one:
listing 14. stylesheets/transitions.css
(excerpt)
/* Screen pushes in from the right */ @-webkit-keyframes inFromRight { from { -webkit-transform: translateX(100%); } to { -webkit-transform: translateX(0); } } .push.in { -webkit-animation-name: inFromRight; }
|
For the JavaScript, we could recycle the transition function we made for the fade,
calling it transition_push(), for example. We’d then just need to
change all the instances of fade to push. And then
again for flip when we want to implement flip transitions, and so on.
On second thoughts, it would be nicer to pass the transition type in as a parameter to our
transition() function:
listing 15. javascripts/ch4/09-slide.js (excerpt)
function transition(toPage, type) { ⋮ toPage .addClass("current " + type + " in") .one("webkitAnimationEnd", function(){ fromPage.removeClass("current " + type + " out"); toPage.removeClass(type + " in"); }); fromPage.addClass(type + " out"); }
|
Now when we create CSS animations for a new transition, they’ll automatically be
available to use in our script. We just pass the new name in:
transition(nextPage, "push");
We’d like the push transition to be used for navigating down from a list to a detail page, so we need to add some new click handlers for the list
items:
listing 16. javascripts/ch4/09-slide.js (excerpt)
$("#spots-list li").click(function(e){ e.preventDefault(); transition("#page-spot", "push"); }); $("#stars-list li").click(function(e){ e.preventDefault(); transition("#page-star", "push"); });
|
With this, the detail pages will slide in from the right to replace the list pages. As
we outlined earlier, though, what we’d also like is for the reverse to occur when the user
is navigating back up the app’s hierarchy. Next up, we’ll look at
building out that functionality, and, while we’re at it, adding support for going
“back.”