»
S
I
D
E
B
A
R
«
Building Your First App: Animation
12 November 2009 by Rob Spectre
This entry is part 8 of 9 in the series Building Your First App

We’re almost there with the penultimate step in building your first Boxee application. In the last installment, we finished the construction of the application by finishing the metadata box. In this step, we’ll do our last round of polish before we’re ready for the best step of all – release!

Animation is the crucial last polish that can really make your application shine and is super easy to add. For our app, we are going to add a nice theater-light style fade in for the active elements of our interface while the application loads. This can be accomplished by applying an animation element to our list container and metadata box. Let’s take a look at what that element looks like:

1
2
3
<animation type="Conditional" condition="Window.IsVisible(DialogProgress.xml)">
   <effect type="fade" start="100" end="20" time="200"/>
</animation>

In this element we are doing two things – setting a condition and setting an effect. The condition is set with the animation element telling Boxee to render the animation when certain criteria are met. In this case, we are defining the condition as the visibility of Boxee’s default “loading clock” animation.

We then define what kind of animation with the effect element. Here we put the attributes of how we would like this animation to behave.

type
There are many animation effects available within Boxee; the type attribute defines which one we want. As mentioned before, we are using a “fade” animation for our first app.

start / end
The start and end attributes have deceiving names for their function in a fade animation. For this effect, start and end are the values we are setting for opacity at the beginning and end of the animation. So if we input the values “100″ and “20,” we are telling Boxee to render a fade effect that changes the interface object’s opacity from 100% (fully solid) to 20% (nearly transparent).

time
The time attribute defines the interval of the animation in milliseconds. With “200″ as our value, we are telling Boxee to fade the interface object from 100% to 20% in 0.2 seconds.

With our animation element defined, we need to just add it to the controls we wish to fade. Adding an animation is as simple as including the animation element to the control we wish to animate. First we’ll start with the image control that provides the background of the list container.

1
2
3
4
5
6
7
8
9
10
<control type="image">
	<animation type="Conditional" condition="Window.IsVisible(DialogProgress.xml)">
	   <effect type="fade" start="100" end="20" time="200"/>
	</animation>
	<posx>60</posx>
	<posy>230</posy>
	<width>502</width>
	<height>416</height>
	<texture>list.png</texture>
</control>

Now when we start our application, we can see that while Boxee loads our RSS feed, the list container background does a neat theater fade. To give the entire app that same polished look we will need to add the effect also to the metadata box’s image control, the list container, and the group control containing our metadata objects.

Here’s our final main.xml now fully animated:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?xml version="1.0"?>
   <window type="window" id="14000">
   <defaultcontrol always="true">100</defaultcontrol>
   <allowoverlay>no</allowoverlay>
   <controls>
      <control type="group">
          <control type="image">
             <posx>0</posx>
             <posy>0</posy>
             <width>1280</width>
             <height>720</height>
             <texture>bg.png</texture>
          </control>
          <control type="image">
             <animation type="Conditional" condition="Window.IsVisible(DialogProgress.xml)">
	         <effect type="fade" start="100" end="20" time="200"/>
	     </animation>
             <posx>60</posx>
             <posy>230</posy>
             <width>502</width>
             <height>416</height>
             <texture>list.png</texture>
         </control>
         <control type="image">
             <animation type="Conditional" condition="Window.IsVisible(DialogProgress.xml)">
	         <effect type="fade" start="100" end="20" time="200"/>
	     </animation>
             <posx>630</posx>
             <posy>255</posy>
             <width>574</width>
             <height>355</height>
             <texture>details.png</texture>
          </control>
          <control type="list" id="100">
           <animation type="Conditional" condition="Window.IsVisible(DialogProgress.xml)">
	       <effect type="fade" start="100" end="20" time="200"/>
	   </animation>
	   <posx>60</posx>
	   <posy>230</posy>
	   <width>502</width>
	   <height>416</height>
	   <orientation>vertical</orientation>
	   <itemlayout width="502" height="65">
	    <control type="label">
		<posx>0</posx>
		<posy>0</posy>
		<width>502</width>
		<height>62</height>
		<font>font40</font>
		<align>left</align>
		<aligny>center</aligny>
		<label>$INFO[ListItem.Label]</label>
		<textcolor>white</textcolor>
	    </control>
	    </itemlayout>
	    <focusedlayout width="502" height="65">
	       <control type="image">
		   <posx>0</posx>
		   <posy>0</posy>
		   <width>502</width>
		   <height>65</height>
		   <texture>white.png</texture>
		   <colordiffuse>DD171717</colordiffuse>
	       </control>
	       <control type="label">
		   <visible>!Control.HasFocus(100)</visible>
		   <posx>0</posx>
		   <posy>0</posy>
		   <width>502</width>
		   <height>62</height>
		   <font>font40</font>
		   <align>left</align>
		   <aligny>center</aligny>
		   <label>$INFO[ListItem.Label]</label>
		   <textcolor>white</textcolor>
		   <selectedcolor>DD171717</selectedcolor>
	       </control>
	       <control type="label">
		   <visible>!Control.HasFocus(100)</visible>   
		   <posx>0</posx>
		   <posy>0</posy>
		   <width>502</width>
		   <height>62</height>
		   <font>font40</font>
		   <align>left</align>
		   <aligny>center</aligny>
		   <label>$INFO[ListItem.Label]</label>
		   <textcolor>white</textcolor>
		   <selectedcolor>DD171717</selectedcolor>
		   <scroll>true</scroll>
		   <scrollspeed>30</scrollspeed>
	       </control>
	    </focusedlayout>
	    <content type="url" url="rss://yourdomain.com/yourfeed.rss">
	    </content>
	</control>
        <control type="group">
           <animation type="Conditional" condition="Window.IsVisible(DialogProgress.xml)">
	      <effect type="fade" start="100" end="20" time="200"/>
           </animation>
           <control type="image">
              <visible>true</visible>
              <posx>635</posx>
              <posy>265</posy>
              <width>560</width>
              <height>230</height>
              <texture>$INFO[Container(100).ListItem.Thumb]</texture>
           </control>
           <control type="label">
              <visible>true</visible>
              <posx>635</posx>
              <posy>500</posy>
              <width>560</width>
              <height>115</height>
              <font>light23</font>
              <align>left</align>
              <aligny>center</aligny>
              <label>[B]Description:[/B] $INFO[Container(100).ListItem.property(description)]</label>
              <background>grey</background>
              <textcolor>white</textcolor>
              <wrapmultiline>true</wrapmultiline>
           </control>
         </control>
      </control>
   </controls>
