7.2. Using an Animation to Create a Fade EffectYou can create a nice fade effect by changing the opacity of an element. Let's start with the programmatic approach. In the pageLoad() function, we create a new Sys.UI.FadeAnimation object: var ani = new Sys.UI.FadeAnimation(); Then we set the target element: a label element (<span>) we created on the page: ani.set_target($("Label1").control); The default behavior for the fading animation is that the element fades in. However, the Sys.UI.FadeEffect enumeration defines two options, FadeIn and FadeOut, which you can change by calling the set_effect() method: ani.set_effect(Sys.UI.FadeEffect.FadeOut); We then define how long the animation should run. The default value is one second; the following code triples that: ani.set_duration(3); Finally, we run the animation: ani.play(); This is all illustrated in Example 7-1. Example 7-1. Using a fading animation
Note that the display: inline-block CSS command is used; otherwise, Internet Explorer will not show the animation (for reasons I have been unable to determine). When the page is loaded, the element fades over the course of three seconds. Figure 7-1 shows how the page appears as the Label control is fading. Figure 7-1. The label is fading into the backgroundNaturally, this effect can also be implemented in a declarative way. As always, you create an xml-script element whose name is a camel-case version of the class, so FadeAnimation becomes a <fadeAnimation> element. It is important to provide an ID for the animation, because you need to be able to refer to it to start it. You can start it not only with code, but also using xml-script, as follows: <application> <load> <invokeMethod target="ani" method="play" /> </load> </application> This approach is explained in greater detail in Chapter 9. Example 7-2 shows the complete code, with important page elements highlighted. Example 7-2. Implementing a fading animation with xml-script
7.2.1. Using an Animation to Move an ElementChanging an element's opacity is a special kind of animation. A more general animation provided by Atlas is one that simply increments the value of a number at set intervals. You can then use the changing number value in some useful way, typically to set an element property. One example that immediately comes to mind is animating an element by continually changing left and top properties. The Atlas Sys.UI.NumberAnimation class animates numbers from a start value to an end value. By setting the animation's duration and frames-per-second values, you control the number of intermediate steps and how long the whole animation takes. We will again use a Label control as an example. The code instantiates the Sys.UI.NumberAnimation class and sets the required properties, except for the frames per second, where the default value of 25 is used: var ani = new Sys.UI.NumberAnimation(); ani.set_target($("Label1").control); ani.set_startValue(0); ani.set_endValue(300); ani.set_duration(3);
ani.set_integralValues(true); Because the NumberAnimation class is generic, so to speakthere are no assumptions about how you will use the changing numeric valuesit does not implement a method that you can call directly to translate the numeric values into an element property. Instead, you set the NumberAnimation class's setValue property to a function that performs the work you want to do. This has the advantage that you can manipulate the numeric values as needed. For example, some browsers (like the Mozilla-based ones) only accept values for positioning that include a unit, such as "20px" instead of just "20", so your setMethod() function can add a unit to the number. One challenge is referencing the element to be animated without making the code too specific (for instance, with document.getElementById() and a fixed ID). The animation class enables you to get a reference to the target object using get_target(), and the result's element property grants access to the associated DOM element. You can combine this reference with your implementation of setValue() and then start the animation. Your code might look like the following: ani.setValue = function(value) { this.get_target().element.style.left = value + "px"; this.get_target().element.style.top = value + "px"; } ani.play(); Example 7-3 shows a complete listing for a page that animates a Label control, moving it around on the page. Example 7-3. Moving an element with an animation
Once the page has been loaded, the label element moves across the page at a 45-degree angle. Notice how the position: relative CSS property is used to make this possible. Figure 7-2 is a snapshot of the result. Figure 7-2. The element moves across the screen7.2.2. Using a Length Animation to Move an ElementThe preceding code can also be written declaratively. As noted, to provide cross-browser support, the top and left properties of an element must not be set to a number but must contain a unit. The NumberAnimation class can provide the unit only when you create a custom setValue() method. However, Atlas also provides a class called LengthAnimation that is capable of performing the task more directly. It works like NumberAnimation, with two differences:
So, the LengthAnimation class looks like a "better" way to move an element than the NumberAnimation class from the previous example. However, both work, that's why both are shown here. Still, using the LengthAnimation class to animate a Label control is a bit tricky. The left and top properties are part of the element's style, which is not directly accessible as properties. However, a behavior called <layout> provides access to style this information, and therefore to the positioning values. To animate a Label control, therefore, when you define the label in xml-script, add the <layout> behavior to it and assign an ID: <label > <behaviors> <layout /> </behaviors> </label> Then create an animationor two, since we are modifying two style values: <lengthAnimation target="Label1Style" duration="3" property="left" startValue="0" endValue="300" /> <lengthAnimation target="Label1Style" duration="3" property="top" startValue="0" endValue="300" /> In the <application><load> section, you must start both animations, of course. Example 7-4 shows the resulting listing. Example 7-4. Moving an element with xml-script
7.2.3. Compositing (Grouping) AnimationsWhen the effect you want involves more than one animation, the markup can get ugly: you get several animations that start in sequence (but hopefully are executed in parallel). The preceding example (Example 7-4) contained two separate animations, one for the horizontal value and one for the vertical value, each of which you had to define separately, including their duration. You can simplify things by grouping animations using the Sys.UI.CompositeAnimation class. Grouping animations helps make sure that animations execute in parallel. You can do this using the xml-script <compositeAnimation> element. Within the element, the <animation> element contains the xml-script definitions for all animations that should be executed together. You can then specify an id attribute and a duration attribute for the <compositeAnimation> element that then apply to the group as a whole: <compositeAnimation duration="3"> <animations> <lengthAnimation target="Label1Style" property="left" startValue="0" endValue="300" /> <lengthAnimation target="Label1Style" property="top" startValue="0" endValue="300" /> <fadeAnimation target="Label1" effect="FadeOut" /> </animations> </compositeAnimation> You can start the composited animation using <invokeMethod>: <application> <load> <invokeMethod target="ani" method="play" /> </load> </application> Example 7-5 shows the complete code for a page that contains a set of grouped animations. Example 7-5. Grouping animations on a page
This animation is composed of three subanimations that each complete at the same time (see Figure 7-3):
Figure 7-3. The label moves and fades at the same timeAnd even though the real-world use of animations is a bit limited, Atlas makes it very convenient to add some eye candy to a web application. Since these features all reside in an external JavaScript file, the Atlas.js library itself is not bloated by including this functionality by default. |