Fluent Animations in Silverlight

A fluent (jQuery-esque) API for creating Silverlight animations easily in code, built on top of Silverlight.FX, along with some early thoughts on possible integration of animations and view models.

About a month or so back, Daniel sent me an email about an idea he was working on - a fluent interface that allows developers to build professional UI complete with visual effects and how that related to my Silverlight.FX effects framework.

This morning he posted his work on creating composite animations in code that builds on top of Silverlight.FX. Very cool and super interesting! Here are a couple of examples from his post:

// Play a yellow highlight for one second when an image is clicked
Animator.WithNew(highlightImage)
  .Highlight(Colors.Yellow)
  .For(1.Seconds())
  .When(EffectBehaviors.Clicked).Play();

// A composite animation involving multiple effects
Animator.WithNew(compositeImage)
  .WithEasing(EffectEasing.QuadraticInOut)
  .Move(50).For(1.Seconds())
  .And().Resize(0.5, 0.5).For(1.Seconds())
  .And().Spin(360).For(1.Seconds())
  .And().FadeTo(0.5).For(1.Seconds())
  .Play();

Check out Daniel's post for more details and to download the samples and code.

I'll be posting Silverlight.FX sources itself on github rather than a zip attachment on blog posts in the near future so folks can more easily fork and experiment with ideas and additions. The SilverlightFX repository with latest binaries is already up - feel free to start watching it to be notified of checkins I will be making.

A Fluent API
For those familiar with jQuery, this will immediately ring a bell. The fluent API pattern can really help readability of code when the semantics of the code have a natural sequence and share some shared context - as in this case, the effective animation to apply and play.

What do folks think of it? I certainly wish there were some things in the .net framework that offered this style of fluent API, as it would help make code much more manageable (CodeDOM?).

Animations and the View Model Pattern?
Daniel's work brings a thought in my mind that I'll go ahead and share. Generally a view model shouldn't be concerned about visual presentation. And animations pretty much fall into the domain of presentation. For example, the code above would be written in the code-behind associated with some UI and be a part of the presentation.

However, the sequences defined above almost seem to define a meta-animation or animation model for the actual animation that is to be played. In fact Daniel talks about animators being reusable. I wonder if there is some merit in looking at these animators as a piece of model data that can be constructed by a view model, and handed to a view via an event. In turn, the the view, which subscribes to the view model, could in response materialize an actual animation instance by applying it to a visual element. Now why would I want to do such a thing, even if I could - an animation might be the result of some user interaction that is translated into an action on the view model. The alternative would be for the view model to surface a number of properties that the view or a value converter translates those properties into an animation sequence. Any thoughts on this subject?

I've increasingly adopted the view model pattern in favor of code-behind-less views since working on Silverlight and Silverlight.FX. Maybe that explains this thought process... :-)

Posted on Friday, 12/19/2008 @ 1:03 PM | #Silverlight


Comments

15 comments have been posted.

Daniel

Posted on 12/19/2008 @ 2:05 PM
Thanks for the shout out!

I will say that working on the fluent interface project for complete UI layouts has, over time, exposed a lot of challenges due to coupling the presentation to pure code, as well as attempting to anticipate the needs of developers using the interface while keeping the modelling components lightweight. For shorter-scoped goals like animation, though, the fluent interface shines. I am still determining the future of my UI project, but I believe that MVVM and your concept of modelling meta-animations to build dynamically from user interaction is the right direction to go. I look forward to experimenting more along those lines with the latest FX bits.

Cheers!

Daniel

Steve Gentile

Posted on 12/19/2008 @ 5:45 PM
In light of you speaking of 'jquery'.

The real power is the 'unobtrusive' features - where the javascript is not spaghetti code into the markup. Instead it's 'attached to the elements' in the markup - typically in a separate .js file.

Let's say for example, you want to create a tab view in jquery. You layout your html elements, your markup, ul /ul li /li etc.. with some span and divs for content, etc... Then in your script file you will attach the 'tabview' to that ul. The ul knows nothing about it.

This is better than li onclick=somejsfunction() all in your markup.

In WPF/Silverlight, it's sorta strange with behavior itself being a declarative part of the UI.

ie. TextBlock click=

So, if I were to use 'jquery-like' approach, I'd remove any 'event handlers' or such that represent code on the markup and instead attach it in the actually code.

That is, what I think Daniel is doing here with his code. I've seen a mess of xaml in the views doing animations, and it just looks, feels, smells wrong to me.

I expect unobtrusive code on that markup.

So, I would expect an image lets say on the xaml.

In the code, 'attach' the animation to that image. The image would know nothing about it - the view would be clean. The code would be in the code.

That is my take - hope it makes sense.

