WPF Tilt Effect Behavior

Update: Added KeepDragging Property and TiltFactor Property and the possibility to attach the behavior to a panel

tiltwpf
tiltwpf

One of the things I wanted to add to my metro UI controls collection is adding the Tilt effect that uses WP7, the issue in WPF is that it has not the same features as Silverlight or WP7 because WPF uses real 3D. So in order to make a simple Tilt effect is real complex code.
After looking on the internet I found the first great step in order to create the behavior:
Greg Schechter’s Planeator

If you take a look at his code, it is absolutely great because it is simplified to the maximum the control and the binding:

<pl:Planerator RotationY="35">
           <StackPanel Orientation="Horizontal" ... >
                <StackPanel>
                    <Label  FontSize="24" Content=" " Foreground="#FF000000"/>
                    <Border ... >
                        <MediaElement x:Name="myMediaElement" />
                    </Border>
               </StackPanel>
                <ListBox ... />
            </StackPanel>
</pl:Planerator>

The issue is that I have to add the StackPanel inside the Container, but I can create a behavior that replaces the child control adding a Planerator, to have simply:

<Button Margin="271,155,12,12"  Content="Button" FontSize="36" Background="#FF00B1FF" Foreground="White">
     <i:Interaction.Behaviors>
         <pl:TiltBehavior/>
    </i:Interaction.Behaviors>
 </Button>

Another example

<Grid Canvas.Left="12" Canvas.Top="116" Height="192" Name="grid1" Width="380">
            <i:Interaction.Behaviors>
                <pl:TiltBehavior KeepDragging="False" TiltFactor="20" />
            </i:Interaction.Behaviors>
            <Button Background="GreenYellow" Content="Button" FontSize="36" Foreground="White" Height="66" Margin="10,10,191,116" Width="179"/>
            <Button Background="DarkOrange" Content="Button" FontSize="36" Foreground="White" Height="66" Margin="144,93,57,33" Width="179"/>
        </Grid>

And that’s all now you have the tilt effect like WP7 in WPF.
Note: At this moment I have tested it in a Grid, Wrappanel and in a Canvas, might be in another panel is necessary to add the dependency properties to the Planerator.

Tilt example, rename .doc to .7z

Now I will implement this behavior to the metro buttons that I have created for the WPF Metro template.

Advertisements

8 thoughts on “WPF Tilt Effect Behavior

  1. Hi mareinsula,

    this is a very nice effect. Have been looking for something like that for a while.
    We are currently trying to use it in an updated Surface 2.0 application.
    Though we are having trouble ajusting it to respond properly to Multitouch input.

    If you have any idea how do modify it from mouse events to touchevents we would be very interested.

    1. I have just took a look to the TouchDevice class and it has to be controlled using events Msdn TouchDevice so I will adapt it doing the following, I will inherit a grid, for instance, adding the touch events and a pair of properties in order to emulate Mouse.GetPosition(RotatorParent.Child), and Mouse.LeftButton == MouseButtonState.Pressed). Doing that I think it works like a charm. Anyway I think that Surface 2.0 will be the base of W8 tablet edition so I will adapt the code in a few weeks in order to add the surfacelistbox, and else. ah, Thank’s a lot for the feedback.

  2. Great work on this. I modified your code slightly though. In your CompositionTarget_Rendering method you can change it so that when you drag off the tile it tilts back to normal by simply adding an else statement like so

    if (current.X >= 0 && current.X = 0 && current.Y <= (attachedElement as FrameworkElement).ActualHeight)
    {
    RotatorParent.RotationY = -1 * TiltFactor + current.X * 2 * TiltFactor / (attachedElement as FrameworkElement).ActualWidth;
    RotatorParent.RotationX = -1 * TiltFactor + current.Y * 2 * TiltFactor / (attachedElement as FrameworkElement).ActualHeight;
    }
    else
    {
    RotatorParent.RotationY = RotatorParent.RotationY – 5 < 0 ? 0 : RotatorParent.RotationY – 5;
    RotatorParent.RotationX = RotatorParent.RotationX – 5 < 0 ? 0 : RotatorParent.RotationX – 5;
    }

    This gives it an effect that would be more similar to the Windows Phone tilt. Other than that small change brilliant work here. This helped me out of a serious bind I was in moving some of our desktop applications over to a Windows 8 "look and feel"

    1. Thank you for your tip, I have not checked my WPF code since a long time ago, I am involved in several WP8 projects, and soon the will be released. I will update when I have time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s