On yesterday’s Innovation Day 2010, me & my partner (Kresna, CTO Armanovus) was speaking about “Introduction to Developing Apps w/ Silverlight”, covering from the very beginning (history, basic XAML, what’s new in Silverlight 4, etc), to finally focusing on developing Windows Phone 7 application with Silverlight. We showed off some fun demo stuff including Foursquare for WP7, Pillbox, Twitter Search, Accelerometer look-a-like in WP7, some cool panoramic behaviour stuff, and Silverlight Multitouch (yes luckily i'm geared with TouchSmart TM-2 laptop! :)
At first, I was inspired by this post about Windows Phone Animation, it was simply 3 sliders and 1 image to demo 3D perspective transform feature by using “plane projection”. But reading that post kinda makes me think, “Why is this guy using so much code-behind while we can simply do DATA-BINDING directly from XAML?” Hmm… I just thought so because I don’t think I like coding too much :p
So now I’m giving very basic tutorial on how to utilize 3D Silverlight perspective transform on Windows Phone. Make sure you already have Windows Phone Development kit installed on your PC, if not, now you better go download them all at once :)
Let’s get started!
Open Visual Studio 2010 / VS2010 Express for Windows Phone / Expression Blend 4 RC, go create new Project (File > New Project). In this case I am using one of my favorite tool, Blend 4 RC.
Go play around, change the Title & Sub-title text on top, then add 3 sliders + 1 image so it would look like this:
(Make sure to set the Maximum properties of each sliders to 360 and Minimum to 0)
Just to make sure in Objects & Timeline panel you will see control-hierarchy just like this:
Now the super-fun stuff begins. What you need to make those sliders work like a charm is some DATA-BINDING. To what? Well maybe I should explain about Plane Projection a little bit:
Plane Projection
PlaneProjection is a class that represents a perspective transform (a 3-D-like effect) on an object. So not only it can be applied to Images, but to Controls (UIElement) as well. You can create 3D effects on a Grid/Canvas/Stackpanel container, which means that anything contained inside is also being transformed, as long as it’s visible :) For example buttons, textboxes, etc, you can still interact with them (clicking, typing, etc) even while they’re being projected.
PlaneProjection has 12 properties to control the rotation and positioning of an object. But basically it’s divided into 4 :
- Rotation (X/Y/Z) : specify the number of degrees to rotate the object in space. Specifically, RotationX specifies rotating around the horizontal axis, RotationY along the vertical axis, and RotationZ is like the diagonal vector, rotating around a line perpendicular to the object.
- CenterOfRotation (X/Y/Z) : change where the axis of rotation are positioned, therefore you could change the effect of rotation. Default value is 0.5 (on the scale 0 to 1).
- GlobalOffset (X/Y/Z) : This one’s useful when you want to simply move the object along X/Y/Z axis without worrying about the rotation applied to it. In other words, GlobalOffset translates an object along the axis of the screen.
- LocalOffset (X/Y/Z) : Unlike GlobalOffset, LocalOffset translates an object along the respective axis after it has been rotated. That is why in this LocalOffset case, the Rotation value determines the DIRECTION of the translated object.
Got a little bit of insight? :)
Now first thing we need to do is adding Projection properties in our image:
<Image Height="380" Width="380" Name="image1" Source="...">
<Image.Projection>
<PlaneProjection x:Name="Projection"
CenterOfRotationX="0.5"
CenterOfRotationY="0.5"
CenterOfRotationZ="0.5" />
</Image.Projection>
</Image>
And this simple magic does the trick!
<Slider Name="slider1" Maximum="360" SmallChange="1"
Value="{Binding RotationX, Mode=TwoWay, ElementName=Projection}"/>
Do it for other slider (for axis Y and Z), and that’s it, you’re done! NO CODE-BEHIND :)
If you’d like to see the value of rotation you could add 3 textblocks and bind them directly to each of the Slider’s value. For example,
<TextBlock x:Name="textX" Text="{Binding ElementName=slider1, Path=Value}" />
So here’s our final screenshot: (Source code attached, you can download it here.)



Cheers… :)