Información general sobre transformaciones

En este tema se describe cómo usar clases Transform de 2D para girar, escalar, mover (trasladar) y distorsionar objetos FrameworkElement.

¿Qué es una transformación?

Transform define el modo en que se asignan (o transforman) puntos de un espacio de coordenadas a otro. Esta asignación se describe mediante una estructura Matrix de transformación, que es una colección de tres filas por tres columnas de valores Double.

Nota

Windows Presentation Foundation (WPF) usa matrices principales de fila. Los vectores se expresan como vectores de fila, no como vectores de columna.

En la tabla siguiente se muestra la estructura de una matriz de WPF.

Matriz de transformación 2D

Eje X Eje Y Transformaciones afines
M11

Valor predeterminado: 1.0
M12

Valor predeterminado: 0.0
0,0
M21

Valor predeterminado: 0.0
M22

Valor predeterminado: 1.0
0,0
OffsetX

Valor predeterminado: 0.0
OffsetY

Valor predeterminado: 0.0
1,0

Manipulando los valores de la matriz, puede girar, escalar, sesgar y mover (trasladar) un objeto. Por ejemplo, si cambia a 100 el valor de la primera columna de la tercera fila (el valor de OffsetX), puede usarlo para mover un objeto 100 unidades a lo largo del eje X. Si cambia a 3 el valor de la segunda columna de la segunda fila, puede usarlo para triplicar el alto actual de un objeto. Si cambia ambos valores, mueve el objeto 100 unidades a lo largo del eje X y ajusta su alto a un factor de 3. Como Windows Presentation Foundation (WPF) solo admite transformaciones afines, los valores de la columna derecha siempre son 0, 0, 1.

Aunque Windows Presentation Foundation permite manipular directamente los valores de matriz, también proporciona varias clases Transform que permiten transformar un objeto sin conocer cómo se configura la estructura de matriz subyacente. Por ejemplo, la clase ScaleTransform le permite escalar un objeto al establecer las propiedades ScaleX y ScaleY, en vez de manipular la matriz de transformación. Del mismo modo, la clase RotateTransform le permite girar un objeto al establecer solo la propiedad Angle.

Clases Transform

Windows Presentation Foundation (WPF) proporciona las siguientes clases Transform de 2D para las operaciones de transformación comunes:

Clase Descripción Ejemplo Ilustración
RotateTransform Gira un elemento según la propiedad Angle especificada. Girar un objeto Ilustración de un giro
ScaleTransform Escala un elemento por las cantidades ScaleX y ScaleY especificadas. Ajustar la escala de un elemento Ilustración del ajuste de la escala
SkewTransform Distorsiona un elemento por las cantidades AngleX y AngleY especificadas. Sesgar un elemento Ilustración del sesgo
TranslateTransform Mueve (traslada) un elemento por las cantidades X y Y especificadas. Trasladar un elemento Ilustración de un traslado

Para crear transformaciones más complejas, Windows Presentation Foundation (WPF) proporciona las dos clases siguientes:

Clase Descripción Ejemplo
TransformGroup Agrupa varios objetos TransformGroup en un solo Transform que puede aplicar a las propiedades de transformación. Aplicar varias transformaciones a un objeto
MatrixTransform Crea transformaciones personalizadas que no proporcionan otras clases Transform. Cuando usa MatrixTransform, manipula la matriz directamente. Usar un objeto MatrixTransform para crear transformaciones personalizadas

Windows Presentation Foundation (WPF) también proporciona transformaciones 3D. Para obtener más información, vea la clase Transform3D.

Propiedades de transformación comunes

Una manera de transformar un objeto es declarar el tipo Transform correspondiente y aplicarlo a la propiedad de transformación del objeto. Los diferentes tipos de objetos tienen distintos tipos de propiedades de transformación. En la siguiente tabla se enumeran varios tipos de Windows Presentation Foundation (WPF) usados comúnmente y sus propiedades de transformación.

Tipo Propiedades de transformación
Brush Transform, RelativeTransform
ContainerVisual Transform
DrawingGroup Transform
FrameworkElement RenderTransform, LayoutTransform
Geometry Transform
TextEffect Transform
UIElement RenderTransform

