This blog post describes the implementation of a metro 'tilt' effect for Windows Phone 7 which causes element to respond to user interactions by tilting in 3D
So far in the "Metro In Motion" series I have covered fluid list animations, 'peel' animations and flying title. In this blog post I am looking at the 'tilt' effect seen in native Windows Phone 7 applications where list items, tiles, check-boxes and other user interface element tilt slightly when the user presses them. This is a subtle 3D effect that makes the phone interface more tactile and playful.
I was in two minds about whether to implement my own tilt effect since there is an implementation of this effect available via the Silverlight (for Windows Phone 7) Toolkit. However, I am not that keen on the toolkit implementation of this feature. Firstly, the effect is applied by specifying the types of element that should tilt, unfortunately this fails in various scenarios; secondly, the tilt is a bit over-the-top. Personally, I think this effect works best when it is at its most subtle.
The video below shows the tilt effect in action, together with the other Metro In Motion effects:
The implementation of this effect is actually rather simple, relying heavily on the PlaneProjection transform that makes 3D transformations accessible to mere mortals like myself (for more powerful and flexible 3D effects I would thoroughly recommend René Schule's Matrix3DEx library). The effect is added to any element by applying an attached property:
The value of the Tilt property defines how pronounced the effect is. When the Tilt property is attached, event handlers are added to the UI element:
When the element is clicked, the distance of the click location to the centre is computed. A PlaneProjection is used to tilt the element based on the click location, with a click at the top causing it to tilt around the X axis, and a click on the side tilting around the Y axis. A ScaleTransform is used to make the element shrink slightly, giving a user the feeling that the element has been pushed into the phone slightly.
When the manipulation is complete the properties of these various transforms are animated back to their original values usingCreateAnimation which is a simple utility method for creating DoubleAnimation instances:
The magnitude of the ScaleTransform and PlaneProjection depends on the click location, with clicks to the centre of the element resulting in a scaling, but no rotation, and clicks at the edge causing rotation but no scaling. The net result can be observed below where the effect of clicking at various locations of an element is shown:
You can also see the effect of clicking a square element below:
Finally, native phone applications have another subtle effect where elements that are tilted at the bottom of the screen appear to be viewed from above, whilst ones at the top are viewed from below. This can be achieved by applying a local offset to the PlaneProjection and an equal and opposite vertical TranslateTransform. The following code is added ...
Which results in the following effect:
With that, the effect is complete!
Please note, the images in this blog post use a Tilt 'factor' of 6 in order to make the effect easier to see in these static images. I would urge you to use a much lower factor, perhaps 2, to make this effect much more subtle. I think it works best if the user almost doesn't notice the effect, rather they 'feel' it.
You can download the full sourcecode for this blog post here: MetroInMotion4.zip
Regards,Colin E.
Want to receive more insights?
If you enjoyed this blog post, why not subscribe to our mailing list
to receive Scott Logic content, news and insights straight to your inbox?
Sign up here.
I am CTO at Scott Logic and am a prolific technical author, blogger and speaker on a range of technologies.
My blog includes posts on a wide range of topics, including WebAssembly, HTML5 / JavaScript and data visualisation with D3 and d3fc. You'll also find a whole host of posts about previous technology interests including iOS, Swift, WPF and Silverlight.
I'm board member of FINOS, which is encouraging open source collaboration in the financial sector. I'm also very active on GitHub, contributing to a number of different projects.