Animating Windows

 

This is an excerpt from the upcoming book Programming Windows 8 with HTML5 for Dummies

-----------------------------------------

The component animation that is inherent to HTML5 and even JQuery is not only supported in Metro, it is encouraged. The navigation model is new through, and there are bits in WinRT that make it easy to animate.

 

Everything for page and content level animation (sometimes called Transitions) is covered by WinJS though, and you can find it in WinJS.UI.Animation. Here is a sample of what you can get there:

 

  • Page transition: Animates the contents of a page into or out of view.
  • Content transition: Animates one piece or set of content into or out of view.
  • Fade in/out: Shows transient elements or controls.
  • Crossfade: Refreshes a content area.
  • Expand/Collapse: Shows additional inline information.
  • Reposition: Moves an element into a new position.
  • Show/Hide popup: Displays contextual UI on top of the view.
  • Show/Hide edge UI: Slides edge-based UI into or out of view.
  • Show/Hide panel: Slides large edge-based panels into or out of view.
  • Add/Delete from list: Adds or deletes an item from a list.
  • Add/Delete from search list: Adds or deletes an item from a list when filtering search results.
  • Badge update: Updates a numerical badge.
  • Start/End a drag or drag-between: Gives visual feedback during a drag-and-drop operation.

 

That’s a lot of animating. Don’t feel like you have to animate everything to get into the store. I would, though, seriously consider animating page and content transitions in order to show that you have given a nod to the realities of the Metro design language.

 

Page level transitions

 

Compared to dealing with the GestureLibrary, page transitions are a snap. In WinJS.UI.Animation you will find an enterPage function, and an exitPage function. They both do about the same thing, they just need to be run at different times in the page lifecycle.

 

Both methods take an element object and an offset object, and return a Promise. While an element is in transition you can’t act on it, so you want to use the promise to delay any page functionality (like removing an element) until the animation is over.

 

WinJS.UI.Animation.enterPage(content, startingPosition).done();

 

The content is the element or elements that you are animating. This seems counterintuitive but I believe it is set up this way so that you can choose to animate only certain parts of the page, and still have content level control later. The enterPage function is designed to be used with the Navigation libraries we talked about in Saying Hello World.

 

The startingPosition is exactly what it looks like. It is where the content collection should start before the animation occurs. You can pick a place on the page and pass in a JavaScript array of the location to make this happen. The recommendation is, though, to use “undefined” for the default start location.

 

The done of course represents the Promise that is being returned by the function. When the animation is done, the rest of the code will be run, and not until the animations is done. This is to prevent the entire UI from locking up while an animation is being performed.

 

To set up an animated page sequence, try the following steps:

 

  • Create a blank JavaScript Metro project.
  • Make a new directory called “pages” for the pages we are going to transition amongst.
  • Add three pages. Right click on the pages directory and select Add New Item. Select Page Control. Do it three times. I named mine firstpage, nextpage and thepageafter.
  • In default.html, add a content div replacing the paragraph tag, like this:

 

<body>
    <div id="content"></div>
</body>

 

  • In the default.js file, add a navigated event handler.

 

WinJS.Navigation.addEventListener("navigated", function (eventObject) {
        var url = eventObject.detail.location;
        var content = document.getElementById("content");
        WinJS.Utilities.empty(content);
        eventObject.detail.setPromise(WinJS.UI.Pages.render(url, content, eventObject.detail.state).then(function () {
            WinJS.Application.sessionState.lastUrl = url;
        }));
    });

 

  • Also, navigate to the first content page in the onactivated event. This will get things started.

 

app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            args.setPromise(WinJS.UI.processAll().then(function(){
                return WinJS.Navigation.navigate("/pages/firstpage.html");
            }));
        }
    };

 

  • The firstpage.html, nextpage.html, and thepageafter.html give the header and main sections a ID. While you are in there, add a button for navigation.

 

<body>
    <div class="firstpage fragment">
        <header aria-label="Header content" role="banner" id="header">
            <button class="win-backbutton" aria-label="Back" disabled></button>
            <h1 class="titlearea win-type-ellipsis">
                <span class="pagetitle">Welcome to firstpage</span>
            </h1>
        </header>
        <section aria-label="Main content" role="main" id="main">
            <p>Content goes here.</p>
            <button id="nextPage">Next Page</button>
        </section>
    </div>
</body>

 

Add a transition function to firstpage.js, nextpage.js and thepageafter.js that navigates to the shosen page and uses the animation.

 

function transition() {
        WinJS.UI.Animation.exitPage([[header],[main]], null).done(
            function () {
                WinJS.Navigation.navigate("/pages/nextpage.html");
            });
    }

 

This will be different for each page! It should navigate to the page you want to go next.

 

  • Finally, in the firstpage.js (and the others) and change the ready event to fire the new transition function when the click event occurs.

 

WinJS.UI.Pages.define("/pages/firstpage.html", {
        // This function is called whenever a user navigates to this page. It
        // populates the page elements with the app's data.
        ready: function (element, options) {
            var nextPage = document.getElementById("nextPage");
            nextPage.addEventListener("click", transition, false);
            WinJS.UI.Animation.enterPage([[header],[main]], null);
        }
    });

I wish I had a pretty picture of this to show you, but wiley STILL hasn’t implemented those animated pages. If you can’t get it to work, download the sample code and give that a try. There is also a fantastic sample (if a little overcomplicated) on the dev.windows.com samples site.

 

Animating content

 

Good news! Animating content is almost excactly the same as animating entire pages. The Animation library has enterContent and exitContent functions that work a lot like enterPage and exitPage.

 

WinJS.UI.Animation.enterContent(content, startingPosition).done()

 

The content object is an HTML element (the ID of said object) that you want to animate. The startingPosition is best set to null unless you have a specific starting position. And the Promise returned is just to make sure that you don’t do anything with the entity until the animation is through.

 

I’ll spare you the steplist – it looks a lot like the Animating Pages example above. Just put the enterContent in the load function, and the exitContent in the navigation event.

 

Comments are closed

Bill Sempf

Husband. Father. Pentester. Secure software composer. Brewer. Lockpicker. Ninja. Insurrectionist. Lumberjack. All words that have been used to describe me recently. I help people write more secure software.

PageList

profile for Bill Sempf on Stack Exchange, a network of free, community-driven Q&A sites

MonthList