</window>

For more information on animating your Boxee app, refer to this excellent guide for Xbox Media Center.

Only one step left – release!

Adding Animation to an External Control
12 August 2009 by Rob Spectre

One of the elements I liked most in building the UI for AL TV was the drawer animation coming from under each thumbnail to provide the label of the ListItem. That UI mechanic is present all over the Boxee application and using it leaves more screen real estate to fit in a greater number of thumbnails.

Show me your drawers.

Show me your drawers.

The implementation was easy – two “slide” animations on the label and a background image for the ListItem in the panel container.

<animation effect="slide" start="0,-100" center="auto" time="200">Focus</animation>
<animation effect="slide" end="0,-100" center="auto" time="200">Unfocus</animation>

zOMG! Those thumbnails totally drop their drawers when you focus on them now.

Having opposite elements for Focus and Unfocus, the drawer slides cleanly out and back in as a ListItem receives and loses focus. When starting out developing my new Associated Press app, I knew I wanted to leverage a similar mechanic, but was unsure if it would fit with the app’s feel. The target length of experience, breadth of content, and probably userbase for each app probably didn’t share much on the Venn Diagram.

Making a news app look like a music video app wouldn’t please many users, after all, and the AP content lent itself to more of a scrolling ticker list design, a la Auto-Tune The News.

unfocused

Youkilis suspended?! But why?

A panel, album-cover like navigation was totally out for the AP experience, which I envisioned being brief, daily and ubersimple. Only one thumbnail visible from 30 feet away and text bigger than Jesus. A drawer would be great for the meta information like publish date and description, but those would be located in a label external to the list container. Without performing the animation within the list container, how would I be able to get the drawer effect I was looking for? The answer is the “condition” attribute. Just as the value of the animation elements used in AL TV were the conditions we desired – Focus and Unfocus – so to can we set arbitrary conditions using the Boxee API. Consider the following XML:

<animation effect="slide" start="0,-105" center="auto" time="200" condition="Control.HasFocus(111)">Conditional</animation>
<animation effect="slide" end="0,-105" center="auto" time="200" condition="!Control.HasFocus(111)">Conditional</animation>

Instead of the value of the animation element being our desired behavior, we instead choose “Conditional” and then use the condition attribute.

Ah.  With focus we can see the metadata, which tells us he was suspended for punching out a douchebag from the Detroit Tigers.  Well done drawer animation and well done Youkilis.

Ah. With focus we can see the metadata, which tells us he was suspended for punching out a douchebag from the Detroit Tigers. Well done drawer animation and well done Youkilis.

In this case, we use the Boxee API to determine if our list container does or does not have focus. If it does, pull out the drawer with the metadata. If it does not, slide that back up cleanly as the user clicks on other things. This simple animation did much for the professional, clean design of the app, except the slide would always happen before the list container was finished parsing the RSS feed. To prevent this, we can use the visible element to make sure it plays nicely and waits until the RSS is finished loading.

<visible>!Window.IsVisible(DialogProgress.xml)</visible>

This same attribute can be leveraged for all kinds of zooms, fades, and rotates to killer effect, limited only by your imagination in terms of the use cases. GetWindow, ActivateWindow, IsPaused and many other methods can trigger animations that would be useful to the user. You can see this tip in action with the Associated Press app, soon to be published in the App Box.

»  Substance: WordPress   »  Style: Ahren Ahimsa
© 2009, all rights reserved.