Animate multiple transforms from C# – WPF

I have been stuck in the world of WPF for a while, hence the lack of posts. Things have calmed down and I am back.

Let’s talk about animating objects in WPF/XAML/C#. Animating multiple transforms in XAML is easy: setup the initial transforms, add a storyboard, set up an event trigger, and go. What about doing this in C#? And how do you animate multiple transforms in a TransformGroup from C#? Let’s take a look:

Overview:

  • Create your object (say a rectangle, button, user control, etc.)
  • Apply a TransformGroup to the object (add one or more of the following to the TranformGroup: TranslateTransform, ScaleTransform, SkewTransform, or RotateTransform)
  • In an event get the TransformGroup of the object and apply a DoubleAnimation to the particular Transform in the group

Screenshot
Animate multiple transforms screen shot

Code

        public Window1()
        {
            InitializeComponent();

            //Create event for the button
            btn.Click += new RoutedEventHandler(btn_Click);

            //Create a rectangle
            Rectangle rect = new Rectangle();
            rect.Name = "rect";
            rect.Width = 50;
            rect.Height = 50;
            rect.Fill = Brushes.Beige;

            //Add a TransformGroup to the rectangle (note the order)
            TransformGroup tg = new TransformGroup();
            tg.Children.Add(new TranslateTransform(50.0, 50.0));
            tg.Children.Add(new ScaleTransform(1.0,1.0));
            tg.Children.Add(new SkewTransform(1.0,1.0));
            tg.Children.Add(new RotateTransform(0.0,150.0,150.0));
            rect.RenderTransform = tg;

            //Add controls to the page
            cnvMain.Children.Add(rect);
        }

        void btn_Click(object sender, RoutedEventArgs e)
        {
            //Rectangle rect = cnvMain.FindName("rect") as Rectangle;
            Rectangle rect = cnvMain.Children[2] as Rectangle;

            //Define DoubleAnimation for Translate Transform
            DoubleAnimation daTranslateX = GenerateDoubleAnimation(300);
            DoubleAnimation daTranslateY = GenerateDoubleAnimation(300);

            //Get the TranslateTransform for the rectangle (note Children[0], we added TranslateTransform first)
            TranslateTransform tt = (rect.RenderTransform as TransformGroup).Children[0] as TranslateTransform;

            //Apply animation to the TranslateTransform
            tt.BeginAnimation(TranslateTransform.XProperty, daTranslateX);
            tt.BeginAnimation(TranslateTransform.YProperty, daTranslateY);

            ////Do the same for Scale
            DoubleAnimation daScaleX = GenerateDoubleAnimationDouble();
            DoubleAnimation daScaleY = GenerateDoubleAnimationDouble();
            ScaleTransform sct = (rect.RenderTransform as TransformGroup).Children[1] as ScaleTransform;
            sct.BeginAnimation(ScaleTransform.ScaleXProperty, daScaleX);
            sct.BeginAnimation(ScaleTransform.ScaleYProperty, daScaleX);

            //Do the same for Skew
            //DoubleAnimation daSkewX = GenerateDoubleAnimation(45);
            //DoubleAnimation daSkewY = GenerateDoubleAnimation(45);
            //SkewTransform skt = (rect.RenderTransform as TransformGroup).Children[2] as SkewTransform;
            //skt.BeginAnimation(SkewTransform.AngleXProperty, daSkewX);
            //skt.BeginAnimation(SkewTransform.AngleYProperty, daSkewY);

            //Do the same for Rotate
            DoubleAnimation daRotate = GenerateDoubleAnimation(360);
            RotateTransform rt = (rect.RenderTransform as TransformGroup).Children[3] as RotateTransform;
            rt.BeginAnimation(RotateTransform.AngleProperty, daRotate);
            rt.BeginAnimation(RotateTransform.CenterXProperty, daTranslateX);
            rt.BeginAnimation(RotateTransform.CenterYProperty, daTranslateY);
        }

        DoubleAnimation GenerateDoubleAnimation(int max)
        {
            DoubleAnimation da = new DoubleAnimation();
            da.To = randomNumber.Next(max);
            da.AccelerationRatio = .8;
            da.DecelerationRatio = .1;
            da.Duration = new Duration(TimeSpan.FromSeconds(2));

            return da;
        }

        DoubleAnimation GenerateDoubleAnimationDouble()
        {
            DoubleAnimation da = new DoubleAnimation();
            da.To = randomNumber.NextDouble();
            da.AccelerationRatio = .8;
            da.DecelerationRatio = .1;
            da.Duration = new Duration(TimeSpan.FromSeconds(2));
            return da;
        }

Download the project (not up yet). I am in the process of converting this to a Silverlight project. Please leave me some feedback or questions.

1 comment so far

  1. gurmeet on

    hi,
    Ur information is suffcient for starting..however i need some more help from you regarding WPF.
    I want to change a WPF usercontrol having rectangles in it using C#.. please help me out in this.

    thanks


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: