Formas de Xamarin.Forms: transformaciones de objetos Path
Un elemento Transform
define cómo transformar un objeto Path
de un espacio de coordenadas a otro espacio de coordenadas. Cuando se aplica una transformación a un objeto Path
, cambia cómo se representa el objeto en la interfaz de usuario.
Las transformaciones se pueden categorizar en cuatro clasificaciones generales: rotación, escalado, asimetría y traducción. Xamarin.Forms define una clase para cada una de estas clasificaciones de transformación:
RotateTransform
, que gira unPath
por unAngle
especificado.ScaleTransform
, que escala un objetoPath
por las cantidadesScaleX
yScaleY
especificadas.SkewTransform
, que inclina un objetoPath
por las cantidadesAngleX
yAngleY
especificadas.TranslateTransform
, que mueve un objetoPath
por las cantidadesX
yY
especificadas.
Xamarin.Forms también proporciona las siguientes clases para crear transformaciones más complejas:
TransformGroup
, que representa una transformación compuesta formada por varios objetos de transformación.CompositeTransform
, que aplica varias operaciones de transformación a un objetoPath
.MatrixTransform
, que crea transformaciones personalizadas que no proporcionan otras clases de transformación.
Todas estas clases derivan de la clase Transform
, que define una propiedad Value
de tipo Matrix
, que representa la transformación actual como un objeto Matrix
. Esta propiedad está respaldada por un objeto BindableProperty
, lo que significa que puede ser destino de los enlaces de datos, y con estilo. Para obtener más información sobre la estructura Matrix
, consulta Matriz de transformación.
Para aplicar una transformación a Path
, crea una clase de transformación y establécela como el valor de la propiedad Path.RenderTransform
.
Transformación de rotación
Una transformación de rotación gira un objeto Path
en el sentido de las agujas del reloj sobre un punto especificado en un sistema de coordenadas X-Y bidimensional.
La clase RotateTransform
, que se deriva de la clase Transform
, define las siguientes propiedades:
Angle
, de tipodouble
, representa el ángulo, en grados, de rotación en el sentido de las agujas del reloj. El valor predeterminado de esta propiedad es 0.0.CenterX
, de tipodouble
, representa la coordenada x del punto central de rotación. El valor predeterminado de esta propiedad es 0.0.CenterY
, de tipodouble
, representa la coordenada y del punto central de rotación. El valor predeterminado de esta propiedad es 0.0.
Estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que pueden ser destinos de los enlaces de datos, y que se les puede aplicar un estilo.
Las propiedades CenterX
y CenterY
especifican el punto sobre el que se gira el objeto Path
. Este punto central se expresa en el espacio de coordenadas del objeto que se transforma. De forma predeterminada, la rotación se aplica a (0,0), que es la esquina superior izquierda del objeto Path
.
En el ejemplo siguiente se muestra cómo girar un objeto Path
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<RotateTransform CenterX="0"
CenterY="0"
Angle="45" />
</Path.RenderTransform>
</Path>
En este ejemplo, el objeto Path
se gira 45 grados sobre su esquina superior izquierda.
Transformación de escala
Una transformación de escala aumenta un objeto Path
en el sistema de coordenadas X-Y bidimensional.
La clase ScaleTransform
, que se deriva de la clase Transform
, define las siguientes propiedades:
ScaleX
, de tipodouble
, que representa el factor de escala del eje X. El valor predeterminado de esta propiedad es 1.0.ScaleY
, de tipodouble
, que representa el factor de escala del eje y. El valor predeterminado de esta propiedad es 1.0.CenterX
, de tipodouble
, que representa la coordenada X del punto central de esta transformación. El valor predeterminado de esta propiedad es 0.0.CenterY
, de tipodouble
, que representa la coordenada Y del punto central de esta transformación. El valor predeterminado de esta propiedad es 0.0.
Estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que pueden ser destinos de los enlaces de datos, y que se les puede aplicar un estilo.
El valor de ScaleX
y ScaleY
tiene un gran impacto en el escalado resultante:
- Los valores entre 0 y 1 reducen el ancho y el alto del objeto escalado.
- Los valores mayores que 1 aumentan el ancho y el alto del objeto escalado.
- Los valores de 1 indican que el objeto no se escala.
- Los valores negativos invierten el objeto de escala horizontal y verticalmente.
- Los valores entre 0 y -1 invierten el objeto de escala y reducen su anchura y altura.
- Los valores inferiores a -1 invierten el objeto y aumentan su anchura y altura.
- Los valores de -1 invierten el objeto escalado, pero no cambian su tamaño horizontal o vertical.
Las propiedades CenterX
y CenterY
especifican el punto sobre el que se escala el objeto Path
. Este punto central se expresa en el espacio de coordenadas del objeto que se transforma. De forma predeterminada, la rotación se aplica a (0,0), que es la esquina superior izquierda del objeto Path
. Esto tiene el efecto de mover el objeto Path
y también de hacer que parezca más grande, ya que cuando aplicas una transformación, cambias el espacio de coordenadas en la que reside el objeto Path
.
En el ejemplo siguiente se muestra cómo se modifica la escala de un objeto Path
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<ScaleTransform CenterX="0"
CenterY="0"
ScaleX="1.5"
ScaleY="1.5" />
</Path.RenderTransform>
</Path>
En este ejemplo, el objeto Path
se escala a 1,5 veces el tamaño.
Transformación del sesgo
Una transformación de sesgo sesga un objeto Path
en el sistema de coordenadas x-y 2D, y es útil para crear la ilusión de profundidad 3D en un objeto 2D.
La clase SkewTransform
, que deriva de la clase Transform
, define las siguientes propiedades:
AngleX
, de tipodouble
, que representa el ángulo sesgado del eje x, que se mide en grados en sentido contrario a las agujas del reloj desde el eje y. El valor predeterminado de esta propiedad es 0.0.AngleY
, de tipodouble
, que representa el ángulo sesgado del eje y, que se mide en grados en sentido contrario a las agujas del reloj desde el eje x. El valor predeterminado de esta propiedad es 0.0.CenterX
, de tipodouble
, que representa la coordenada x del centro de transformación. El valor predeterminado de esta propiedad es 0.0.CenterY
, de tipodouble
, que representa la coordenada y del centro de transformación. El valor predeterminado de esta propiedad es 0.0.
Estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que pueden ser destinos de los enlaces de datos, y que se les puede aplicar un estilo.
Para predecir el efecto de una transformación de sesgo, considere que AngleX
sesga los valores del eje X relativos al sistema de coordenadas original. Por lo tanto, para AngleX
de 30, el eje y gira 30 grados a lo largo del origen y sesga los valores de x en 30 grados a partir de ese origen. De forma similar, un AngleY
de 30 sesga los valores del objeto Path
en 30 grados a partir del origen.
Nota:
Para sesgar un objeto Path
en su lugar, debes establecer las propiedades CenterX
y CenterY
en el punto central del objeto.
En el ejemplo siguiente se muestra cómo sesgar un objeto Path
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<SkewTransform CenterX="0"
CenterY="0"
AngleX="45"
AngleY="0" />
</Path.RenderTransform>
</Path>
En el siguiente ejemplo se aplica un sesgo horizontal de 45 grados a un objeto Path
desde un punto central de (0,0).
Transformación de traslación
Una transformación de traslación mueve un objeto del sistema de coordenadas x-y bidimensional.
La clase TranslateTransform
, que deriva de la clase Transform
, define las siguientes propiedades:
X
, de tipodouble
, que representa la distancia que se va a mover a lo largo del eje x. El valor predeterminado de esta propiedad es 0.0.Y
, de tipodouble
, que representa la distancia que se va a mover a lo largo del eje y. El valor predeterminado de esta propiedad es 0.0.
Estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que pueden ser destinos de los enlaces de datos, y que se les puede aplicar un estilo.
Los valores negativos X
mueven un objeto a la izquierda, mientras que los valores positivos mueven un objeto a la derecha. Los valores negativos Y
mueven un objeto hacia arriba, mientras que los valores positivos mueven un objeto hacia abajo.
En el ejemplo siguiente se muestra cómo usar un objeto Path
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<TranslateTransform X="50"
Y="50" />
</Path.RenderTransform>
</Path>
En este ejemplo, el objeto Path
se mueve 50 unidades independientes del dispositivo hacia la derecha y 50 unidades independientes del dispositivo hacia abajo.
Varias transformaciones
Xamarin.Forms tiene dos clases que admiten la aplicación de varias transformaciones a un objeto Path
. Son TransformGroup
y CompositeTransform
. TransformGroup
realiza transformaciones en cualquier orden deseado, mientras que CompositeTransform
realiza transformaciones en un orden específico.
Grupos de transformación
Los grupos de transformación representan transformaciones compuestas por varios objetos Transform
.
La clase TransformGroup
, que deriva de la clase Transform
, define una propiedad Children
, de tipo TransformCollection
, que representa una colección de objetos Transform
. Estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que pueden ser destinos de los enlaces de datos, y con formato de estilo.
El orden de las transformaciones es importante en una transformación compuesta que usa la clase TransformGroup
. Por ejemplo, si primero gira, después escala y, a continuación, traslada, obtendrá un resultado diferente que si primero traslada, luego gira y, a continuación, escala. Un orden con motivos es significativo, porque las transformaciones como la rotación y el escalado se realizan con respecto al origen del sistema de coordenadas. El escalado de un objeto centrado en el origen genera un resultado diferente al escalado de un objeto que se ha alejado del origen. De forma similar, la rotación de un objeto centrado en el origen genera un resultado diferente a la rotación de un objeto que se ha alejado del origen.
En el ejemplo siguiente se muestra cómo realizar una transformación compuesta mediante la clase TransformGroup
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.5"
ScaleY="1.5" />
<RotateTransform Angle="45" />
</TransformGroup>
</Path.RenderTransform>
</Path>
En este ejemplo, el objeto Path
escala 1,5 veces su tamaño y luego gira 45 grados.
Transformaciones compuestas
Una transformación compuesta aplica varias transformaciones a un objeto.
La clase CompositeTransform
, que deriva de la clase Transform
, define las siguientes propiedades:
CenterX
, de tipodouble
, que representa la coordenada x del punto central de esta transformación. El valor predeterminado de esta propiedad es 0.0.CenterY
, de tipodouble
, que representa la coordenada Y del punto central de esta transformación. El valor predeterminado de esta propiedad es 0.0.ScaleX
, de tipodouble
, que representa el factor de escala del eje x. El valor predeterminado de esta propiedad es 1.0.ScaleY
, de tipodouble
, que representa el factor de escala del eje y. El valor predeterminado de esta propiedad es 1.0.SkewX
, de tipodouble
, que representa el ángulo sesgado del eje x, que se mide en grados en sentido contrario a las agujas del reloj desde el eje y. El valor predeterminado de esta propiedad es 0.0.SkewY
, de tipodouble
, que representa el ángulo sesgado del eje y, que se mide en grados en sentido contrario a las agujas del reloj desde el eje x. El valor predeterminado de esta propiedad es 0.0.Rotation
, de tipodouble
, representa el ángulo, en grados, de rotación en el sentido de las agujas del reloj. El valor predeterminado de esta propiedad es 0.0.TranslateX
, de tipodouble
, que representa la distancia que se va a mover a lo largo del eje X. El valor predeterminado de esta propiedad es 0.0.TranslateY
, de tipodouble
, que representa la distancia que se va a mover a lo largo del eje y. El valor predeterminado de esta propiedad es 0.0.
Estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que pueden ser destinos de los enlaces de datos, y que se les puede aplicar un estilo.
CompositeTransform
aplica transformaciones en este orden:
- Escalar (
ScaleX
yScaleY
). - Sesgar (
SkewX
ySkewY
). - Girar (
Rotation
). - Trasladar (
TranslateX
,TranslateY
).
Si quieres aplicar varias transformaciones a un objeto en un orden diferente, debes crear TransformGroup
e insertar las transformaciones en el orden previsto.
Importante
CompositeTransform
usa los mismos puntos centrales y CenterX
CenterY
, para todas las transformaciones. Si quieres especificar diferentes puntos centrales por transformación, usa TransformGroup
,
En el ejemplo siguiente se muestra cómo realizar una transformación compuesta mediante la clase CompositeTransform
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
HeightRequest="100"
WidthRequest="100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<CompositeTransform ScaleX="1.5"
ScaleY="1.5"
Rotation="45"
TranslateX="50"
TranslateY="50" />
</Path.RenderTransform>
</Path>
En este ejemplo, el objeto Path
escala 1,5 veces su tamaño, después gira 45 grados y luego se traslada 50 unidades independientes del dispositivo.
Transformaciones de matriz
Una transformación se puede describir en términos de una matriz de transformación afín 3x3, que realiza transformaciones en el espacio 2D. Esta matriz 3x3 se representa mediante la estructura Matrix
, que es una colección de tres filas y tres columnas de valores double
.
La clase Matrix
define las propiedades siguientes:
Determinant
, de tipodouble
, que obtiene el determinante de la matriz.HasInverse
, de tipobool
, que indica si la matriz es invertible.Identity
, de tipoMatrix
, que obtiene una matriz de identidad.HasIdentity
, de tipobool
, que indica si la matriz es una matriz de identidad.M11
, de tipodouble
, que representa el valor de la primera fila y la primera columna de la matriz.M12
, de tipodouble
, que representa el valor de la primera fila y la segunda columna de la matriz.M21
, de tipodouble
, que representa el valor de la segunda fila y la primera columna de la matriz.M22
, de tipodouble
, que representa el valor de la segunda fila y la segunda columna de la matriz.OffsetX
, de tipodouble
, que representa el valor de la tercera fila y la primera columna de la matriz.OffsetY
, de tipodouble
, que representa el valor de la tercera fila y la segunda columna de la matriz.
Las propiedades OffsetX
y OffsetY
se denominan así porque especifican la cantidad para traducir el espacio de coordenadas a lo largo del eje X y el eje Y, respectivamente.
Además, la estructura Matrix
expone una serie de métodos que se pueden usar para manipular los valores de matriz, incluidos Append
, Invert
, Multiply
, Prepend
y muchos más.
En la tabla siguiente, se muestra la estructura de una matriz de Xamarin.Forms:
M11
M12
0,0
M21
M22
0,0
OffsetX
OffsetY
1.0
Nota:
Una matriz de transformación afín tiene su columna final igual a (0,0,1), por lo que solo deben especificarse los miembros de las dos primeras columnas.
Manipulando los valores de la matriz, puedes girar, escalar, inclinar y traducir objetos Path
. Por ejemplo, si cambias el valor OffsetX
a 100, puedes usarlo para mover un objeto Path
100 unidades independientes del dispositivo a lo largo del eje X. Si cambias el valor M22
a 3, puedes usarlo para triplicar el alto actual de un objeto Path
. Si cambias ambos valores, mueves el objeto Path
100 unidades independientes del dispositivo a lo largo del eje X y ajusta su alto a un factor de 3. Además, las matrices de transformación afín se pueden multiplicar para formar cualquier número de transformaciones lineales, como rotación y asimetría, seguidas de la traducción.
Transformaciones personalizadas
La clase MatrixTransform
, que deriva de la clase Transform
, define una propiedad Matrix
, de tipo Matrix
, que representa la matriz que define la transformación. Estas propiedades están respaldadas por objetos BindableProperty
, lo que significa que pueden ser destinos de los enlaces de datos, y con formato de estilo.
Cualquier transformación que puedas describir con un objeto TranslateTransform
, ScaleTransform
, RotateTransform
o SkewTransform
puede describirse igualmente mediante MatrixTransform
. Sin embargo, las clases TranslateTransform
, ScaleTransform
, RotateTransform
y SkewTransform
son más fáciles de conceptualizar que establecer los componentes vectoriales en Matrix
. Por lo tanto, la clase MatrixTransform
se usa normalmente para crear transformaciones personalizadas que no proporcionan las clases RotateTransform
, ScaleTransform
, SkewTransform
o TranslateTransform
.
En el ejemplo siguiente se muestra cómo transformar un objeto Path
mediante MatrixTransform
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<MatrixTransform>
<MatrixTransform.Matrix>
<!-- M11 stretches, M12 skews -->
<Matrix OffsetX="10"
OffsetY="100"
M11="1.5"
M12="1" />
</MatrixTransform.Matrix>
</MatrixTransform>
</Path.RenderTransform>
</Path>
En este ejemplo, el objeto Path
se extiende, inclina y desplaza en las dimensiones X e Y.
Como alternativa, esto se puede escribir en un formato simplificado que usa un convertidor de tipos integrado en Xamarin.Forms:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z">
<Path.RenderTransform>
<MatrixTransform Matrix="1.5,1,0,1,10,100" />
</Path.RenderTransform>
</Path>
En este ejemplo, la propiedad Matrix
se especifica como una cadena delimitada por comas que consta de seis miembros: M11
, M12
, M21
, M22
, OffsetX
, OffsetY
. Aunque los miembros están delimitados por comas en este ejemplo, también se pueden delimitar por uno o varios espacios.
Además, el ejemplo anterior se puede simplificar aún más especificando los mismos seis miembros que el valor de la propiedad RenderTransform
:
<Path Stroke="Black"
Aspect="Uniform"
HorizontalOptions="Center"
RenderTransform="1.5 1 0 1 10 100"
Data="M13.908992,16.207977L32.000049,16.207977 32.000049,31.999985 13.908992,30.109983z" />