Silverlight 3 - Create a nice Navigation Flip
Here is a sample we made at RunAtServer using Silverlight 3 Perspective 3D feature and the new Navigation API to create a nice navigation flip!
Video
How does it work ?
Short story
The app use the new navigation api to navigate while animating a 3d flip transformation.
Long story
The main xaml has a Frame element in a StackPanel with an associated PlaneProjection:
<StackPanel x:Name="mainContentPageContainer" Grid.Row="2"> <StackPanel.Projection> <PlaneProjection x:Name="mainPanelProjection" /> </StackPanel.Projection> <navigation:Frame x:Name="mainContentPage" Source="HomePage"></navigation:Frame> </StackPanel>
There are 2 Storyboards (FlipStart and FlipEnd) with one animation each:
- The first Storyboard animate the RotationY property of the PlaneProjection (mainPanelProjection) from 0 to 90 (half 180°) during 1s.
The navigation will happen when it complete. - The second animate the RotationY property of the PlaneProjection from 270 to 360 (half 180°) and NOT from 90 to 180, we’ll see that later.
Note the Easing function to add a bounce effect at the end of the page flip.
<Storyboard x:Name="FlipStart"> <DoubleAnimation From="0" To="90" Duration="00:00:1" Completed="Flip1Half_Completed" Storyboard.TargetName="mainPanelProjection" Storyboard.TargetProperty="RotationY"> </DoubleAnimation> </Storyboard> <Storyboard x:Name="FlipEnd"> <DoubleAnimation From="270" To="360" Duration="00:00:1" Storyboard.TargetName="mainPanelProjection" Storyboard.TargetProperty="RotationY"> <DoubleAnimation.EasingFunction> <BounceEase Bounces="2" EasingMode="EaseOut" /> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard>
To learn more on PlaneProjection and Perspective 3D read my previous post:
http://weblogs.asp.net/lduveau/archive/2009/03/31/silverlight-3-playing-with-perspective-3d.aspx
The menu is composed of HyperlinkButton elements whose Click events check if the requested page is not the current page and begin the first Storyboard (FlipStart).
private void Menu_Click(object sender, RoutedEventArgs e) { menuClicked = sender as HyperlinkButton; if (mainContentPage.Source.ToString() != menuClicked.Tag.ToString()) FlipStart.Begin(); }
This is where the magic happens:
Remember the first StoryBoard (FlipStart) apply a 3d transform on the StackPanel from 0 to 90°. When it complete it just navigate to the requested page, then the next Storyboard (FlipEnd) begins! But if we do just that the new page would be inversed, that’s why after the first 90°, the page do a full 180°, and then finish animating a new 90°… makes sense?
void Flip1Half_Completed(object sender, EventArgs e) { if(menuClicked != null) mainContentPage.Navigate(new Uri(menuClicked.Tag.ToString(), UriKind.Relative)); FlipEnd.Begin(); }
That’s it!
The code attached is a bit more complex as I added the direction change after each menu click, as well as selected menu backcolor management.
Download the code (Silverlight 3 beta needed)