Neste artigo iremos aprender um pouco sobre o Perspective 3D. Criaremos uma aplicação bem objetiva, onde iremos movimentar uma imagem em volta de seus 3 eixos.

Perspective 3D é um dos recursos do Silverlight 3 onde utilizando o PlaneProjection podemos alterar a perspectiva alterando os valores dos 3 eixos (X, Y, Z) utilizando as propriedades RotateX , RotateY e RotateZ movimentando determinado elemento em seus eixos.

Então vamos iniciar!!!  (obs.: Para quem já conhece mais e quer ir direto ao assunto, no final do artigo coloquei 2 listagens com o código inteiro, tanto XAML quanto C#.)

Crie um projeto Silverlight. (File > New > Project > Silverlight Application) de um nome ao seu projeto (neste caso demos o nome de "Silverlight_rotate").

 
Vamos na Toolbox e selecionamos o objeto Rectangle e adicionamos em nosso projeto.
 
 


Ao adicionar o objeto Rectangle, repare que no código XAML(Pronuncia-se “Zammel”) , ele adiciona o seguinte código com algumas propriedades definidas.

<Rectangle Height="214" HorizontalAlignment="Left" Margin="67,16,0,0"

                   Name="rectangle1" Stroke="Black" StrokeThickness="1"

                   VerticalAlignment="Top" Width="263">

Rectangle>

 

(*Obs.: XAML = Extensible Application Markup Language. É uma linguagem criada pela Microsoft baseada em XML e fundamental para o desenvolvimento de aplicações Silverlight e WPF-Windows Application Foundation.)

 

Dentro de Rectangle vamos adicionar uma imagem. Você pode ir pelo código XAML e colocar o seguinte código dentro de Rectangle, onde deve-se mencionar o caminho da imagem de dentro de seu projeto, neste caso a imagem esta na pasta Images, dentro de nosso projeto e a imagem de nome silverlight.png.


<Rectangle.Fill>

<ImageBrush ImageSource="/Silverlight_rotate;component/Images/silverlight.png" />

Rectangle.Fill>

 


Uma forma mais simples é selecionar o objeto Rectangle e ir na guia de propriedades do Visual Studio, procurar por Fill, clique no icone da imagem e depois em "Select image".



Depois em "Add..." ai é só procurar a imagem em um de seus diretórios selecionar e clicar em abrir selecione a imagem como na figura a seguir e clique em OK.


Com a imagem já adicionada vamos agora codificar o movimento de nosso objeto rectangle.

 

Vamos trabalhar com os eixos X, Y, Z.
Então adicionamos o seguinte código em nosso XAML, para que inicie com as propriedades do rotate como 0, dentro das TAGS "Rectangle" colocamos o código referente ao recurso Perspective 3D.

<Rectangle.Projection>

                <PlaneProjection

                    RotationX="0"

                    RotationY="0"

                    RotationZ="0">              

                PlaneProjection>

Rectangle.Projection>

 

Perceba que atribuimos as propriedades RotationX, RotationY e RotationZ o valor zerado, para que inicie o nosso objeto sem inclinação para nem um dos 3 eixos, porém se quiser que inicie inclinado para algum lado é só atribuir um valor para qualquer uma das propriedades que ele ira iniciar inclinado de acordo com o eixo que foi passado o valor. (Valores positivos inclinam para um lado e negativos no sentido contrário.) 

Vamos agora adicionar um ComboBox em nosso projeto, a função dele será selecionar em qual dos eixos (eixo X, eixo Y, eixo Z) queremos que ele rode. 

Vamos alterar algumas propriedade de nosso ComboBoxno no código XAML na propriedade Name para Name="cboDirecao" que agora será o nome de nosso ComboBox o código ficara semelhante ao código abaixo.
 

<ComboBox Height="23" HorizontalAlignment="Left" Margin="66,249,0,0" Name="cboDirecao" VerticalAlignment="Top" Width="120" />

 

 

Agora, na guia "Solution Explorer" clique para abrir os itens de MainPage.xaml e abra o arquivo MainPage.xaml.cs.

 Dentro deste arquivo vamos criar uma função para preencher a lista do ComboBox com os valores como mostrado no código abaixo.

  private void carrega_direcao()

        {

         

            cboDirecao.Items.Clear();

            cboDirecao.Items.Add("EIXO - X");

            cboDirecao.Items.Add("EIXO - Y");

            cboDirecao.Items.Add("EIXO - Z");

 

        }

 

 

E chamamos esta função logo quando a página é carregada, então chamamos a função carrega_direcao, dentro do método MainPage como no código abaixo.

    public MainPage()

        {

            InitializeComponent();

 

            carrega_direcao();      

          

        }

 

Em MainPage, Dentro da Partial Class, declare 3 variáveis do tipo double chamadas valor_x, valor_y e valor_z e já atribua um valor (em nosso exemplo atribuímos 0 e depois vamos adicionando de 5 em 5 o valor na propriedade.)(*Obs.: Lembre-se de declarar estas variáveis como tipo Double e não como int. Caso declare como int, em tempo de execução ao clicar no Button para movimentar a foto, não ira funcionar e vai aparecer uma menssagem no rodapé do Internet Explorer, de erro de página. Se estiver rodando pelo Visual Studio irá apresentar uma menssagem dizendo que a propriedade não pode ser definida com um objeto do tipo Int)

Agora vamos criar uma função que ira movimentar o nosso objeto Rectangle onde ele ira verificar o item que esta selecionado do ComboBox e recebera um parâmetro do Button que foi acionado, e através do parâmetro ele tomara a decisão de somar ou diminuir o valor da direção do movimento.

private void movimenta_rectangle(string direcao_giro)

{

switch (cboDirecao.SelectedIndex)

{

case 0:

if (direcao_giro == "+") { valor_x += 5; } else { valor_x -= 5; }

rectangle1.Projection.SetValue(PlaneProjection.RotationXProperty, valor_x);

break;

 

case 1:

if (direcao_giro == "+") { valor_y += 5; } else { valor_y -= 5; }

rectangle1.Projection.SetValue(PlaneProjection.RotationYProperty, valor_y);

break;

 

case 2:

if (direcao_giro == "+") { valor_z += 5; } else { valor_z -= 5; }

rectangle1.Projection.SetValue(PlaneProjection.RotationZProperty, valor_z);

break;

 

default:

MessageBox.Show("Selecione uma opçao de direção.");

break;

 

}

 

 

Agora adicione 2 Button em nosso projeto.

Clique em um deles  e vamos trocar no código XAML as propriedades no nome e do texto de exibição. Para isso atribua à propriedade Content o valor "+" e para a propriedade Name o valor  "btnMovimentaPositivo". Ficara parecido com o código a seguir.

<Button Content="+" Height="23" HorizontalAlignment="Left" Margin="260,249,0,0" Name="btnMovimentaPositivo" VerticalAlignment="Top" Width="36" Click="btnMovimentaPositivo_Click" />

 

 

Clique no outro Button e vamos fazer a mesma coisa, clique nele e altere o XAML na propriedade Content deixe “-” e na propriedade Name “btnMovimentaNegativo”.

<Button Content="-" Height="23" HorizontalAlignment="Left" Margin="210,249,0,0" Name="btnMovimentaNegativo" VerticalAlignment="Top" Width="36" Click="btnMovimentaNegativo_Click" />

 

 
De duplo clique no Button que definimos como “+”, vamos chamar a nossa função e iremos passar o parâmetro para aumentar sentido da direção do movimento como no código abaixo.
 

private void btnMovimentaPositivo_Click(object sender, RoutedEventArgs e)

{

movimenta_rectangle("+");

}

 

 

Agora faça o mesmo com o outro Button, porém passando como parâmetro o valor “-”.

 

private void btnMovimentaNegativo_Click(object sender, RoutedEventArgs e)

{

movimenta_rectangle("-");

}

 

 

Pronto, agora podemos executar nosso aplicativo e testá-lo.

 
 
 

*************************************************************************************

Segue abaixo o código completo, tanto do XAML quanto do código C#.

Código XAML

<UserControl x:Class="Silverlight_rotate.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">

 

    <Grid x:Name="LayoutRoot" Background="White">

        <Rectangle Height="214" HorizontalAlignment="Left" Margin="67,16,0,0"

                   Name="rectangle1" Stroke="Black" StrokeThickness="1"

                   VerticalAlignment="Top" Width="263">

            <Rectangle.Fill>

                <ImageBrush ImageSource="/Silverlight_rotate;component/Images/silverlight.png" />

            Rectangle.Fill>

            <Rectangle.Projection>

                <PlaneProjection

                    RotationX="0"

                    RotationY="0"

                    RotationZ="0">              

                PlaneProjection>

            Rectangle.Projection>

        Rectangle>

        <ComboBox Height="23" HorizontalAlignment="Left" Margin="66,249,0,0" Name="cboDirecao" VerticalAlignment="Top" Width="120" />

        <Button Content="+" Height="23" HorizontalAlignment="Left" Margin="293,249,0,0" Name="btnMovimentaPositivo" VerticalAlignment="Top" Width="36" Click="btnMovimentaPositivo_Click" />

        <Button Content="-" Height="23" HorizontalAlignment="Left" Margin="251,249,0,0" Name="btnMovimentaNegativo" VerticalAlignment="Top" Width="36" Click="btnMovimentaNegativo_Click" />

    Grid>

UserControl>

 

Código C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

 

namespace Silverlight_rotate

{

    public partial class MainPage : UserControl

    {

        //Declaração da variaveis que irão ser

        //utilizadas para passar o valor de movimento.

        double valor_x = 0;

        double valor_y = 0;

        double valor_z = 0;

 

        public MainPage()

        {

            InitializeComponent();

           

            //Chama função que carrega itens do ComboBox

            carrega_direcao();      

          

        }

 

        ///

        /// Função que carrega itens de

        /// direção de movimento no ComboBox

        ///

        private void carrega_direcao()

        {

         

            cboDirecao.Items.Clear();

            cboDirecao.Items.Add("EIXO - X");

            cboDirecao.Items.Add("EIXO - Y");

            cboDirecao.Items.Add("EIXO - Z");

 

        }

 

        //Passa parâmetro "+" para a função identificar e acrescentar

        //o valor na direção do movimento.

        private void btnMovimentaPositivo_Click(object sender, RoutedEventArgs e)

        {

            movimenta_rectangle("+");

        }

 

        //Passa parâmetro "-" para a função identificar e subtrair

        //o valor na direção do movimento.

        private void btnMovimentaNegativo_Click(object sender, RoutedEventArgs e)

        {

            movimenta_rectangle("-");

        }

 

       ///

       /// Movimenta o objeto Rectangle, recebendo o parâmetro

       /// que identifica se irá somar ou subtrair o valor

       /// na direção do movimento e também verifica para

       /// qual direção irá movimentar através do item que

       /// foi selecionado no ComboBox

       ///

       ///

        private void movimenta_rectangle(string direcao_giro)

        {

            switch (cboDirecao.SelectedIndex)

            {

                case 0:

                    if (direcao_giro == "+") { valor_x += 5; } else { valor_x -= 5; }

                    rectangle1.Projection.SetValue(PlaneProjection.RotationXProperty, valor_x);                                  

                    break;

 

                case 1:

                    if (direcao_giro == "+") { valor_y += 5; } else { valor_y -= 5; }

                    rectangle1.Projection.SetValue(PlaneProjection.RotationYProperty, valor_y);                

                    break;

 

                case 2:

                    if (direcao_giro == "+") { valor_z += 5; } else { valor_z -= 5; }

                    rectangle1.Projection.SetValue(PlaneProjection.RotationZProperty, valor_z);                   

                    break;

 

                default:

                    MessageBox.Show("Selecione uma opçao de direção.");

                    break;

 

            }

       

        }

 

    }

}

 

*************************************************************************************

Espero que este artigo tenha sido útil a você.

Muito obrigado pela sua atenção e interesse.