Monday, December 22, 2008

The Carousel Silverlight Application … Awesome!

What did our esteemed delegator tried and did …

He tried to create a simple Fish Eye type menu where the icons are spaced evenly in degrees around a circle.

How did he do it?

First he needed to load the images into his Silverlight page. This was done by dynamically adding any number of images into an array and the setting the canvas top and left to the appropriate position. Easier said than done.

How do you get the X and Y coordinates on the outer edge of a circle? This is a question with which he tortured everyone in his team and in the true spirit of things, everyone vanished on a separate thread doing research for the delegator. 

The scene:

clip_image001

clip_image002                This is the point where he wants the X and Y coordinate.

clip_image003                This is the angle that we need to work with.

He used C# for the language…You need the following formulas to do this:

First, the Math .NET object, so that you can do the COSINE and SINE calculations.

The COSINE and SINE needs the radians to get the correct coordinates. To calculate the radian from an angle you need

  • Radian = ANGLE * Pi / 180

Then

  • X = Radius * COS(Radian)
  • Y = Radius * SIN(Radian)

Once he could calculate the x and y coordinates he was ready to rock and roll. Here is the method he used to add the animations to the images.

   1: private void addAnimation(Image image, double angle, double x, double y)
   2: {
   3:     TransformGroup tfGroup = new TransformGroup();
   4:  
   5:     //MouseOver animation for resizing
   6:     Storyboard sbMouseOver = new Storyboard();
   7:     ScaleTransform tfGrow = new ScaleTransform();
   8:     tfGrow.SetValue(NameProperty, "tfGrow_" + image.Name);
   9:     tfGrow.CenterX = 24;
  10:     tfGrow.CenterY = 24;
  11:     tfGrow.ScaleX = 1;
  12:     tfGrow.ScaleY = 1;
  13:     tfGroup.Children.Add(tfGrow);
  14:  
  15:     DoubleAnimation daGrowX = new DoubleAnimation();
  16:     daGrowX.SetValue(Storyboard.TargetNameProperty, tfGrow.GetValue(NameProperty));
  17:     daGrowX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(ScaleTransform.ScaleX)"));
  18:     daGrowX.To = 2;
  19:     daGrowX.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
  20:     daGrowX.AutoReverse = true;
  21:     sbMouseOver.Children.Add(daGrowX);
  22:  
  23:     DoubleAnimation daGrowY = new DoubleAnimation();
  24:     daGrowY.SetValue(Storyboard.TargetNameProperty, tfGrow.GetValue(NameProperty));
  25:     daGrowY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(ScaleTransform.ScaleY)"));
  26:     daGrowY.To = 2;
  27:     daGrowY.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
  28:     daGrowY.AutoReverse = true;
  29:     sbMouseOver.Children.Add(daGrowY);
  30:  
  31:     image.Resources.Add("sbMouseOver_" + image.Name, sbMouseOver);
  32:  
  33:     //Startup storyboard - Rotates the images in a circle
  34:     Storyboard sbStartLoading = new Storyboard();
  35:     TranslateTransform tfMove = new TranslateTransform();
  36:     tfMove.SetValue(NameProperty, "tfMove_" + image.Name);
  37:     tfMove.X = x+200;
  38:     tfMove.Y = y+200;
  39:     tfGroup.Children.Add(tfMove);
  40:  
  41:     DoubleAnimationUsingKeyFrames daMoveX = new DoubleAnimationUsingKeyFrames();
  42:     daMoveX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(TranslateTransform.X)"));
  43:     daMoveX.SetValue(Storyboard.TargetNameProperty, tfMove.GetValue(NameProperty));
  44:     DoubleAnimationUsingKeyFrames daMoveY = new DoubleAnimationUsingKeyFrames();
  45:     daMoveY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(TranslateTransform.Y)"));
  46:     daMoveY.SetValue(Storyboard.TargetNameProperty, tfMove.GetValue(NameProperty));
  47:     
  48:     TimeSpan nextTime = new TimeSpan(0, 0, 0, 0, 0);
  49:     LinearDoubleKeyFrame myFrameX = new LinearDoubleKeyFrame();
  50:  
  51:     LinearDoubleKeyFrame myFrameY = new LinearDoubleKeyFrame();
  52:  
  53:     for (int i = 0; i < 72; i++)
  54:     {
  55:         angle += 5;
  56:         if (angle > 360)
  57:         {
  58:             angle -= 360;
  59:         }
  60:         double aniAngle = (angle) * Math.PI / 180;
  61:  
  62:         double nuX = 150 * Math.Cos(aniAngle);
  63:         double nuY = 150 * Math.Sin(aniAngle);
  64:  
  65:         TimeSpan nuTime = nextTime.Add(new TimeSpan(0, 0, 0, 0, 100));
  66:  
  67:         //LinearDoubleKeyFrame 
  68:         myFrameX = new LinearDoubleKeyFrame();
  69:         myFrameX.KeyTime = KeyTime.FromTimeSpan(nuTime);
  70:         myFrameX.Value = nuX+200;
  71:         daMoveX.KeyFrames.Add(myFrameX);
  72:  
  73:         //LinearDoubleKeyFrame 
  74:         myFrameY = new LinearDoubleKeyFrame();
  75:         myFrameY.KeyTime = KeyTime.FromTimeSpan(nuTime);
  76:         myFrameY.Value = nuY+200;
  77:         daMoveY.KeyFrames.Add(myFrameY);
  78:  
  79:         nextTime = nuTime;
  80:     }
  81:  
  82:     daMoveX.Duration = new Duration(nextTime);
  83:     daMoveY.Duration = new Duration(nextTime);
  84:     sbStartLoading.Children.Add(daMoveX);
  85:     sbStartLoading.Children.Add(daMoveY);
  86:  
  87:     image.Resources.Add("sbStartLoad_" + image.Name, sbStartLoading);
  88:     image.RenderTransform = tfGroup;
  89: }


In the end he came up with a rotating circle of images which independently animate.

clip_image002

Well done Mr Delegator!

2 comments:

  1. can you share the application pls. The full source code or at least just the working application. Im trying to do smth like that but stucked. And its very important im gonna use it in my school project which will lasted in 10 days :)
    thanks from Turkey.
    (kemalcankara@hotmail.com)

    ReplyDelete
  2. Hi!
    Can you share the app, please. The full source code or at least just the working application.
    This will help much because i do a job that should have a carousel in silverlight.

    leandro9119@gmail.com

    Now thanks.

    ReplyDelete