Before starting out on my tweening adventures I have to admit too being complete tweening newbie. On previous WPF and Silverlight projects animations were rolled from scratch to provide the desired responses to changes in the applications state. With regards to Designer and Developer workflow this stage of the process is usually where the 2 worlds collide. The developer adding animations in code behind hand cranking; Storyboards and animations; and dealing with event handlers. The designer is using Blend to create Timeline animations declared in Xaml. The other point to note is that Developers can't do animations, we may be able to code the equations and provide the necessary hooks for when event that happen when an animation finishes, but essentially the designer will have the last say in the matter with regards to the aesthetics of the animation created. My own experience is that we start with good intentions by putting all the animations in Xaml but this can become a little tricky when you have to deal with different states and trigger different animations. So this is when I fall back to putting all my animations together in a Resource Dictionary; and handling the state changes in code which fire the animations that the designer has created. The other problem that i have come across is when you have dynamic data data bound to an Items Control and you need to animate the different items based on their position in the Control, this simply can't all be done in Xaml and is a combination of Storyboards declared in Xaml and code behind to trigger the animations. In general animations can cause problems and I was also frustrated that these animations having to be hand rolled from scratch, this was evident when Felix asked if I would write some Silverlight animation code for him recently and while I was doing this all the memories of working with WPF and animations came flooding to mind at which point I thought that there must be a better way. I vaguely remembered reading an article on Silverlight Cream from Koen over at first floor solutions and further back a post from Adam Kinney. If like me you are new to Tweening this is a great place to start and is where my journey really begins. After reading the blog posts and looking over the other Tweening libraries from Cristian all of which are based on Robert Penner equations I was feeling confident that I could use this code and start to tackle my first problem. Animating Baby Smash! shapes.
After helping Scott with some other parts of Baby Smash! we started talking about how to animate the different shapes that Felix had created. We discussed the above and based on the outcome I decided to use tweening rather than hand cranking the animations from scratch, but I wanted to do something that would not only work in Silverlight but also in WPF, this is where Koens' Library solved my problem. I download his simple Silverlight application which shows off some of the basic features available in the Tweening Library and put in some additional tweaks to the UI allowing for more control over the different Transfroms which we can use in Xaml. We have a bunch of different transforms available in Silverlight, which include; RenderTransform; ScaleTransform; RotateTransform; and SkewTransform. Not only did I want to be able to play with tweens for each Transform type I also wanted to allow users to change the values for their selected transform, for example the Scale Transform supports Scaling on the X and Y axis so there are sliders which can be used to change the values from and to which the tween will use to animate the Scale tween selected.
Scott is building Baby Smash! mainly using code behind, and I can understand the attraction of heading for the code behind as this is what we feel comfortable cranking. From personal experience when building WPF applications burying goo in the code behind is not always that best thing especially when you are building interactions for the user. These interactions will have an impact on the designer and if they are not in the Xaml then they can't help that easily, but also they are more willing to change Xaml than code behind. Keon solution fits well, it allows me to add the animations in Xaml and event handlers in the code behind, allowing the designer to tweak the animations to produce the desired effect.
So now we have away to play around with the different tweens and how they effect the various Transforms, we can also hit the Xaml button and get the Xaml required to recreate the Storyboard. The next job is to get everything working in WPF. I created a new WPF assembly and stuck Keons' library in. Next up add a reference from Baby Smash! project to the tweener project. Find the User Control shape that I want to change and add this code into the Resources collection of the Grid we also need to add the RenderTransformOrigin and set the value. Finally I needed to add the Render, Rotate, Scale and Skew transform to the Transform group collection of the grid. Hit F5 and i get to see my shape and the tween animation that I created in the Silverlight app.
There are a couple of problems with my approach; first is that we are duplicating the tweening code in all the User Controls; and second problem is randomness, if I want to keep the equation applied to the shape but randomly change the from and to values this is currently not possible. I style may help here as Styles support animations, however I am referencing UI Elements that are in the Grid and this could cause some issues with regards to Scoping. My other choice is to add the animations into another Xaml file and use a Resource Dictionary. Keons' Library is best used inside a Control Template, however the Baby Smash! shapes are User Controls which contain a layout grid that hosts other UI Elements unfortunately these controls do not inherit from Control and thus I am unable to use the Control Template. As I could not make a decision I thought that I would attempt both the Style route and the Resource dictionary. I created an empty style for the layout root grid and moved the tweening Xaml into here, and that is about as far as it went, I got an exception at runtime complaining that it could not find the target. This is the scoping issue that mentioned earlier as the UI Element that we want to target is out of scope. So next up is the Resource Dictionary. I created the Resource Dictionary in Blend and moved the tweening Storyboard into the Resource Dictionary, final part in Xaml is to just add in a reference from within the User Controls Resources collection to the new Resource Dictionary. Using this mechanism means that I have to trigger the tween for each shape from code behind, but its only a couple of lines. In Baby Smash! the figure generator is where most of the action takes place so in there I added some code to kick off the animation for shape. I have now replaced the duplicate code with a single Storyboard that we have in the Resource Dictionary, cool, but what about Random changing of the tweening easing functions and input values ? To implement this part I iterate over all the Children which in this case are DoubleAnimationUsingKeyFrames and call on of the Utility methods in Baby Smash! to get two random numbers generated. To change the other values we can simply add the other static method calls to change the inputs on the tween. So I guess the next question really is "What would it have taken to do it all in code behind ?? " You can see that if we go with all the animation tweening in code behind then it looks like this, yeah that's all it takes to get the animation working. By creating the Storyboards in code behind we loose the Verbose qualities of Xaml but we also loose the designer. My current thoughts are that if you have a number of UI Elements that you want to animate and these animations are pre baked by the Designer, go for the Xaml route. However, if you are looking for a solution to either dynamic items in an Items Control or you are looking to do something which is similar to Baby Smash! go with the code behind.
While I was building this code Dev Dave and Scorbs put together the FlickrViewr using the Animating Wrap Panel and Robbie updated his site and also posted a great post on animating panels. So the next job is to take Dev Daves' AWP and change his interpolations with Penners' Equations. I have got pretty far with this but I have a performance tweak that I would like to make before posting the source. What I am hoping to build is a versatile AWP where you can easily say in Xaml what tweening easing equation you want to use along with the inputs. You can download all the source from my SkyDrive or you can load up the URL and have a play with the app here.