Search code examples
windows-phone-7expression-blend

Smoothly rotate controls from Portrait to Landscape in Windows Phone 7


I am displaying a Canvas and would like it to rotate smoothly through 90 degrees when the phone is rotated from Portrait to Landscape.

It seems that when the phone is rotated (at least in the emulator) the canvas is automatically rotated but the transition is not a smooth one, (i.e. it goes from 0 to 90 degrees) - I assume this is the auto-layout function.

I would like my canvas to rotate smoothly, i.e. not suddenly jump from 0 to 90 degrees (as the auto-layout function does). I have setup two states in Blends state manager and I call the following:

    private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
    {
        if ((e.Orientation & PageOrientation.Landscape) != 0)
        {
            VisualStateManager.GoToState(this, "Landscape", true);
        }
        else
        {
            VisualStateManager.GoToState(this, "Portrait", true);
        }
   }

I have set up transitions between these as follows:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="OrientationStates">
        <VisualStateGroup.Transitions>
            <VisualTransition From="Portrait" GeneratedDuration="0" To="Landscape">
                <Storyboard>
                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="LayoutRoot">
                        <EasingDoubleKeyFrame KeyTime="0" Value="90"/>
                        <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </VisualTransition>
            <VisualTransition From="Landscape" GeneratedDuration="0" To="Portrait">
                                        <Storyboard>
                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="LayoutRoot">
                        <EasingDoubleKeyFrame KeyTime="0" Value="90"/>
                        <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </VisualTransition>
        </VisualStateGroup.Transitions>
        <VisualState x:Name="Portrait"/>
        <VisualState x:Name="Landscape"/>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

The interesting point is that it seems that the transition should START at 90 degrees and rotate back to 0 because it seems that the auto-layout function kicks in first. Is this what I should be doing?

Or how do I override the auto-layout feature so that the transition is triggered first?

I am only working in the emulator (waiting for the lengthy App Hub registration process) so it is difficult to see if this is the right way to go.


Solution

  • You might be interested in David Anson's implementation of this effect here:

    http://blogs.msdn.com/b/delay/archive/2010/09/28/this-one-s-for-you-gregor-mendel-code-to-animate-and-fade-windows-phone-orientation-changes-now-supports-a-new-mode-hybrid.aspx

    It is all open source.