Simultaneous and dynamic animations

by gleblanc 15. September 2008 10:47
In this post, we'll show how to perform several animations at the same time. To illustrate this, we will implement a carrousel with images that remain permanently vertical :

Project / source code

So, let's write the Silverlight application. We'll write it as if we didn't know the number of images at time of writing / compiling the program. Due to that constraint, adding images and forcing animations has to be done dynamically, by program, at run-time. I know the program presented here is not be 100% independant of number of images (since images are inserted as resource at development time) but we accept such a restriction to keep things simple. We are discussing here animations, not remote access to images.

We are changing some dimensions (to take care of my BlogEngine restrictions) and put an image (SilverlightLogo.jpg) in the background of our main container (a grid named LayoutRoot as usual). Nothing very special yet. 

<UserControl x:Class="Anim1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="500" Height="500">
    <Grid x:Name="LayoutRoot" >
     <Grid.Background>
      <ImageBrush ImageSource="SilverlightLogo.jpg" Stretch="Uniform" />
     </Grid.Background>
 
    </Grid>
</UserControl> 

We insert a transparent canvas in front of our main LayoutRoot container. Since this canvas will be in rotation, we name it RotatingSurface. Inside this canvas, we insert a rail. Images will be fixed on this rail. We also decide to react to the Loaded event, in order to initialize things. 

  <Grid x:Name="LayoutRoot" >
    .....
    <Canvas x:Name="RotatingSurface" Width="400" Height="400"
            Background="Transparent" Loaded="RotatingSurface_Loaded" >
 
     <Ellipse x:Name="rail" Canvas.Left="50" Canvas.Top="50" Width="300"
              Height="300" Stroke="Gray" StrokeThickness="10" />
    </Canvas>
  </Grid>

We are here adding five images as resource (DaVinci, Newton, Mozart, Shakespeare and Einstein, all of same size, 90x110) but we code our program to be more general (doing so, adding more images will just require a change in the tabNames array).  

In Page.xaml.cs, we add (outside of functions) :

   string[] tabNames = {"DaVinci", "Shakespeare", "Newton", "Mozart", "Einstein" };
   Image[] tabImages;

In the RotateSurface_Loaded function :

  • we create an array of images (remember, to keep things simple, these images were inserted in the project and are thus automatically copied into the XAP file),
  • place them along the the rail (a bit of trigonometry, with Sin and Cos, is needed but nothing worth a Nobel prize),
  • finally add each of these images as children of the canvas.

  private void RotatingSurface_Loaded(object sender, RoutedEventArgs e)
  { 
   int N = tabNames.Length;                // number of images
   // get radius and position of rail
   double wRail = rail.ActualWidth / 2;    // width of rail
   double hRail = rail.ActualHeight / 2;   // height of rail
   double xRail = (double)rail.GetValue(Canvas.LeftProperty);
   double yRail = (double)rail.GetValue(Canvas.TopProperty); 
   double wImage = 90, hImage = 110;       // same size for all images 
   // create an array of images (N depending on tabNames array)
   tabImages = new Image[N];
   for (int i = 0; i < N; i++)
   {
    tabImages[i] = new Image();
    tabImages[i].Source=new BitmapImage(new Uri(tabNames[i]+".jpg",
                                                UriKind.Relative));
    tabImages[i].Width = wImage;
    tabImages[i].Height = hImage;

    // put image at the right place
    double X = wRail * Math.Cos(i * 2 * 3.14 / N) + xRail + wRail - wImage / 2;
    double Y = wRail * Math.Sin(i * 2 * 3.14 / N) + yRail + hRail - hImage / 2;
    tabImages[i].SetValue(Canvas.LeftProperty, X);
    tabImages[i].SetValue(Canvas.TopProperty, Y);

    RotatingSurface.Children.Add(tabImages[i]);
   }
  }

We need to add

 using System.Windows.Media.Imaging;

to make BitmapImage known by Visual Studio. 

At this point, images are displayed but the result is still very static (nothing in rotation yet) :

