Updated Tilt Effect

Jeff has posted a version of the Windows Phone 7 “tilt” effect that is packaged as a control, built by Luke. It’s only fair that I update my tilt code too – it uses the same attached property implementation as my previous tilt code, but the new updated tilt algorithm (direct from the shell team) that is used in Luke’s control.

This version uses a global camera effect to ensure that each object tilts not only around its own centre, but is also angled towards the middle of the screen. This effect is accomplished by first translating the object to the middle of the screen doing a normal RenderTransform (in 2D space), and then transforming it back where it came from using a Projection (in 3D space):

TranslateTransform transform = new TranslateTransform();
transform.X = centerDelta.X;
transform.Y = centerDelta.Y;
element.RenderTransform = transform;

PlaneProjection projection = new PlaneProjection();
projection.GlobalOffsetX = -1 * centerDelta.X;
projection.GlobalOffsetY = -1 * centerDelta.Y;
element.Projection = projection;

This is a relatively simple trick that is used in several other places in the Windows Phone 7 animations, something I hope to be posting more on later.

Other than the global camera, a switch to using manipulation events, and some general code clean-up, the basic technique has not changed from the previous version:

  1. An attached property, TiltEffect.IsTiltEnabled, can be placed on any element in the tree (typically the root of a page or even the frame)
  2. When this is done, the control starts listening for ManipulationStarted events on that element
  3. If a manipulation is detected, the code checks the object being manipulated to check whether it is a "tiltable" object
  4. If it is, the appropriate RenderTransform and Projection are added to the element, and the ManipulationDelta and ManipulationCompleted events are hooked
  5. Whenever your finger (mouse) moves, the tilt angle is updated
  6. When the manipulation completes (or when you leave the hit-area of the control) an animation is run to "spring" the control back into place after a short delay

This is all done in a pretty efficient way, such that there is only ever one animation in the app and so that the added transforms and projections are removed after use. Attached is a simple example project that uses the updated effect along with some super-ugly demo pages that show the effect in, errr, effect. It also behaves nicely with tombstoning so that it remembers the scroll positions of each page and the settings you have chosen on the first page. Fingers crossed, this will also make it into the official documentation as a sample such that even developers who don't read my blog will have access to the tilt effect in their apps (although shame on them for not reading! ;-) ).

TiltEffectRtm.zip