Efectos de perspectiva 3D para interfaces de usuario XAML
Puedes usar transformaciones de perspectiva para aplicar efectos 3D al contenido de tus aplicaciones de Windows Runtime. Por ejemplo, puedes crear la ilusión de que un objeto gira hacia ti o se aleja, como se muestra aquí.
Otro uso habitual de las transformaciones de perspectiva es la organización de objetos relacionados entre sí para crear un efecto 3D, como aquí.
Además de crear objetos 3D estáticos, puedes animar las propiedades de la transformación de perspectiva para crear efectos 3D en movimiento.
Acabas de ver las transformaciones de perspectiva aplicadas a imágenes, pero puedes aplicar estos efectos a cualquier UIElement, incluidos los controles. Por ejemplo, puedes aplicar un efecto 3D a todo un contenedor de controles como este:
Este es el código XAML usado para crear este ejemplo:
<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>
Aquí nos hemos centrado en las propiedades de PlaneProjection que se usan para girar y mover objetos en el espacio 3D. El siguiente ejemplo te permite experimentar con estas propiedades y ver su efecto en un objeto.
Clase PlaneProjection
Puedes aplicar efectos 3D a cualquier UIElement estableciendo la propiedad Projection del UIElement mediante una clase PlaneProjection. PlaneProjection define cómo se representa la transformación en el espacio. El ejemplo siguiente muestra un caso sencillo.
<Image Source="kid.png">
<Image.Projection>
<PlaneProjection RotationX="-35" />
</Image.Projection>
</Image>
Esta figura muestra cómo se representa la imagen. Los ejes x, y y z se muestran como líneas rojas. La imagen se gira hacia atrás 35 grados alrededor del eje X mediante la propiedad RotationX.
La propiedad RotationY gira alrededor del eje Y del centro de rotación.
<Image Source="kid.png">
<Image.Projection>
<PlaneProjection RotationY="-35" />
</Image.Projection>
</Image>
La propiedad RotationZ gira alrededor del eje Z del centro de rotación (una línea perpendicular al plano del objeto).
<Image Source="kid.png">
<Image.Projection>
<PlaneProjection RotationZ="-45"/>
</Image.Projection>
</Image>
Las propiedades de rotación pueden especificar un valor de giro positivo o negativo en cualquiera de las direcciones. El número absoluto puede ser mayor que 360, que permite girar el objeto más de una rotación completa.
Puedes mover el centro de rotación mediante las propiedades CenterOfRotationX, CenterOfRotationY y CenterOfRotationZ. De forma predeterminada, los ejes de rotación pasan por el centro del objeto, lo que hace que el objeto gire alrededor de su centro. Si mueves el centro de rotación al borde exterior del objeto, girará alrededor de dicho borde. Los valores predeterminados de CenterOfRotationX y CenterOfRotationY son 0,5 y el valor predeterminado de CenterOfRotationZ es 0. En el caso de CenterOfRotationX y CenterOfRotationY, los valores entre 0 y 1 establecen el punto dinámico en algún lugar del objeto. Un valor 0 indica un borde del objeto, y 1 indica el borde opuesto. Se permiten valores fuera de este intervalo, que moverán el centro de rotación como corresponda. Debido a que el eje Z del centro de rotación se dibuja a través del plano del objeto, puedes mover el centro de rotación detrás del objeto mediante un número negativo, o delante del objeto (hacia ti) mediante un número positivo.
CenterOfRotationX mueve el centro de rotación a lo largo del eje X paralelo al objeto, mientras que CenterOfRotationY mueve el centro de rotación a lo largo del eje Y del objeto. Las siguientes ilustraciones muestran cómo se usan los diferentes valores para CenterOfRotationY.
<Image Source="kid.png">
<Image.Projection>
<PlaneProjection RotationX="-35" CenterOfRotationY="0.5" />
</Image.Projection>
</Image>
CenterOfRotationY = "0.5" (predeterminado)
<Image Source="kid.png">
<Image.Projection>
<PlaneProjection RotationX="-35" CenterOfRotationY="0.1"/>
</Image.Projection>
</Image>
CenterOfRotationY = "0.1"
Observa cómo gira la imagen alrededor del centro cuando la propiedad CenterOfRotationY se establece en el valor predeterminado de 0,5 y gira cerca del borde superior cuando se establece en 0,1. Verás un comportamiento similar cuando se cambia la propiedad CenterOfRotationX para que se mueva al lugar donde la propiedad RotationY gira el objeto.
<Image Source="kid.png">
<Image.Projection>
<PlaneProjection RotationY="-35" CenterOfRotationX="0.5" />
</Image.Projection>
</Image>
CenterOfRotationX = "0.5" (predeterminado)
<Image Source="kid.png">
<Image.Projection>
<PlaneProjection RotationY="-35" CenterOfRotationX="0.5" />
</Image.Projection>
</Image>
CenterOfRotationX = "0.9" (borde derecho)
Usa CenterOfRotationZ para situar el centro de rotación por encima o por debajo del plano del objeto. De esta manera, puedes rotar el objeto alrededor del punto, de forma similar a un planeta que gira alrededor de una estrella.
Posicionamiento de un objeto
Hasta ahora, has aprendido cómo girar un objeto en el espacio. Puedes colocar estos objetos que giran en el espacio relacionados entre sí con una de estas propiedades:
- LocalOffsetX mueve un objeto a lo largo del eje X del plano de un objeto que gira.
- LocalOffsetY mueve un objeto a lo largo del eje Y del plano de un objeto que gira.
- LocalOffsetZ mueve un objeto a lo largo del eje Z del plano de un objeto que gira.
- GlobalOffsetX mueve un objeto a lo largo del eje X alineado con la pantalla.
- GlobalOffsetY mueve un objeto a lo largo del eje Y alineado con la pantalla.
- GlobalOffsetZ mueve un objeto a lo largo del eje Z alineado con la pantalla.
Desplazamiento local
Las propiedades LocalOffsetX, LocalOffsetY y LocalOffsetZ trasladan un objeto a lo largo del eje respectivo del plano del objeto después de que haya girado. Por consiguiente, la rotación del objeto determina la dirección en que este se traslada. Para demostrar este concepto, el ejemplo siguiente anima LocalOffsetX de 0 a 400 y RotationY de 0 a 65 grados.
Observa en el ejemplo anterior que el objeto se mueve a lo largo de su propio eje X. Muy al principio de la animación, cuando el valor de RotationY es casi cero (paralelo a la pantalla), el objeto se mueve a lo largo de la pantalla en la dirección X, pero a medida que el objeto gira acercándose, se mueve hacia ti a lo largo del eje X del plano del objeto. Por otra parte, si animaste la propiedad RotationY a -65 grados, el objeto se alejará describiendo una curva.
LocalOffsetY funciona de manera similar a LocalOffsetX, excepto que se mueve a lo largo del eje vertical, por lo que cambiar RotationX afecta a la dirección en que LocalOffsetY mueve el objeto. En el ejemplo siguiente, LocalOffsetY se anima de 0 a 400 y RotationX de 0 a 65 grados.
LocalOffsetZ traslada el objeto perpendicular al plano del objeto como si se hubiera dibujado un vector directamente a través del centro, desde detrás del objeto hacia ti. Para demostrar cómo funciona LocalOffsetZ, en el ejemplo siguiente se anima LocalOffsetZ de 0 a 400 y RotationX de 0 a 65 grados.
Al principio de la animación, cuando el valor de RotationX está cerca de cero (paralelo a la pantalla), el objeto se mueve directamente hacia ti, pero a medida que la cara del objeto gira hacia abajo, este se mueve hacia abajo.
Desplazamiento global
Las propiedades GlobalOffsetX, GlobalOffsetY y GlobalOffsetZ trasladan el objeto a lo largo de los ejes relativos a la pantalla. Es decir, a diferencia de las propiedades de desplazamiento local, el eje por el que se mueve el objeto es independiente de cualquier rotación que se le aplique. Estas propiedades resultan útiles cuando solo quieres mover el objeto a lo largo de los ejes X, Y o Z de la pantalla sin preocuparte por la rotación que le aplique.
El ejemplo siguiente anima GlobalOffsetX de 0 a 400 y RotationY de 0 a 65 grados.
Observa en este ejemplo que el objeto no cambia su curso a medida que gira. Esto se debe a que el objeto se mueve a lo largo del eje x de la pantalla independientemente de su rotación.
Escenarios semi3D más complejos
Puedes usar los tipos Matrix3DProjection y Matrix3D para escenarios semi-3D más complejos que los que son posibles con PlaneProjection. Matrix3DProjection proporciona una completa matriz de transformación 3D para aplicar a cualquier UIElement, por lo que puedes aplicar matrices de transformación y matrices de perspectiva de modelos arbitrarios a los elementos. Ten en cuenta que estas API son mínimas y, si las usas, tendrás que escribir el código que crea correctamente las matrices de transformación 3D. Por este motivo, es más fácil usar PlaneProjection para escenarios 3D sencillos.