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").
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.)
<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"> < SPAN>PlaneProjection> < SPAN>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.
<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.
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" /> |
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" /> < SPAN>Rectangle.Fill> <Rectangle.Projection> <PlaneProjection RotationX="0" RotationY="0" RotationZ="0"> < SPAN>PlaneProjection> < SPAN>Rectangle.Projection> < SPAN>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" /> < SPAN>Grid> < SPAN>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; } } } } |