Transformaciones y sistemas de coordenadas

Al transformar un objeto, no solo transforma el objeto, se transformar el espacio de coordenadas en el que se encuentra. De forma predeterminada, una transformación tiene su centro en el origen del sistema de coordenadas del objeto de destino: (0,0). La única excepción es TranslateTransform; TranslateTransform no tiene propiedades de centrado que establecer porque el efecto de traslación es el mismo independientemente del lugar donde esté centrado.

En el ejemplo siguiente se usa RotateTransform para girar un elemento Rectangle, un tipo de FrameworkElement, 45 grados desde su centro predeterminado (0, 0). En la ilustración siguiente se muestra el efecto de la rotación.

Un elemento FrameworkElement se rotó 45 grados aproximadamente (0,0)
Elemento Rectangle girado 45 grados alrededor del punto (0,0)

<Canvas Width="200" Height="200">
  <Rectangle 
    Canvas.Left="100" Canvas.Top="100"
    Width="50" Height="50" 
    Fill="RoyalBlue" Opacity="1.0">
    <Rectangle.RenderTransform>
      <RotateTransform Angle="45" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Canvas>

De forma predeterminada, el elemento gira sobre su esquina superior izquierda, (0, 0). Las clases RotateTransform, ScaleTransform y SkewTransform proporcionan propiedades CenterX y CenterY que le permiten especificar el punto al que se aplica la transformación.

En el ejemplo siguiente también se usa RotateTransform para girar un elemento Rectangle 45 grados, pero, esta vez, las propiedades CenterX y CenterY establecen que RotateTransform tiene un centro de (25, 25). En la ilustración siguiente se muestra el efecto de la rotación.

Una geometría se rotó 45 grados aproximadamente (25, 25)
Elemento Rectangle girado 45 grados alrededor del punto (25, 25)

<Canvas Width="200" Height="200">
  <Rectangle 
    Canvas.Left="100" Canvas.Top="100"
    Width="50" Height="50" 
    Fill="RoyalBlue" Opacity="1.0">
    <Rectangle.RenderTransform>
      <RotateTransform Angle="45" CenterX="25" CenterY="25" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Canvas>

Transformación de un elemento FrameworkElement

Para aplicar transformaciones a FrameworkElement, cree una clase Transform y aplíquela a una de las dos propiedades que proporciona la clase FrameworkElement:

  • LayoutTransform: transformación que se aplica antes del cálculo de diseño. Después de aplicar la transformación, el sistema de diseño procesa el tamaño y la posición transformados del elemento.

  • RenderTransform: transformación que modifica la apariencia del elemento, pero se aplica una vez completado el cálculo de diseño. Mediante la propiedad RenderTransform en lugar de la propiedad LayoutTransform, puede obtener ventajas de rendimiento.

¿Qué propiedad debe usar? Debido a las ventajas de rendimiento que proporciona, use la propiedad RenderTransform siempre que sea posible, sobre todo cuando use objetos Transform animados. Use la propiedad LayoutTransform cuando vaya a ajustar la escala, rotar o distorsionar y necesite que el elemento primario se ajuste al tamaño transformado del elemento. Tenga en cuenta que. cuando se usan con la propiedad LayoutTransform, los objetos TranslateTransform parecen no tener efecto en los elementos. Esto se debe a que el sistema de diseño devuelve el elemento trasladado a su posición original como parte de su procesamiento.

Para información adicional sobre el diseño en Windows Presentation Foundation (WPF), consulte la información general sobre el diseño.

Ejemplo: Girar un elemento FrameworkElement 45 grados

En el ejemplo siguiente, se usa RotateTransform para girar un botón 45 grados en el sentido de las agujas del reloj. El botón se almacena en una clase StackPanel que tiene otros dos botones.

De forma predeterminada, RotateTransform gira sobre el punto (0, 0). Puesto que el ejemplo no especifica un centro, el botón gira sobre el punto (0, 0), que está en la esquina superior izquierda. RotateTransform se aplica a la propiedad RenderTransform. En la ilustración siguiente se muestra el resultado de la transformación.