So, let's animate the canvas. We define for the RotatingSurface canvas :

  • the rotation point, at the center (coordinates are relative in RenderTransformOrigin),
  • a rotation transform named rotCanvas (the storyboard will animate its Angle property),
  • a storyboard (named stb) that animates Angle forever from 0 to 360° in 10 seconds :

  <Canvas x:Name="RotatingSurface" Width="400" Height="400" 
          Background="Transparent" Loaded="RotatingSurface_Loaded"
          RenderTransformOrigin="0.5, 0.5">
   <Canvas.RenderTransform>
    <RotateTransform x:Name="rotCanvas" />
   </Canvas.RenderTransform>
   <Canvas.Resources>
    <Storyboard x:Name="stb" RepeatBehavior="Forever">
     <DoubleAnimation Storyboard.TargetName="rotCanvas"
                      Storyboard.TargetProperty="Angle" From="0" To="360"
                      Duration="0:0:10" />
    </Storyboard>
   </Canvas.Resources>
   <Ellipse x:Name="rail" Canvas.Left="50" Canvas.Top="50"
            Width="300" Height="300" Stroke="Gray" StrokeThickness="10" />
  </Canvas>

As last instruction in the RotatingSurface_Loaded function, we start the stb storyboard :

 stb.Begin();

 

Here is the result of the current implementation. It doesn't give full satisfaction :

