Efeitos de perspectiva 3D na UI XAML

Você pode aplicar efeitos 3D ao conteúdo em seus aplicativos Windows Runtime usando transformações de perspectiva. Por exemplo, você pode criar a ilusão de que um objeto é girado para ou para longe de você, conforme mostrado aqui.

Imagem com transformação de perspectiva

Outro uso comum para transformações de perspectiva é organizar objetos uns com os outros para criar um efeito 3D, como aqui.

Empilhando objetos para criar um efeito 3D

Além de criar efeitos 3D estáticos, você pode animar as propriedades de transformação de perspectiva para criar efeitos 3D móveis.

Você acabou de ver transformações de perspectiva aplicadas a imagens, mas pode aplicar esses efeitos a qualquer UIElement, incluindo controles. Por exemplo, você pode aplicar um efeito 3D a um contêiner inteiro de controles como este:

Efeito 3D aplicado a um contêiner de elementos

Aqui está o código XAML usado para criar este exemplo:

<StackPanel Margin="35" Background="Gray">
    <StackPanel.Projection>
        <PlaneProjection RotationX="-35" RotationY="-35" RotationZ="15"  />
    </StackPanel.Projection>
    <TextBlock Margin="10">Type Something Below</TextBlock>
    <TextBox Margin="10"></TextBox>
    <Button Margin="10" Content="Click" Width="100" />
</StackPanel>

Aqui, nos concentramos nas propriedades de PlaneProjection que são usadas para girar e mover objetos no espaço 3D. O próximo exemplo permite que você experimente essas propriedades e veja seu efeito em um objeto.

Classe PlaneProjection

Você pode aplicar efeitos 3D a qualquer UIElement definindo a propriedade Projeção do UIElement usando um PlaneProjection. O PlaneProjection define como a transformação é renderizada no espaço. O exemplo a seguir mostra um caso simples.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationX="-35"   />
    </Image.Projection>
</Image>

Esta figura mostra como a imagem é renderizada. O eixo x, o eixo y e o eixo z são mostrados como linhas vermelhas. A imagem é girada para trás 35 graus em torno do eixo x usando a propriedade RotationX .

RotateX menos 35 graus

A propriedade RotationY gira em torno do eixo y do centro de rotação.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationY="-35"   />
    </Image.Projection>
</Image>

RotateY menos 35 graus

A propriedade RotationZ gira em torno do eixo z do centro de rotação (uma linha perpendicular para o plano do objeto).

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationZ="-45"/>
    </Image.Projection>
</Image>

Rotacionar Z em -45 graus

As propriedades de rotação podem especificar um valor positivo ou negativo para girar em qualquer direção. O número absoluto pode ser maior que 360, o que gira o objeto mais de uma rotação completa.

Você pode mover o centro de rotação usando as propriedades CenterOfRotationX, CenterOfRotationY e CenterOfRotationZ . Por padrão, os eixos de rotação passam diretamente pelo centro do objeto, fazendo com que ele gire em torno do próprio centro. Mas se você mover o centro de rotação para a borda externa do objeto, ele girará ao redor dessa borda. Os valores padrão para CenterOfRotationX e CenterOfRotationY são 0,5 e o valor padrão para CenterOfRotationZ é 0. Para CenterOfRotationX e CenterOfRotationY, os valores entre 0 e 1 definem o ponto dinâmico em algum local dentro do objeto. Um valor 0 indica uma borda de objeto e 1 indica a borda oposta. Valores fora desse intervalo são permitidos e moverão o centro de rotação adequadamente. Como o eixo z do centro de rotação é desenhado pelo plano do objeto, você pode mover o centro de rotação atrás do objeto usando um número negativo e na frente do objeto (em direção a você) usando um número positivo.

CenterOfRotationX move o centro de rotação ao longo do eixo x paralelo ao objeto, enquanto CenterOfRotationY move o centro ou rotação ao longo do eixo y do objeto. As próximas ilustrações demonstram o uso de valores diferentes para CenterOfRotationY.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationX="-35" CenterOfRotationY="0.5" />
    </Image.Projection>
</Image>

CenterOfRotationY = "0,5" (padrão)

CenterOfRotationY é igual a 0,5

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationX="-35" CenterOfRotationY="0.1"/>
    </Image.Projection>
</Image>

CenterOfRotationY = "0.1"

CenterOfRotationY é igual a 0,1