Un botón transformado mediante RenderTransform
Rotación de 45 grados en el sentido de las agujas del reloj desde la esquina superior izquierda

<Border Margin="30" 
  HorizontalAlignment="Left" VerticalAlignment="Top"
  BorderBrush="Black" BorderThickness="1" >
  <StackPanel Orientation="Vertical">
    <Button Content="A Button" Opacity="1" />
    <Button Content="Rotated Button">
      <Button.RenderTransform>
        <RotateTransform Angle="45" />
      </Button.RenderTransform>
    </Button>
    <Button Content="A Button" Opacity="1" />
  </StackPanel>
</Border>

En el ejemplo siguiente también se usa RotateTransform para girar un botón 45 grados en el sentido de las agujas del reloj; pero también se establece la propiedad RenderTransformOrigin del botón en (0,5, 0,5). El valor de la propiedad RenderTransformOrigin es relativo al tamaño del botón. Como resultado, la rotación se aplica al centro del botón en lugar de a la esquina superior izquierda. En la ilustración siguiente se muestra el resultado de la transformación.

Un botón transformado alrededor de su centro
Rotación de 45 grados en el sentido de las agujas del reloj alrededor del centro

<Border Margin="30"   
  HorizontalAlignment="Left" VerticalAlignment="Top"
  BorderBrush="Black" BorderThickness="1">
  <StackPanel Orientation="Vertical">
    <Button Content="A Button" Opacity="1" />
    <Button Content="Rotated Button"
      RenderTransformOrigin="0.5,0.5">
      <Button.RenderTransform>
        <RotateTransform Angle="45" />
      </Button.RenderTransform>
    </Button>
    <Button Content="A Button" Opacity="1" />
  </StackPanel>
</Border>

En el ejemplo siguiente se usa la propiedad LayoutTransform en vez de la propiedad RenderTransform para girar el botón. Esto hace que la transformación afecte al diseño del botón, lo que desencadena un recorrido completo del sistema de diseño. Como resultado, el botón se gira y se vuelve a cambiar de posición porque su tamaño ha cambiado. En la ilustración siguiente se muestra el resultado de la transformación.

Botón transformado mediante LayoutTransform
Propiedad LayoutTransform utilizada para girar el botón

<Border Margin="30"   
 HorizontalAlignment="Left" VerticalAlignment="Top"
 BorderBrush="Black" BorderThickness="1">
  <StackPanel Orientation="Vertical">

    <Button Content="A Button" Opacity="1" />   
    <Button Content="Rotated Button">
      <Button.LayoutTransform>
        <RotateTransform Angle="45"  />
      </Button.LayoutTransform>
    </Button>   
    <Button Content="A Button" Opacity="1" />
  </StackPanel>
</Border>

Animación de transformaciones

Como heredan de la clase Animatable, las clases Transform se pueden animar. Para animar un objeto Transform, aplica una animación de un tipo compatible a la propiedad que quieras animar.

En el ejemplo siguiente se usan Storyboard y DoubleAnimation con RotateTransform para hacer que Button gire en su sitio cuando le hacen clic.

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Button Animated RotateTransform Example"
  Background="White" Margin="50">
  <StackPanel>
    
    

    <Button Content="A Button"
      RenderTransformOrigin="0.5,0.5">
      <Button.RenderTransform>
        <RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
      </Button.RenderTransform>
      <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation 
                Storyboard.TargetName="AnimatedRotateTransform"
                Storyboard.TargetProperty="Angle" 
                To="360" Duration="0:0:1" FillBehavior="Stop" />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Button.Triggers>
    </Button>

  </StackPanel>
</Page>

Para ver el ejemplo completo, consulte Ejemplo de transformaciones 2D. Para más información sobre animaciones, vea Información general sobre animaciones.

Características de objeto Freezable

Como hereda de la clase Freezable, la clase Transform presenta varias características especiales: los objetos Transform se pueden declarar como recursos, compartirse entre varios objetos, convertirse en objetos de solo lectura para mejorar el rendimiento, clonarse y hacerse seguros para subprocesos. Para más información sobre las diferentes características que ofrecen los objetos Freezable, vea Información general sobre objetos Freezable.

Vea también