(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

Floating Visual Elements

(129 votes)
Miroslav Miroslavov
>
Miroslav Miroslavov
Joined Nov 24, 2009
Articles:   8
Comments:   6
More Articles
5 comments   /   posted on May 04, 2010
Categories:   White Papers , General

This article is compatible with the latest version of Silverlight.

This is part 2 of the series “Silverlight in Action”.

Here we’re sharing our experience from the amazing CompletIT web site.

As you may already know, every Silverlight application “must” have some objects floating around in a quite 3D manner. For example, let’s make a panel with happy faces floating around the screen in a controlled way, like this one.

See how it looks

Floating

Floating in Action

Get Microsoft Silverlight

Idea

The idea is to create an attached behavior for a panel, so that when enabled, through attached property it’ll make all panel’s children float around. To make this effect we will use PlaneProjection and TranslateTransform. We’ll create Storyboard that will animate these properties, to random values (but in controlled manner with a threshold) and when it completes – the animation will begin again with changed “To” by random. This way we’ll create random continuous floating of the visual objects.

Implementation

We need a class that holds the attached property. Let’s name it FloatingService. It has one attached property, for instance IsChildrenFloating of type boolean to trigger the behavior and two more properties to handle the Maximum allowed values for the PlaneProjection and TranslateTransform. So when IsChildrenFloating is attached to the panel with value of true, all its children will start floating.

This is how we control the animation in the FloatingService class.

 var panel = sender as Panel;
 if (panel != null)
 {
     var projectionMax = GetProjectionMax(panel);
     var translateMax = GetTranslateMax(panel);
  
     foreach (UIElement child in panel.Children)
     {
         var storyboard = new Storyboard();
   
         PlaneProjection planeProjection;
         child.EnsureProjection(out planeProjection);
  
         DoubleAnimation projectionX = AnimationFactory.CreateProjectionXAnimation(planeProjection, random.Next(-projectionMax, projectionMax), seconds);
         DoubleAnimation projectionY = AnimationFactory.CreateProjectionYAnimation(planeProjection, random.Next(-projectionMax, projectionMax), seconds);
         DoubleAnimation projectionZ = AnimationFactory.CreateProjectionZAnimation(planeProjection, random.Next(-projectionMax, projectionMax), seconds);
  
         storyboard.Children.Add(projectionX);
         storyboard.Children.Add(projectionY);
         storyboard.Children.Add(projectionZ);
  
         ScaleTransform scale;
         TranslateTransform translate;
         RotateTransform rotate;
         SkewTransform skew;
         child.EnsureTransforms(out scale, out rotate, out skew, out translate);
   
         DoubleAnimation translateX = AnimationFactory.CreateTranslateXAnimation(translate, random.Next(-translateMax, translateMax), seconds);
         DoubleAnimation translateY = AnimationFactory.CreateTranslateYAnimation(translate, random.Next(-translateMax, translateMax), seconds);
   
         storyboard.Children.Add(translateX);
         storyboard.Children.Add(translateY);
   
         storyboard.Completed += (s, e1) =>
                                     {
                                         projectionX.To = random.Next(-projectionMax, projectionMax);
                                         projectionY.To = random.Next(-projectionMax, projectionMax);
                                         projectionZ.To = random.Next(-projectionMax, projectionMax);
                                         translateX.To = random.Next(-translateMax, translateMax);
                                         translateY.To = random.Next(-translateMax, translateMax);
                                         storyboard.Begin();
                                     };
         storyboard.Begin();
     }
 }

So we create Storyboard from code, to hold the 5 animations – for rotating X,Y,Z and translating X,Y. And when the Storyboard finishes we choose new random values for end of the animations and start it again.

And now we only need to use the attached behavior to begin the floating of visuals.

How to use the behavior

 <StackPanel FloatingObjects:FloatingService.IsChildrenFloating="True"
             FloatingObjects:FloatingService.TranslateMax="10"
             FloatingObjects:FloatingService.ProjectionMax="25"
             Orientation="Horizontal"
             VerticalAlignment="Center">
     <StackPanel.Resources>
         <Style TargetType="ContentControl"
                x:Key="faceControl">
            <Setter Property="Height"
                     Value="75" />
            <Setter Property="Width"
                     Value="75" />
            <Setter Property="Margin"
                     Value="10" />
            <Setter Property="Effect">
                <Setter.Value>
                     <DropShadowEffect BlurRadius="5"
                                       Color="Black"
                                       Opacity=".7" />
                 </Setter.Value>
             </Setter>
            <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate>
                         <Grid>
                             <Rectangle Fill="{TemplateBinding Background}" />
                             <Ellipse Height="10"
                                      Width="10"
                                      Fill="Blue"
                                      Margin="20 20 0 0"
                                      HorizontalAlignment="Left"
                                      VerticalAlignment="Top" />
                             <Ellipse Height="10"
                                      Fill="Blue"
                                      Width="10"
                                      Margin="0 20 20 0"
                                      HorizontalAlignment="Right"
                                      VerticalAlignment="Top" />
                             <Path Data="M0,0 A 10, 10 0 0 0 25, 0"
                                   Stroke="#FFFA0D0D"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Bottom"
                                   Margin="0 0 0 10"
                                   StrokeThickness="2" />
                         </Grid>
                     </ControlTemplate>
                 </Setter.Value>
             </Setter>
         </Style>
     </StackPanel.Resources>
  
     <ContentControl Style="{StaticResource faceControl}"
                     Background="Yellow" />
     <ContentControl Style="{StaticResource faceControl}"
                     Background="Silver" />
     <ContentControl Style="{StaticResource faceControl}"
                     Background="Cyan" />
     <ContentControl Style="{StaticResource faceControl}"
                     Background="Green" />
     <ContentControl Style="{StaticResource faceControl}"
                     Background="Brown" />
 </StackPanel>

Download the code

Stay tuned for the next articles from this series coming up next week.


Subscribe

Comments

  • -_-

    RE: Floating Visual Elements


    posted by Aaron on Apr 28, 2010 16:21

    Brilliant!  You guys rock!

    Smoke and flying piggies next I hope?  :)

  • -_-

    RE: Floating Visual Elements


    posted by p., on May 31, 2010 05:03
    this is gud information
  • -_-

    RE: Floating Visual Elements


    posted by Roshini on Aug 30, 2010 08:35
    Very nice!!!
  • forgetu

    Re: Floating Visual Elements


    posted by forgetu on Aug 18, 2011 09:19

    Thanks.

  • Christine

    Re: Floating Visual Elements


    posted by Christine on Feb 21, 2012 06:09
    I think I am going to hire a freelance artist to help me with creating the graphics that I would need for one of my projects, and then try to figure out how to make the floating visual elements introduced in this guide work in that project. Thanks for sharing!

Add Comment

Login to comment:
  *      *       

From this series