Steve Gentile

Posted on 12/19/2008 @ 5:56 PM
I should add - your approach Nikhil is similiar to what I saw with the ajax - you were about the 'declarative markup' for awhile :)

Adding behaviors in the markup to the markup is how I saw it.

I think there is a mix personally. ie. binding.

I've been working on a asp.net mvc for 9 months now. The biggest transformation has been to slowly remove the 'custom logic' in the view and replace it with special, resuable html helpers. They are easy to create, etc... and output the 'markup' - I've taken for example, jquery javascript, wrapped it up in the helpers.

Html.TabView(
source => tabsList, backgroundColor => 'red', etc...
);

So it would be interesting to see an easy way (easy as in, as easy as a html helper) to create 'markup' like xaml.

< TabView Source={tabsList} backgroundColor='red'>
< /TabView >

So, which one is preferred here?

Nikhil Kothari

Posted on 12/19/2008 @ 6:05 PM
Steve - I agree jQuery really makes the unobtrusive javascript pattern approachable. I was comparing the API style here to typical jQuery APIs and the resulting code.

I also definitely agree with you on the point that XAML can quickly become a mess with event handlers, resources, layout related attributes, storyboard interspersed etc. etc. I personally believe in being able to type in the XAML rather than have some tool generated mess (I do think tools help when you're trying to build a path, or a gradient etc.). XAML that is typable, tends to be readable and manageable, or at least more easily. A lot of what I am trying to do with Silverlight.FX is provide better patterns and approaches (better of course being subjective) to this end. For example:

- Behaviors: these encapsulate event handling, so you don't actually handle events and attach a ton of handlers in xaml markup. Instead in xaml markup you attach these reusable declarative components.
- Resources: The theming system in Silverlight.FX allows you to separate these into separate themes, rather than showing up in App.xaml or in specific UI controls.
- Layout related attributes: often you see a mess of Horizontal/VerticalAlignment and Margin attributes or even Grid.Row/Column attributes. I am trying to clean up those with better layout containers like HStackPanel/VStackPanel and some more layout containers I haven't released just yet.
- Storyboards: often what you want is subtle, pre-canned effects to attach declaratively, so you don't have to define storyboards or handle events to begin/end animations. This is where the declarative effects come into play.
- View/Code separation: the view model implementation in Silverlight.FX is specifically geared at enabling these. I am working on some other ideas like commanding, data templates etc. that further reinforce the importance of this aspect.

Miguel

Posted on 12/20/2008 @ 6:50 AM
Nikhil,

I know you did some work with theming and you mention the need for new layout controls. What do you think about thw work done with the SL Tollkit in this two areas and how is that compared to that work you're going or have done?

About your last point and MVVM. I was completely sold on the idea at some point. As I see it this pattern relies completely on databinding and is exactly there where we found our weak link. In beta 2 we had to go to code behind to work well with the list box and now for RC0 and RTM we need to do several hacks to work with the dropdownlist, datagrid and textbox, because those controls aren't working as needed and code-behind was the only way to achieve that behavior. As much as I'd like to go through that path, I don't think it's something doable, at this point. When you talk about View/Code separation are you also relying on DataBinding? Have you encountered this type of issues?
We're only using Microsoft controls at the moment, but I can imagine it might be harder if we used third party controls, that might offer other benefits, but aren't binding friendly.

By the way, I just read Scott Morrison's post about the new version of the Datagrid, that will solve many of the problems we have, but I don't think that would be enough to achieve what at this point seems an utopical separation.


In respect to animation, I think the VM shouldn't be responsible of defining them. Instead it should only express the intention (navigate to A, show X, hide Y, change from z to z1, etc) and then the view take care about how to do that. The idea of having a reusable Set of Animations sounds compelling, this could help to remove this code from the XAML, or at least from the XAML on each View. This way the VM would say what it wants and the view how it gets done. Similar to how the VM through databinding (and property change notifications) inform the view of the change of a name, but the view is resposable of how to display it (e.g. use a textbox, textblock or something else).
This in a sense is similar to what you're saying, but I don't think is the VM they one that should construct this "animation model", this isn't necessarily the view reposability either, specially if it could be part of this Set of Animations, probably shared acrooss the whole app.

Nikhil Kothari

Posted on 12/20/2008 @ 9:33 AM
@Miguel - I haven't tried this yet, but with the declarative effects in Silverlight.FX, I believe you could specify them in resources to reuse and apply to different elements across the app. Something to try out... and fix any blockers that might surface.

I agree with your distinction of view model and view. However if animations have to be constructed in code (for some particular scenario), and can't be put into resources, it brings up a question of where that should be done. It can be done in the view code behind, but part of me wonders whether the "animation model" per se is just a model that could be independently tested, and separated from the view. Potentially another place to think about this is a value converter, which constructs an animation in response to a property change. Just thinking aloud - thanks for sharing your thoughts as well.

Yes, the MVVM pattern generally relies on data-binding and handling events. For the latter I added equivalents to triggers in Silverlight.FX. For data-binding there are certainly limitations in the SL subset, some of them quite painful (esp. access to binding objects and properties off bindings, lack of UI-UI binding, explicit binding, custom markup extensions). I know we are still far from the utopia state. Any specific ones that you believe have been complete blockers esp. with something as simple as TextBox? I know we're addressing some in SL3, but it would be good to hear if there are any specific ones you'd call out.

So far there hasn't been much duplication with the toolkit. The toolkit did introduce things like AutoComplete which is also in Silverlight.FX. Some things are complementary - eg. theming. The toolkit has the ability to implicitly apply styles. Silverlight.FX provides a mechanism/pattern to author themes separately, and doesn't get into the applying business. However both are evolving, so it will be interesting.

One of my driving philosophies is to keep this framework lean and mean at the cost of some features that might be interesting only to a few. The other is to optimize for solutions that enable building views more simply, with less verbosity, and enabling separation of views and code. At least that is the outlook for now...

Jose Fajardo

Posted on 12/20/2008 @ 2:41 PM
Hi guys, I'm chiming in as someone that is NOT fluent in MVC / MVVM but understands animations very well. And more importantly I'm a designer first / developer distant second.

Whilst I completely understand the problem trying to be solved with Adam's library, as well as other tweener/easling like libraries out there. My main viewpoint on these matters is that animations, regardless of how simple they are, need to ultimately be in the control of a designer. Any animations that are programatically defined & controlled, such as ones done by this library, are out of a designers control.

Flash/Flex allows some very complex animation sequences and almost always in these cases they are achieved purely in code and using tweener/easing like libraries. Basically designers building these animations need to have a strong math's, programming background.

Silverlight 2's VSM is a step in the right direction because it allows a designer to have full control of all interaction animations. As soon as you start allowing those animations to be defined in code then the designer loses the ability to define UI.

Ultimately it would be great if this library were a consumable CLR class in blend so that we can bind to it's DP/AP properties allowing the designer to configure there settings (rather then have it all locked up in code)..

I've built out alot of silverlight apps over the last 1.5 years and it pains me to have to do alot of animations in code, this includes setting properties and running storyboards etc. As a designer I hate having to do anything in code, I love working on the time line and I love wiring up states in the VSM. Unfortunately most of my work these days involves very complex transition/visualization animations which means i need to build out alot of storyboards and procedurally wire them up together in code. I'm hoping Silverlight/Blend will add some future features that allow me to procedurally link storyboards and/or do more complex linking in the VSM, as stated above im doing it all in code.

Long story short, i think any animation configuration/customization done in code will lead to a bad developer/designer workflow story. We need to elevate all animation configurations to the surface of blend so that designers have final input into it.

Nikhil Kothari

Posted on 12/20/2008 @ 4:41 PM
Jose - I fully agree with you on having a good designer/developer workflow; beyond having a good workflow, having the ability to specify things declaratively when needed is essential. I am a huge fan of declaratively specifying what a program or design ought to do.

There are couple of features here - Effects, that come with Silverlight.FX and then other the Fluent API that Daniel is experimenting with...

Effects in Silverlight.FX are declarative and customizable via XAML as shown in my past blog posts on the topic. Yes, they are indeed one layer of abstraction over lower-level animation features such as storyboards, so you're speaking in a bit more abstract terms: resize, spin, flip etc. applied on hover, focus, click, etc. A lot of times you don't need a whole lot of control - you want a subtle effect (eg. small resize on hover that lasts a few milliseconds) and the whole storyboard/VSM thing in my opinion is overkill, not just in terms of XAML it results in, but in terms of handling events (mouse enter/leave) and triggering animations etc. A stock out-of-the-box animation would do just fine.

In fact, our resident designer here, Corrina, who has designed the look and feel for the out-of-the-box Silverlight controls, loved the effects model in Silverlight.FX, in terms of the simplicity it results in for a number of mainline scenarios. Sure when there is something totally custom to be done, all the power and lower-level building blocks of Silverlight are still there, which is really nice - you don't hit a brickwall.

At the same time not everyone has designers on their team. If fact, I think one of the original goals Daniel had that he communicated with me was around creating something that could speak to developers and allow them to create reasonably professional UX even if there was no designer involved. Now, I know just animations don't take you all the way, but they are part of the puzzle, and this is at least a reason for having a stock library of effects and an easy way to apply them - both declaratively and imperatively, depending on the needs of the scenario.

I also imagine the fluent API Daniel has built lends itself very well to a declarative specification model - its almost like a workflow where you can drag/drop individual pre-canned animations and then wire them into sequences or parallels... and persist them into xaml rather than into code.

I think ultimately, declarative or imperative aside, the key difference between the Silverlight.FX model and the raw storyboard mechanisms is the abstraction level at which you're operating. What I certainly want to do or think about first, is how to create a smoother continuum between those two approaches - say you start with abstract and simple effects, and then you want to tweak them beyond what the properties allow - can effects be turned into corresponding storyboards and triggers?

Great comment though! I am not disagreeing with anything you've said; it certainly sparks some interesting discussion and further thought.

Miguel

Posted on 12/20/2008 @ 5:37 PM
Yes thinking of animations as another model sounds right, but really it would be a model totally related to the presentation. Would be like having a model for the layout and then testing it. However, I like the idea of having it as a converter or probably if we could use merged dictionaries it might be better.

About the issues, just to mention to examples:
1. With the combobox if we change the ItemSource and the SelectedItem (e.g. Products and SelectedProducts in the VM) we get an ArgumentOutOfRangeException because the SelectedItem doesn't exist yet in the list of items of the ComboBox. To fix this, we have to go to code-behind, set the ItemsSource and SelectedItems to null, then set them back again to the appropriate values.
2. The textbox, under certain circumstances (I've not been able to reproduce it in a new project) doesn't update the Source if we only enter one character. The solution for this implies subscribing to the LostFocus, saving the text, setting the text to "" and then setting the text back to the saved value.
3. The datagrid leaves blank rows when the DataSource is updated and a row was selected. This was the uglies hack, sometimes we setting the focus to the datagrid before updating the ItemsSource was enough, but other times we have to set the ItemsSource to null, start a timer "wait" until the datagrid is updated, then set it to the new ItemsSource. This is fixed in the latest update of the DataGrid, but I've not been able to test it.

For some issues, like the Textbox, where the workaround is consistent, I've managed to solve them in a declarative way using Attached Properties, but most of the time the needed "Hack" is slightly different which means, go to code behind and code something around to have direct access to the controls.

vikram

Posted on 12/22/2008 @ 9:14 PM
Hi,

good one. One thing, the new underlining in the comment section might be cool but it makes reading the comments more difficult. I think removing the underlining would be a better idea...

David Roh

Posted on 12/27/2008 @ 11:38 AM
I definitely agree with Jose about having as much of the designer aspects controllable from a tool like Blend for designers as possible - complex designs can quickly become difficult to maintain when done in code not controllable by a Blend like tool; however, I realize that the following opinion is going against the popular view when I say that I have serious concerns about declarative programs. If I am wrong, please let me know; however, there currently is very little support for single stepping through declarative programs or other debugging tools - I am not aware of anyway to trap and handle run time errors in a useful manner. This means that many errors and issues are only visible at run time which significantly reduces program quality and reliability.

Obviously, declarative programming is not going away and XAML and declarative programming are currently used to support designer tools which are very much needed. The solution is to significantly improve the declarative debugging capabilities of design tools such as Blend and programming tools such as Visual Studio. In addition, I feel that the ability to have run time error trapping and handling of declarative programs would significantly improve the quality of declarative programs.

Anyway, this is just my view - please provide clarification for things that I have overlooked.

Nikhil Kothari

Posted on 12/27/2008 @ 2:50 PM
@David - I'd too would like to see declarative code become more debuggable as well.

I don't know about storyboards - it seems "debugging" them ought to be part of the design process, but other things like Bindings for example would be great candidates for breakpoints. I know the debugger folks have prototypes for just the sort of scenarios, and hopefully over time they'll become mainstream. There are some declarative systems that are debuggable as well - the workflow designer is one example of such a system - you can put breakpoints on activities, single step through them etc.

Erno

Posted on 12/29/2008 @ 7:53 AM
I prefer the WPF way: adding a storyboard to a style and applying the style to a control and thereby enabeling reuse.
Yes, we need better tools support to do this in XAML because at the moment you can not design an animation/storyboard without hooking it up to a control. So we also need the same resource dictionaries in Silverlight as we have in WPF so we can add the same resource multiple time to the UI.

From a coders point of view we need to be able to parameterize the storyboards (databinding?) so we can add/activate and animation in a specific situation without defining UI in code.

nikhil

Posted on 4/23/2009 @ 12:07 AM
Great research dude!!!
thanks....

yalda nasirian

Posted on 9/4/2009 @ 10:07 PM
hi friends

see my web at

http://yaldanasirian.blogspot.com/
Post your comment and continue the discussion.