Flex and WPF: A comparison – Part 3a

In this installment of the comparison posts I will look at the Animation framework in WPF and Flex. Both these technologies have vastly simplified the programming model for doing animations on your User Interface. Both of them allow animations to be created using markup (XAML/MXML) or code (C#/AS3). There are a number of animations that can be used out-of-the-box and you can also create your own custom animations.

Since this part is again pretty long, I am splitting it into 2 subparts. In this subpart I’ll cover the way it is done in WPF.

In WPF…

Animations in WPF are typically created using Storyboards. Storyboards are timeline-based animations that run for a specific period of time and target specific elements on the UI. Let’s look at the XAML for a simple Storyboard that fades an Ellipse from opaque to transparent in one second.


<Grid>


<Canvas
Margin=”30″
Width=”230″
Height=”230″
Background=”Gray”>


<Canvas.Resources>


<Storyboard
x:Key=”fade”>


<DoubleAnimation
Storyboard.TargetProperty=”(Ellipse.Opacity)”

Storyboard.TargetName=”e1″ From=”1″
To=”0″
Duration=”0:0:1″
/>


</Storyboard>


</Canvas.Resources>


<Ellipse
Name=”e1″
Canvas.Left=”100″
Canvas.Top=”0″
/>


</Canvas>


</Grid>

The Storyboard.TargetName and Storyboard.TargetProperty target the property of the UI element that needs to be animated (in our case the Opacity property of Ellipse). We are using a DoubleAnimation because the Opacity property is of type double. The From, To and Duration values should be self-explanatory. Note that the format of the Duration property is HH:MM:SS.

More than one animation at the same time

The Storyboard class actually derives from ParallelTimeline, which means you can put multiple DoubleAnimations inside your Storyboard and all of them will animate in parallel. So if you wanted to move the Ellipse from x=100 to x=400 and also fade it out, you could so something like this:


<Storyboard
x:Key=”translateAndFade”>


<DoubleAnimation
Storyboard.TargetProperty=”(Ellipse.Opacity)”

Storyboard.TargetName=”e1″ From=”1″
To=”0″
Duration=”0:0:1″
/>


<DoubleAnimation
Storyboard.TargetProperty=”(Canvas.Left)”

Storyboard.TargetName=”e1″ From=”100″
To=”400″
Duration=”0:0:1″
/>


</Storyboard>

Note how I added an extra DoubleAnimation to do the translation. It will now animate in parallel with the fading animation.

Playing in sequence

What if you wanted an animation to start only after the previous one has completed? Sure, you can do it using the BeginTime property. In the previous example if we wanted the translate animation to happen after the fade completes we can do it this way:


<Storyboard
x:Key=”translateAndFade”>


<DoubleAnimation
Storyboard.TargetProperty=”(Ellipse.Opacity)”

Storyboard.TargetName=”e1″ From=”1″
To=”0″
Duration=”0:0:1″
/>


<DoubleAnimation
Storyboard.TargetProperty=”(Canvas.Left)”

Storyboard.TargetName=”e1″ From=”100″
To=”400″
Duration=”0:0:1″

BeginTime=”0:0:1″
/>


</Storyboard>

Note that since my BeginTime has been set to “0:0:1”, it will only start after the fade-animation completes. So the total time-length of the storyboard is 2 seconds as opposed to 1 second for the previous storyboard. You can also nest ParallelTimelines and mix and match with BeginTime to achieve pretty much any sequence of animations.

There are also other properties on the XXXAnimation classes (XXX denotes the type like Double, Color, etc) like

  • AutoReverse – which automatically reverses the animation
  • RepeatBehavior – which sets the number of times you want to repeat the animation. RepeatBehavior=”Forever” results in non-stop animation.
  • AccelerationRatio, DecelerationRatio – easing in/out values specified as a fraction of the Duration. AccelerationRatio=”0.25″ will accelerate the animation in the first quarter followed by constant-speed animation for the remaining 3/4th.

Using keyframes

The animations I described earlier were of the From/To kind, where you have a starting value and an ending value. If you wanted the animation to pass through multiple states in between the start and end values, you need to use keyframe animation. Here is an example right out of the Windows SDK with the comments explaining exactly what I want to convey!

<Ellipse
Width=200
Height=200>

<Ellipse.Fill>

<SolidColorBrush
x:Name=MyAnimatedBrush
Color=Green/>

</Ellipse.Fill>

</Ellipse>

<Storyboard>

<!– Animate from green to red using a linear key frame, from red to

yellow using a discrete key frame, and from yellow back to green with

a spline key frame. This animation repeats forever. –>

<ColorAnimationUsingKeyFrames


Storyboard.TargetProperty=(SolidColorBrush.Color)


Storyboard.TargetName=MyAnimatedBrush


Duration=0:0:6
FillBehavior=HoldEnd
RepeatBehavior=Forever>

<ColorAnimationUsingKeyFrames.KeyFrames>

<!– Go from green to red in the first 2 seconds. LinearColorKeyFrame creates

a smooth, linear animation between values. –>

<LinearColorKeyFrame
Value=Red
KeyTime=0:0:2 />

<!– In the next half second, go to yellow. DiscreteColorKeyFrame creates a

sudden jump between values. –>

<DiscreteColorKeyFrame
Value=Yellow
KeyTime=0:0:2.5 />

<!– In the final 2 seconds of the animation, go from yellow back to green. SplineColorKeyFrame

creates a variable transition between values depending on the KeySpline property. In this example,

the animation starts off slow but toward the end of the time segment, it speeds up exponentially.–>

<SplineColorKeyFrame
Value=Green
KeyTime=0:0:4.5
KeySpline=0.6,0.0 0.9,0.00 />

</ColorAnimationUsingKeyFrames.KeyFrames>

</ColorAnimationUsingKeyFrames>

</Storyboard>

The keyframe animation classes follow the same naming convention of XXXAnimationUsingKeyFrames, where XXX is the type. In the above example we are using ColorAnimationUsingKeyFrames but you could also use DoubleAnimationUsingKeyFrames when animating properties of type Double.

Creating Custom animations

For most cases you should be able to get away with the default animation classes. However for some cases you do need to create your own animation classes. I did a blog post sometime back detailing this technique. The basic idea is that you have a <Type>AnimationBase class from which you derive your animation class, for eg. DoubleAnimation derives from DoubleAnimationBase. Inside the <Type>Animation class you override the CreateInstanceCore() Factory method that returns an instance of <Type>Animation. You can also define additional DependencyProperties on your animation class for further customization. The blog post I mentioned has all these details.

So Storyboards are pretty much the defacto way of describing animations in WPF. However you could also use DoubleAnimation or other animation classes directly without nesting inside a Storyboard. In my experience I have always found it best to have it inside a Storyboard. All the event-based triggering of animations consume Storyboards instead of <Type>Animation instances. I have skipped the part about creating Storyboards and animations in code but it is not much different. Since the tag-names map directly to the class-names, you could recreate the same object hierarchy in code.

The next post will be about Effects – the Flex way of doing animations!

Advertisements

Cool libraries to explore

I have been following the blogs, discussion groups and forums to collect some cool stuff people are doing with Flex and ActionScript 3. I am maintaining a list of all such libraries on my Tools page. I want to make it a central point of access for all the great stuff happening on Flex/AS3.

Posted in as3, flex, tools. 1 Comment »

Flex + Flickr + Cairngorm

Surely I am one of the many who have used the above combination of libraries. I decided to make a simple app that used the Cairngorm architecture for RIA, just to get myself up to speed. The end result is below. I faced a couple of problems deploying it to my server, primarily the Security Sandbox error. I did a blog post on that here. I have seen some people asking about this problem on FlexCoders group. Hopefully my post will be helpful to them.

 

BTW, you can also view the source to see the way I have used Cairngorm.

Technorati tags: flex, cairngorm, flickr

Fixing the Security Sandbox errors with AS3 Flickr API

One of the recent experiments I tried was with the AS3 Flickr API. Adobe Labs has published a library called as3flickrlib on Google Code which makes it easier to access your flickr photos. So I downloaded that (using the flickr-.85.zip link under the Featured Downloads section) and started playing with it. I felt it was pretty straightforward to use it, partly because I have used other Flickr libraries like Flickr.Net for the .Net framework.

When developing inside Flex Builder my code worked great and I could access images and other information through the library. But when I deployed the compiled version to my server, I started getting Error#2048: Security Sandbox violation. Cannot load resource from http://flickr.com/&#8230; I knew that this error had to do something with the crossdomain.xml policy file that must deployed on Flickr so that external access to it is allowed. When I did a Google search on “crossdomain flickr”, I did find the policy file on http://api.flickr.com/crossdomain.xml. But surprisingly the domain was api.flickr.com and not flickr.com, as it stated in my security error.

After a couple more Google searches I came upon this YahooGroups post where it said that the API end-point for Flickr has changed! AHA! This made me think that the as3flickrlib must be still using the old flickr.com endpoint. Sure enough, when I opened up the source for FlickrService.as, it was using the wrong end-point.

public class FlickrService extends URLLoaderBase { /** * The REST endpoint where we can talk with Flickr service */ public static const END_POINT:String = "http://flickr.com/services/rest/?";

To fix that, I looked at the sources for as3flickrlib on the Google Code Subversion repository. Interestingly FlickrService.as over there was using the correct end-point (api.flickr.com). So I got hold of the sources for as3flickrlib and the dependency: as3corelib, recompiled them inside Flex Builder and generated a new as3flickrlib.swc. Using that, things started working like expected.

So if any of you are using the SWC from the zip file provided on as3flickrlib Google Code project, it is NOT going to work when you deploy your application online. You can use my recompiled SWC, which I have uploaded over here. Ideally Adobe should be updating the build and uploading the new version. Right now the source in SVN and the compiled zip are not in sync :-(.

 

 

Technorati tags: , , , ,

Papervision3D

When will I get to play with this? The demos blow me away each I time I see them.

 

Technorati tags: ,
Posted in 3d, flash9. 5 Comments »

Flex as a DSL for Graphics

One of my colleagues, John Dunne, forwarded me this interesting article by Bruce Eckel about Flex as the universal platform for application development. The article talks about the state of affairs with web technologies. It talks about HTML, Javascript, AJAX and Java Applets and describes the problems like installation issues, browser incompatibilities and UI-richness. Finally he settles on Flex as being the solution that overcomes all of the said problems. Check it out.

 

Technorati tags: , ,

Flex and WPF: A comparison – Part 2b

In part-2a we saw some of the building blocks of WPF and how they are used to achieve the content-style separation. This post is a continuation and will focus on Flex’s approach.

Flex has adopted the web standards right from ground up. So if you are a web developer who has had any experience with HTML, CSS, Javascript it should be very natural to program in Flex. A direct one-one mapping looks like this:

HTML –> MXML

CSS –> CSS

Javascript –> Actionscript

 

MXML markup + code-behind

    MXML is the markup language that is used to describe the User Interface components in Flex. In concept it looks very similar to XAML, but since it is also like HTML, it has the familiar tags like <mx:Script/> and <mx:Style/>. The <mx:Script/> tag is used for inline code-behind whereas the <mx:Style/> describe the stylesheet elements for the UI elements. In a previous post I did a comparison of the code-behind models in Flex and WPF, which is slightly more detailed. Actionscript is the language used for the code-behind and its syntax is very similar to Javascript.

    The standard practice for describing UIs is to use MXML. Even the event-handlers are specified directly inside MXML. However it is also possible to bypass MXML completely and define the UI component completely in Actionscript. In the former approach, the MXML compiler will generate the Actionscript for you, which in turn gets compiled to SWF.

Databinding

    Databinding is definitely my favorite feature in Flex and it is extremely powerful. It is also very easy to make your model objects bindable by including a simple metadata tag like [Bindable] against the model property or object. This is simpler than the WPF approach where you will have to implement the INotifyPropertyChanged interface for the model object and manually fire the property change notifications. In Flex just by attaching the [Bindable] metadata tag you get FREE property change notifications. Of course if you want to customize the notifications, that too is possible. What I find really interesting is the part where you bind a UI element to a model object. Say I want to bind the text property of a <mx:Label/> to the firstName property of the Person object. The syntax would look something like this:

<mx:Script>

    [Bindable]

    var _person:Person = new Person(“Pavan”, “Podila”);

</mx:Script>

<mx:HBox>

    <mx:Label text=”{_person.firstName}”/>

</mx:HBox>

 

Since I made the _person instance [Bindable], the Label will automatically update its text property whenever _person.firstName changes. What is exciting is the fact that the curly braces syntax for data-binding can actually include Actionscript inside it! This is very useful in cases where I want to do a little bit of more formatting to the text. If I wanted my text to appear like “FirstName: PAVAN”, I could do this right inside the {}:

    <mx:Label text=”FirstName: {_person.firstName.toUpperCase()}“/>

Doing the same in WPF would have required me to write a class that implements the IValueConverter and then pass in the instance of my model as a parameter. So the syntax would look like below.

[Note that I am following the C#/XAML naming conventions, so my property names have the first letter of each word capitalized: FirstName, LastName.]

<Application.Resources>

    <local:StringToUpperCaseConverter x:Key=”stringConverter”/>

    <local:Person x:Key=”person” FirstName=”Pavan” LastName=”Podila”/>

</Application.Resources>

<Label Content=”{Binding Path=FirstName, Converter={StaticResource stringConverter}}”/>

Also my converter class would look like this:

    [ValueConversion(typeof (string), typeof (string))]

    public class StringToUpperCaseConverter : IValueConverter

    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

        {

            string firstName = (string)value;

            return “FirstName: “ + firstName.ToUpper();

        }

 

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

        {

            return null;

        }

    }

That definitely is a lot more typing to do than the Flex’s approach. I see this is as a major benefit in Flex which I would love to have in WPF.

 

MXML components

    MXML components are reusable views in your application. Say you have a photo-viewer application that shows a list of photos. Each photo could be wrapped inside a MXML component that shows other information about the photo when you click on it. The view of the photo and the interaction can be captured inside this component and can be reused throughout your application. These components can also behave like the DataTemplates in WPF. You can create a property on the MXML component and set that as the model object. Inside the component you can data-bind to the properties of the model thus simulating the DataTemplate. Note that the property you create on your MXML component is your DataContext.

    ItemTemplates in WPF have a direct one-one mapping with the ItemRenderers in Flex. List based controls use the ItemRenderers to render each item in the list. Here is a simple example of an inline ItemRenderer.

<mx:DataGridColumn headerText=”Online” dataField=”online”>

<mx:itemRenderer>

<mx:Component>

<mx:CheckBox click=”data.online=!data.online” selected=”{data.online}”/>

</mx:Component>                        

</mx:itemRenderer>

</mx:DataGridColumn>

 

You can also create a separate MXML file, say Checkbox.mxml, that encapsulates the component. In that case you provide the name of the component to the itemRenderer property (itemRenderer=”Checkbox”, assuming Checkbox.mxml is in the same directory).

CSS styles, skins

    Styling a Flex application means creating a CSS file (or a group of CSS files) that provides the appearance for the different UI elements. Most CSS files would include customized values for many of the UI element properties. But if you want more fine-grained control on the appearance one can also create something called the Skins. A skin file is also a CSS file but can include components from a compiled SWF file. The SWF may have custom rendered skins, also called programmatic skins. Here is a nice article on creating skins for Flex.

Packaging into SWC, SWF and modules

    SWF is the final version of a compiled Flex application. It may also have a bunch of dependencies on Actionscript/Component libraries. These libraries are compiled as SWC. The other option for packaging is to use Flex Modules. Bruce Phillips did a good post on this topic and covers all the necessary material.

 

Technorati tags: , , ,