Silverlight 3 3D Animation Using PlaneProjection and Storyboards

While SL3 doesn't add full 3D support, you can now transform elements in a 3D fashion.

The following videos are recommended (and form the basis of this example) but I've used simple opacity rather than transforming an element off the screen:

http://silverlight.net/learn/learnvideo.aspx?video=187308

http://silverlight.net/learn/learnvideo.aspx?video=189248

 

The new PlaneProject allow you to 'skew' an element in X, Y and Z dimensions. UI elements now have a Projection property which can contain a PlaneProjection:

<Grid.Projection>
  <PlaneProjection x:Name="HeadsGridProjection" RotationX="0" RotationY="0" RotationZ="0"></PlaneProjection>
</Grid.Projection>

The example below uses 2 grids containing a circle (the coin face) and text "Heads" or "Tails". There are 2 storyboards, the 1st rotates the heads to tails, the 2nd animation tails to heads. The storyboards call each other wheneach one finishes using the Completed event of the storyboard.

The code behind looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace _3DCoinFlip
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
      
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            // Automatically start the 1st storyboard when the page loads
            FlipToTails.Begin();
        }
       
        private void FlipToTails_Completed(object sender, EventArgs e)
        {
            // When the head-->tails animation completes, start the tails-->heads animation
            FlipToHeads.Begin();
        }

        private void FlipToHeads_Completed(object sender, EventArgs e)
        {
            // When the tails-->heads animation completes, start the head-->tails animation
            FlipToTails.Begin();
        }
    }
}

 And the XAML:

<UserControl x:Class="_3DCoinFlip.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
    Loaded="UserControl_Loaded" >
    <UserControl.Resources>
       
        <Style TargetType="Grid" x:Key="CoinFace">
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="200"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="CoinText">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="FontSize" Value="48"/>
        </Style>
       

        <Storyboard x:Name="FlipToTails" Completed="FlipToTails_Completed" >
            <!-- heads side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="HeadsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="90"/>
            </DoubleAnimationUsingKeyFrames>



            <!-- Tails Side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="TailsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="270"/>
                <SplineDoubleKeyFrame KeyTime="00:00:02" Value="360"/>
            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="Tails"
                                           Storyboard.TargetProperty="Opacity">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01.01" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>



        <Storyboard x:Name="FlipToHeads" Completed="FlipToHeads_Completed">
            <!-- tails side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="TailsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="90"/>
            </DoubleAnimationUsingKeyFrames>



            <!-- heads Side -->
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="HeadsGridProjection"
                                           Storyboard.TargetProperty="RotationY">
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="270"/>
                <SplineDoubleKeyFrame KeyTime="00:00:02" Value="360"/>
            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="Heads"
                                           Storyboard.TargetProperty="Opacity">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/>
                <SplineDoubleKeyFrame KeyTime="00:00:01.01" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <StackPanel>
            <Grid>
                <Grid Name="Heads" Style="{StaticResource CoinFace}">
                    <Grid.Projection>
                        <PlaneProjection x:Name="HeadsGridProjection" RotationX="0" RotationY="0" RotationZ="0"></PlaneProjection>
                    </Grid.Projection>
                    <Ellipse Stretch="Fill" Fill="Silver"/>
                    <TextBlock Style="{StaticResource CoinText}">Heads</TextBlock>
                </Grid>
                <Grid Name="Tails" Style="{StaticResource CoinFace}" Opacity="0">
                    <Grid.Projection>
                        <PlaneProjection x:Name="TailsGridProjection" RotationX="0" RotationY="0" RotationZ="0"></PlaneProjection>
                    </Grid.Projection>
                    <Ellipse Stretch="Fill" Fill="Gold"/>
                    <TextBlock Style="{StaticResource CoinText}">Tails</TextBlock>
                </Grid>
            </Grid>
        </StackPanel>
    </Grid>
</UserControl>

 

SHARE: