Frame-based animation in WPF

I recently was working on the ubiquitous photo/slideshow app in WPF.  This is something I’ve been tinkering with off and on for last 6 months.  The original intention was to create a photo slideshow application for my upcoming wedding.  Being the nerd, a static video slideshow just wasn’t going to cut it.

Along the way I learned quite a bit about keeping performance up and memory usage low while working with tons of images.  It’s finally in a position where it’s almost done and I wanted to add a few tweaks.  The photos zoom in and randomly arrange like they were dropped on a table.  Once there, they show one by one. 

I wanted to add a little random “drift” while the image was showing to make it more interesting to the eye.  I started originally by creating random storyboards and listening to the Storyboard.Completed event.  When the event fired I created a new storyboard to animate my photo’s Canvas.Left and Top properties.  This worked, but there was an annoying lag between the stop and start of the animations. 

I wanted to move to a frame-based animation rather than WPF’s built-in time-based animation style.  I could have used a timer to update my properties, but I wanted to work more within the constraints of WPF.  I found articles for Silverlight that indicate an empty storyboard with no duration will fire it’s completed event on the next frame, there you can update your properties and restart the storyboard to update your properties every frame.  Although this may work in Silverlight, I could not get it to work in WPF.  Though as I look back, I didn’t try setting the Duration to “0:0:0”.  I wonder if that would work?

Regardless, the technique I ended up using was listening to CompositionTarget.Rendering event it code-behind.  The event fires before your UI renders each frame, allowing you to hook in and do frame based animation.

For more information, you can go here:

2 Replies to “Frame-based animation in WPF”

Leave a Reply

Your email address will not be published. Required fields are marked *