In the below example I used the new projection properties in Silverlight 3 to build a 3D image carousel. Moving the mouse left to right controls the speed and direction of the carousel. Moving the mouse up and down changes the opacity of the carousel, allowing you to see what is going on behind the carousel.

The ‘how to’ bit

To start with I have placed 6 images inside Blend and used the projection properties to offset them against each other to form a 3 dimensional hexagon. I do this by changing 2 projection properties:

CenterOfRotationZ=”-173″

RotationY=”60″

I use the ‘CenterOfRotationZ’ value to move the center point away from each image plane. This value needs to be the same on each of the 6 images I use in order to get them to match up at the edges. I then use the ‘RotationY’ value to change the angle of each image, as I have 6 images each image is rotated by a factor of 60 degrees (6 x 60 = 360 degrees).

I then place an x:Name on each images projection tag as seen in the below example:

<PlaneProjection x:Name=”Image1Projection” CenterOfRotationZ=”-173″ RotationZ=”0″/>

This will allow me to easily change the angle of each image dynamically in the C#.

In the C# I set up a listener to monitor the mouse movement and store the values in ‘pt’:

void LayoutRoot_MouseMove(object sender, MouseEventArgs e)

{

pt = e.GetPosition(LayoutRoot);

}

Next I set up a CompositionTarget.Rendering function so that I can update my 3 dimensional carousel constantly. I use the mouse X co-ordinates to change the speed and direction of the carousel and the mouse Y value to change the opacity:

void CompositionTarget_Rendering(object sender, EventArgs e)

{

Image1Projection.RotationY += ((pt.X – (LayoutRoot.ActualWidth / 2)) / LayoutRoot.ActualWidth) * 10;

Image2Projection.RotationY += ((pt.X – (LayoutRoot.ActualWidth / 2)) / LayoutRoot.ActualWidth) * 10;

Image3Projection.RotationY += ((pt.X – (LayoutRoot.ActualWidth / 2)) / LayoutRoot.ActualWidth) * 10;

Image4Projection.RotationY += ((pt.X – (LayoutRoot.ActualWidth / 2)) / LayoutRoot.ActualWidth) * 10;

Image5Projection.RotationY += ((pt.X – (LayoutRoot.ActualWidth / 2)) / LayoutRoot.ActualWidth) * 10;

Image6Projection.RotationY += ((pt.X – (LayoutRoot.ActualWidth / 2)) / LayoutRoot.ActualWidth) * 10;

image1.Opacity = (pt.Y / LayoutRoot.ActualHeight) * 0.5 + 0.5;

image2.Opacity = (pt.Y / LayoutRoot.ActualHeight) * 0.5 + 0.5;

image3.Opacity = (pt.Y / LayoutRoot.ActualHeight) * 0.5 + 0.5;

image4.Opacity = (pt.Y / LayoutRoot.ActualHeight) * 0.5 + 0.5;

image5.Opacity = (pt.Y / LayoutRoot.ActualHeight) * 0.5 + 0.5;

image6.Opacity = (pt.Y / LayoutRoot.ActualHeight) * 0.5 + 0.5;

}

Grab the code

As always you can grab the code source here.

In the below example I use the new Projection control to create a 3d effect based on the users mouse position. This is a great technique and it looks fantastic, really taking advantage of the new Silverlight capabilities. Whether you’re creating presentations for online universities or an interesting tag cloud for a blog. But how do you create such an effect in Silverlight?

In Silverlight 3 we have 2 new variables to give us the ability to show perspective. We can use this effect on any item, including Images and Text. These 2 new variables are:

RotationY
RotationX

Step by step

Firstly, I place an x:Name called ‘ProjectionFactor’ in the XAML. This gets placed in the ‘PlaneProjection’ tag of the object I want to control:

<Image Source=”images/sbLogo.png” Stretch=”Fill”>
<Image.Projection>
<PlaneProjection
x:Name=”ProjectionFactor” RotationY=”0″ RotationX=”0″/>
</Image.Projection>
</Image>

I then set up a listener in the C# to capture when the mouse is moved. Everytime the mouse is moved I capture the mouse co-ordinates and use the values in the below equations to get the desired effect:

void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
{
//Get the mouse X and Y positions and store it in ‘pt’
pt = e.GetPosition(LayoutRoot);
//Use the values stored in ‘pt’ to effect the value of ‘ProjectionFactor’
ProjectionFactor.RotationY = ((pt.X – (LayoutRoot.ActualWidth / 2)) / LayoutRoot.ActualWidth) * 100;
ProjectionFactor.RotationX = ((pt.Y – (LayoutRoot.ActualHeight / 2)) / LayoutRoot.ActualHeight) * 100;
}

Grab the code

As usual you can download the example files here.

In the below example we take the co-ordinates of the mouse and use that data to control the position of another item. This can be used for sliders, menus, carousels etc;

I have written the code to adapt to the size of the scrollable area, you can see this by clicking on the ‘+’ and ‘-’ buttons. These will add / remove the items inside the scrollable area. If you remove enough items so that the area taken up is less than that of the screen, the items are positioned in the middle.

To carry out this effect I need to keep track of the mouse position, the width of the screen and the width of the Stack panel containing the items. Each of these values need to be updated when ever they are changed.

I then position the movable area based on the following equations;

Where:
a = Mouse X position
b = Width of Screen area
c = Width of area to be moved
if movable area is bigger than screen area:
moveable area X position = (a/b)*(b-c)
if moveable area is smaller than screen area:
moveable area X position = (b-c)/2

This equation is run every time a frame is rendered.

The User Experience bit

It is an important interaction that when working with scrolling content like this, especially when the content is a menu, to make sure that the direction of new content approaches the movement of the mouse.

Get the code

As always you can download the example files here.