Mobile Development at U2U Consult

Based in Brussels, Belgium, U2U Consult has been offering consulting & development services in the EMEA region for over 10 years. We offer mobile development on all platforms from Apple to Android & Microsoft.

This article illustrates two ways of using touch or mouse input to rotate a UI element in a XAML-based Windows 8 Store app. I’m sharing this code because I believe that the corresponding official MSDN sample is too complex. Don't get me wrong: the Windows 8 gestures sample looks nice and gives a complete overview of all gestures and their mouse equivalent. But it uses three entire classes to do something that you can literally do in three lines of code. In this article, I’ll describe the guidelines-compliant way of rotating an element using a two-finger gesture, but I also provide a one-finger alternative. Since not everyone has a touch screen (yet), I also give you two ways for using the mouse to rotate an element. As usual, the article comes with a downloadable sample app. It just displays two round rotatable images. Here’s a screenshot of it:

Multi Touch Rotation

A UI Element can register for rotation by setting its ManipulationMode to Rotate, optionally adding inertia. Multiple manipulation modes can be set in XAML through a comma-separated list. Just ignore Intellisense and don’t use the property editor:

<Image ...
ManipulationMode="Rotate,RotateInertia" />

Setting the manipulation mode causes the corresponding manipulation events (starting, inertiaStarting, started, delta, and completed) to fire. You find the complete list of events and event argument classes in the Touch Input Quickstart. You still have to code what should happen in your app. Typically that boils down to configuring the element’s RenderTransform. To simplify the code in the event handlers, I gave the image a named rotation transformation:

[Tip: You could use the ManipulationCompleted event to implement snap points.]

The pivot point of the rotation is set to the center of the element. For images you can do this in the ImageOpened event. It’s the first event that guarantees that ActualHeight and ActualWidth are set. I must say that every now and then I still get zero values here.

In Visual Studio's Touch Simulator, you can test it with the ‘Rotation touch mode’ button. Press it, hover over the UI element on the page, and scroll the mouse wheel:

On a non-touch device, the guidelines for common user interactions prescribe that a rotation gesture should be triggered by the mouse wheel, with ctrl and shift buttons pressed. So we add an event handler for PointerWheelChanged:

Use casesIn scenarios where inertia is needed (e.g. spinning a wheel) the two finger touch rotation is the right match. That manipulation is also very useful for rotating larger elements, with a high precision. For rotating a small element, I wouldn’t recommend this gesture, simply because you don’t see what you’re doing with two or more fingers on it. For non-touch environments, I’m not sure that the shift-control-mousewheel combination will become popular.

Single Touch Rotation

As an alternative, you can allow a user to put a finger on the element and start dragging. You just need to transform the translation into a rotation with a pinch of trigonometry. It’s easy to build, intuitive, and the code immediately works for the mouse too: click and start dragging. Just enable the TranslateX and TranslateY manipulation modes (and optionally add inertia), register a handler for ManipulationDelta, and initialize the RenderTransform:

In the ManipulationDelta handler, you transform the translation into a rotation by calculating the angle of the delta. Add this angle to the angle of the element’s RotateTransform. I took some time to make a small drawing to illustrate this. Alpha is the angle to be calculated:

From a performance standpoint, I assume that the law of cosines would be the most appropriate solution here. But I have the right to be lazy sometimes, so I went for the “least C#” option: calculate Alpha as the difference of Alpha1 and Alpha2 on the image. Here’s that code:

Use casesI would definitely recommend this type of rotation in non-touch scenarios: it reacts naturally and it does not require the shift and control buttons (or the user’s recollection to press these). In a touch environment, it does not occlude the element you're manipulating. There’s a lag in reaction time, and it’s easy to outpace the algorithm by moving too fast. So I would not use single point rotation to e.g. spin a wheel. The roulette wheel in the sample app is a bad choice - it just looked nice next to that wheel of fortune.