Observe como a imagem gira ao redor do centro quando a propriedade CenterOfRotationY é definida como o valor padrão de 0,5 e gira perto da borda superior quando definida como 0,1. Você verá um comportamento semelhante ao alterar a propriedade CenterOfRotationX para mover para onde a propriedade RotationY gira o objeto.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationY="-35" CenterOfRotationX="0.5" />
    </Image.Projection>
</Image>

CenterOfRotationX = "0,5" (padrão)

CenterOfRotationX é igual a 0,5

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationY="-35" CenterOfRotationX="0.9" />
    </Image.Projection>
</Image>

CenterOfRotationX = "0,9" (borda direita)

CenterOfRotationX é igual a 0,9

Use o CenterOfRotationZ para colocar o centro de rotação acima ou abaixo do plano do objeto. Dessa forma, você pode girar o objeto ao redor do ponto análogo a um planeta orbitando em torno de uma estrela.

Posicionando um objeto

Até agora, você aprendeu a girar um objeto no espaço. Você pode posicionar esses objetos girados no espaço em relação uns aos outros usando estas propriedades:

  • LocalOffsetX move um objeto ao longo do eixo x do plano de um objeto girado.
  • LocalOffsetY move um objeto ao longo do eixo y do plano de um objeto girado.
  • LocalOffsetZ move um objeto ao longo do eixo z do plano de um objeto girado.
  • GlobalOffsetX move um objeto ao longo do eixo x alinhado à tela.
  • GlobalOffsetY move um objeto ao longo do eixo y alinhado à tela.
  • GlobalOffsetZ move um objeto ao longo do eixo z alinhado à tela.

Deslocamento local

As propriedades LocalOffsetX, LocalOffsetY e LocalOffsetZ convertem um objeto ao longo do respectivo eixo do plano do objeto depois que ele é girado. Portanto, a rotação do objeto determina a direção em que o objeto é traduzido. Para demonstrar esse conceito, o próximo exemplo anima LocalOffsetX de 0 a 400 e RotationY de 0 a 65 graus.

Observe no exemplo anterior que o objeto está se movendo ao longo de seu próprio eixo x. No início da animação, quando o valor RotationY é próximo de zero (paralelo à tela), o objeto se move ao longo da tela na direção x, mas à medida que o objeto gira em direção a você, o objeto se move ao longo do eixo x do plano do objeto em sua direção. Por outro lado, se você animasse a propriedade RotationY para -65 graus, o objeto se curvaria para longe de você.

LocalOffsetY funciona de forma semelhante a LocalOffsetX, exceto que ele se move ao longo do eixo vertical, portanto, alterar RotationX afeta a direção localOffsetY move o objeto. Na próxima amostra, LocalOffsetY é animado de 0 a 400 e RotationX de 0 a 65 graus.

LocalOffsetZ translada o objeto perpendicularmente ao plano do objeto, como se um vetor fosse traçado passando diretamente pelo centro, de trás do objeto em direção a você. Para demonstrar como o LocalOffsetZ funciona, o próximo exemplo anima LocalOffsetZ de 0 a 400 e RotationX de 0 a 65 graus.

No início da animação, quando o valor RotationX está próximo de zero (paralelo à tela), o objeto se move diretamente em direção a você, mas à medida que a face do objeto gira para baixo, o objeto se move para baixo.

Deslocamento global

As propriedades GlobalOffsetX, GlobalOffsetY e GlobalOffsetZ convertem o objeto em eixos relativos à tela. Ou seja, ao contrário das propriedades de deslocamento local, o eixo que o objeto move é independente de qualquer rotação aplicada ao objeto. Essas propriedades são úteis quando você deseja simplesmente mover o objeto ao longo do eixo x, y ou z da tela sem se preocupar com a rotação aplicada ao objeto.

O próximo exemplo anima GlobalOffsetX de 0 a 400 e RotationY de 0 a 65 graus.

Observe neste exemplo que o objeto não altera o curso à medida que gira. Isso ocorre porque o objeto está sendo movido ao longo do eixo x da tela sem levar em conta sua rotação.

Cenários semi-3D mais complexos

Você pode usar os tipos Matrix3DProjection e Matrix3D para cenários semi-3D mais complexos do que o possível com o PlaneProjection. Matrix3DProjection fornece uma matriz de transformação 3D completa para aplicar a qualquer UIElement, para que você possa aplicar matrizes de transformação de modelo arbitrária e matrizes de perspectiva aos elementos. Tenha em mente que essas API são mínimas e, portanto, se você usá-las, será necessário escrever o código que cria corretamente as matrizes de transformação 3D. Por isso, é mais fácil usar o PlaneProjection para cenários 3D simples.