Monday, May 13, 2013

WP8 Tip: Using Manipulation Events to Animate a Clipping Mask

This is another post of the clipping mask series that I published last month (here and here). In this post, I’ll show you one way you can control a clipping mask by using manipulation events triggered by another control. It will give the illusion that the clipping mask is being controlled by touch input.

image    image    image

Working with animations on Windows Phone is a lot of fun, but you need to keep in mind that performance might suffer if you abuse it. That is why it is always good to put together basic samples to find the best way to achieve animations.

image

My advice is to break down complex animations and user interactions into smaller and simpler prototypes. Then you can work the very basics of each one of them. This is the way I encourage my team to work, and we have had amazing results on highly effective and productive rapid prototyping approaches.

image

So, for this sample, I want to use the previous clipping mask we created, consisting of two rectangles. One of them (green), with a RectangleGeometry as clipping mask, with a TranslateTransform component. Again, by translating the mask’s transform on the Y axis, it reveals the underlying rectangle (blue) while moving up or down. Check out my post for a full explanation on this technique.

This time, instead of using triggers to run a storyboard animating the mask’s transform, I want to use touch events to control the mask’s movement. One way of doing it is to overlay a ScrollViewer control, which will give you scrolling (vertical and/or horizontal) behaviour out of the box. We will then use the ManipulationDelta event of the scroller to get notified of the corresponding manipulation events (triggered by touches).

Here’s the first simple rectangle, in XAML code.

  1: <Rectangle HorizontalAlignment="Center"
  2:            VerticalAlignment="Center"
  3:            Fill="Blue"
  4:            Height="300"
  5:            Width="100"/>
Here’s the second rectangle, with the clipping mask and the corresponding TranslateTransform, in XAML code.

  1:  <Rectangle HorizontalAlignment="Center"
  2:             VerticalAlignment="Center"
  3:             Fill="Green"
  4:             Height="300"
  5:             Width="100">
  6:     <Rectangle.Clip>
  7:         <RectangleGeometry Rect="0, 0, 100, 300">
  8:             <RectangleGeometry.Transform>
  9:                 <TranslateTransform x:Name="MaskTransform" 
 10:                                     Y="0" />
 11:             </RectangleGeometry.Transform>
 12:         </RectangleGeometry>
 13:     </Rectangle.Clip>
 14: </Rectangle>
Finally, here’s our new ScrollViewer element. Notice the event handler for the ManipulationDelta event, again defined in XAML code.

  1: <ScrollViewer x:Name="ScrollViewer"
  2:               ManipulationDelta="OnManipulationDelta" />
In this case, we will need to get the ManipulationDeltaEventArgs data and retrieve the Y axis translation from it. We will do this in code behind. Once we retrieve the translation, we can add it to our mask’s Y axis Translation.

  1: private void OnManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
  2: {
  3:     var manipulation = e.DeltaManipulation;
  4:     MaskTransform.Y += manipulation.Translation.Y;
  5: }


In the sample, I also included a text field at the bottom of the screen to see the different manipulation variables and keep track of the mask’s translation. I’m displaying them in code behind just after modifying the mask translation.


image    image    image


There you go, with just a few lines of code we were able to modify the non-interactive animated clipping mask into an interactive version, where you can control the animation with touch. This might seem too basic, but this is the foundation to achieve more complex animations.

I hope you like the sample and make use of it. You can download the sample code from my Github repo here.

No comments:

Post a Comment