To keep images vertical, we need to add a rotation to each image : forever, from 0 to -360° in 10 seconds. Such a storyboard has to be added dynamically (remember, we don't know the number of images and these images were created dynamically).

To be able, later on, to start / pause these storyboards, we declare and initialize an array of N storyboards. For each image, we create by program :

  • a RotateTransform (we'll animate its Angle property),
  • a storyboard,
  • a DoubleAnimation that will animate Angle and that will pertain to the storyboard just created.

   Storyboard[] tabStoryboards; // outside of functions
   .....
   tabStoryboards = new Storyboard[N];
   for (int i = 0; i < N; i++)
   {
    .....       // create an Image in tabImages[i]
    RotateTransform rt = new RotateTransform();
    tabImages[i].RenderTransform = rt;
    tabImages[i].RenderTransformOrigin = new Point(0.5, 0.5);
    Storyboard st = new Storyboard();
    DoubleAnimation da = new DoubleAnimation();
    da.Duration = new Duration(new TimeSpan(0, 0, 10));
    da.To = -360;
    da.RepeatBehavior = RepeatBehavior.Forever;
   
    Storyboard.SetTargetProperty(da, new PropertyPath("Angle"));
    Storyboard.SetTarget(da, rt);
   
    st.Children.Add(da);
    tabStoryboards[i] = st;
    RotatingSurface.Children.Add(tabImages[i]);
   }


And now, to start the animation :

  stb.Begin();
  for (int i=0; i<N; i++) tabStoryboards[i].Begin(); 

You know the result, at the beginning of this post.

 



Tags:

Comments

9/17/2008 8:50:51 AM #

Trackback from Community Blogs

Silverlight Cream for September 16, 2008 -- #369

Community Blogs

9/17/2008 9:06:25 AM #

Is there a project for this sample?

Fallon Massey United States

9/17/2008 12:35:03 PM #

Great job!

As a mathematician, I guess I would have used translations and sinus and stuff like that, but your solution is really clear and simple and works perfectly.

Anna Poland

9/17/2008 5:16:26 PM #

Pingback from mgalinks.wordpress.com

2008 September 17 - Links for today « My (almost) Daily Links

mgalinks.wordpress.com

9/24/2008 10:34:47 PM #

Elegant

mike greenway United States

1/2/2009 9:17:30 PM #

well good combination of the greatest person in the history of human

Busby SEO Test Pinay United States

2/11/2009 9:18:45 AM #

Thanks for the great reference post

Free Service Manual United States

2/19/2009 8:26:39 PM #

Really neat... thanks.

London Tours United Kingdom

3/3/2009 9:40:29 AM #

woww great post! thanks!

learning selling United States

3/9/2009 11:28:52 AM #

silverlight is for real app

My Little Blogs United States

3/17/2009 11:45:55 AM #

It's neat and amazing. A really great post!

Web Conferencing United States

3/25/2009 11:39:30 AM #

Thanks for this post,, really amazing.

tnomeralc web design toys United States

4/20/2009 6:20:40 PM #

Thanks for a nice and informative site. Somehow I was drawn to reading the post and I enjoyed a lot. Have a nice day!

Criminal Background Check United States

7/14/2009 3:05:17 PM #

I like how you write.Are you interesting in a part time writer job?

Jacques Lemans United States

7/21/2009 8:53:41 AM #

I really appreciate the kind of topics you post here, that's much as I think and we can apply it to many ways. Thanks for sharing us a great information that is actually helpful. Good day!

buy blog reviews United States

7/24/2009 9:26:56 PM #

I don't like your template but your posts are quite good so I will check back!

Lucien Piccard United States

8/5/2009 6:45:59 AM #

I usually don�t post in Blogs but your blog forced me to, amazing work.. beautiful �

payday loans United States

8/5/2009 6:46:02 AM #

Hi there, I found your blog on Google while seeking for first aid for a heart attack and your post looks very interesting for me.

payday loans United States

8/14/2009 5:22:45 PM #

Just what I was googling for! Thanks for sharing!

Web Designer San Diego United States

8/17/2009 12:47:20 PM #

Thanks for this great post - I don�t think I could say anything else that would do it justice.

How To Win Lottery United States

8/17/2009 12:47:24 PM #

I just couldn't leave your website before saying that I really enjoyed the quality information you offer. Will be back often to check up on new stuff you post!

San Diego Web Design United States

8/20/2009 10:41:30 AM #

This blog Is very informative , I am really pleased to post my comment on this blog . It helped me with ocean of knowledge so I really belive you will do much better in the future

Web design United Kingdom

8/24/2009 4:35:46 PM #

Funny, I actually had this on my mind a few days ago and now I come across your blog...

Learn & Master Guitar United States

8/24/2009 4:35:49 PM #

There are certainly a couple more details to take into consideration, but thanks for sharing.

Duck Hunting Canada United States

9/9/2009 2:42:35 PM #

There are certainly a lot more details to take into consideration, but thanks for sharing.

Internet marketing United Kingdom

9/11/2009 2:33:43 PM #

I was inspired by the coding and the blog of yours.I think I have read it twice because it was such an interesting demonstration by you.Clearly explained and defined the classes and functions.The rotation method has fascinated me. Thanks for this informative post.

SEO Company UK United Kingdom

9/13/2009 9:28:30 PM #

Toto ozn�men� o stavu doru.en� je generov�no automaticky.

payday online United States

9/14/2009 6:13:16 AM #

I leave a lot of comments on a lot of blogs each week - but there is one situation where I rarely leave a comment - even if the post deserves it.Good work

payday loans United States

9/14/2009 4:07:16 PM #

Where can I get free downloads of educational animations?

SEO Tools United States

9/15/2009 5:03:04 PM #

I havent any word to appreciate this post.....Really i am impressed from this post....the person who create this post it was a great human..thanks for shared this with us.

payday online United States

9/16/2009 5:38:36 PM #

Where can I get free downloads of educational animations?

basketball live score United States

9/16/2009 5:39:51 PM #

I havent any word to appreciate this post

live score United States

9/16/2009 5:40:40 PM #

I leave a lot of comments on a lot of blogs each week

live score United States

9/16/2009 5:58:20 PM #

I was inspired by the coding and the blog of yours.

live sport scores United States

9/16/2009 5:59:46 PM #

There are certainly a lot more details to take into consideration

championship live scores United States

9/16/2009 6:00:56 PM #

Funny, I actually had this on my mind a few days ago and now I come across your blog.

championship live scores United States

9/16/2009 6:02:45 PM #

There are certainly a couple more details to take into consideration, but thanks for sharing.

championship live scores United States

9/23/2009 7:54:01 PM #

Hi. I read a few of your other posts and wanted to know if you would be interested in exchanging blogroll links?

payday loans United States

9/23/2009 7:54:05 PM #

There is obviously a lot to know about this.  I think you made some good points in Features also.

payday loans United States

9/25/2009 9:27:38 PM #

thanks !! very helpful post!

bad credit loans United States

9/29/2009 7:58:41 AM #

Great overview. Your style of writing is really a joy to read.

Make Money Online United States

9/30/2009 11:35:53 AM #

Is there a project for this sample?

Tiffany Rings People's Republic of China

10/2/2009 4:15:18 PM #

Wow! what an idea ! What a concept ! Beautiful .. Amazing �

personal loan United States

10/2/2009 4:15:21 PM #

thanks !!  very helpful post!

personal loan United States

10/9/2009 7:04:42 PM #

Please add some more posts as I have nothing to read here already.

web design United Kingdom

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About the author

Gerard Leblanc is the author of several books (in french) on C++, C#, .NET and Silverlight (Eyrolles, Paris as publisher). See www.gleblanc.eu as the companion web site for these books (included sample programs).
He is Microsoft MVP for Silverlight.

MVP logo