Visão geral das transformações

Este tópico descreve como usar as classes 2D Transform para girar, dimensionar, mover (traduzir) e distorcer objetos FrameworkElement.

O que é uma transformação?

Um Transform define como mapear ou transformar pontos de um espaço de coordenadas para outro espaço de coordenadas. Esse mapeamento é descrito por uma transformação Matrix, que é uma coleção de três linhas com três colunas de valores Double.

Nota

O WPF (Windows Presentation Foundation) usa matrizes principais de linha. Os vetores são expressos como vetores de linha, não vetores de coluna.

A tabela a seguir mostra a estrutura de uma matriz do WPF.

Uma matriz de transformação 2D

Eixo X Eixo Y Transformação Affine
M11

Padrão: 1.0
M12

Padrão: 0.0
0.0
M21

Padrão: 0.0
M22

Padrão: 1.0
0.0
OffsetX

Padrão: 0.0
OffsetY

Padrão: 0.0
1.0

Ao manipular valores de matriz, você pode girar, dimensionar, distorcer e mover (traduzir) um objeto. Por exemplo, se você alterar o valor na primeira coluna da terceira linha (o valor OffsetX) para 100, poderá usá-lo para mover um objeto 100 unidades ao longo do eixo x. Se você alterar o valor na segunda coluna da segunda linha para 3, poderá usá-lo para alongar um objeto para três vezes a altura atual. Se você alterar os valores, mova objeto 100 unidades no eixo e alongue sua altura por um fator de 3. Como o Windows Presentation Foundation (WPF) dá suporte apenas a transformações de afim, os valores na coluna direita são sempre 0, 0, 1.

Embora o WPF (Windows Presentation Foundation) permita manipular diretamente valores de matriz, ele também fornece várias classes de Transform que permitem transformar um objeto sem saber como a estrutura de matriz subjacente está configurada. Por exemplo, a classe ScaleTransform permite dimensionar um objeto definindo suas propriedades ScaleX e ScaleY, em vez de manipular uma matriz de transformação. Da mesma forma, a classe RotateTransform permite que você gire um objeto apenas definindo sua propriedade Angle.

Classes de transformação

O WPF (Windows Presentation Foundation) fornece as seguintes classes Transform 2D para operações de transformação comuns:

Classe Descrição Exemplo Ilustração
RotateTransform Gira um elemento pelo Angle especificado. girar um objeto Ilustração de girar
ScaleTransform Dimensiona um elemento pelas quantidades ScaleX e ScaleY especificadas. dimensionar um elemento Ilustração de dimensionar
SkewTransform Distorce um elemento pelos valores especificados de AngleX e AngleY. distorcer um elemento Ilustração de distorção
TranslateTransform Movimenta (translada) um elemento pelas quantidades X e Y especificadas. traduzir um elemento Ilustração de converter

Para criar transformações mais complexas, o Windows Presentation Foundation (WPF) fornece as duas seguintes classes:

Classe Descrição Exemplo
TransformGroup Agrupa vários objetos TransformGroup em uma única Transform que você pode aplicar para transformar propriedades. aplicar várias transformações a um objeto
MatrixTransform Cria transformações personalizadas que não são fornecidas pelas outras classes Transform. Ao usar um MatrixTransform, você manipula uma Matriz diretamente. usar um MatrixTransform para criar transformações personalizadas

O WPF (Windows Presentation Foundation) também fornece transformações 3D. Para obter mais informações, consulte a classe Transform3D.

Propriedades comuns da transformação

Uma maneira de transformar um objeto é declarar o tipo de Transform apropriado e aplicá-lo à propriedade de transformação do objeto. Diferentes tipos de objetos têm diferentes tipos de propriedades de transformação. A tabela a seguir lista vários tipos do WPF (Windows Presentation Foundation) comumente usados e suas propriedades de transformação.

Tipo Propriedades de transformação
Brush Transform, RelativeTransform
ContainerVisual Transform
DrawingGroup Transform
FrameworkElement RenderTransform, LayoutTransform
Geometry Transform
TextEffect Transform
UIElement RenderTransform

Transformações e sistemas de coordenadas

Ao transformar um objeto, você não transforma apenas o objeto, transforma o espaço de coordenadas no qual esse objeto existe. Por padrão, uma transformação é centralizada na origem do sistema de coordenadas do objeto de destino: (0,0). A única exceção é TranslateTransform; um TranslateTransform não tem nenhuma propriedade central a ser definida porque o efeito de tradução é o mesmo, independentemente de onde ele está centralizado.

O exemplo a seguir usa um RotateTransform para girar um elemento Rectangle, um tipo de FrameworkElement, em 45 graus sobre seu centro padrão, (0, 0). A ilustração a seguir mostra o efeito da rotação.

Um FrameworkElement girava 45 graus sobre (0,0)
Um elemento Rectangle girava 45 graus sobre o ponto (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>

Por padrão, o elemento gira sobre o canto superior esquerdo (0, 0). As classes RotateTransform, ScaleTransforme SkewTransform fornecem propriedades CenterX e CenterY que permitem especificar o ponto no qual a transformação é aplicada.

O próximo exemplo também usa um RotateTransform para girar um elemento Rectangle em 45 graus; no entanto, desta vez, as propriedades CenterX e CenterY são definidas para que o RotateTransform tenha um centro de (25, 25). A ilustração a seguir mostra o efeito da rotação.

Geometria rotacionada 45 graus ao redor (25, 25)
Um elemento Retângulo girava 45 graus sobre o ponto (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>

Transformando um FrameworkElement

Para aplicar transformações a um FrameworkElement, crie um Transform e aplique-o a uma das duas propriedades fornecidas pela classe FrameworkElement:

  • LayoutTransform – uma transformação que é aplicada antes do cálculo de layout. Depois que a transformação é aplicada, o sistema de layout processa o tamanho e a posição transformados do elemento.

  • RenderTransform – uma transformação que modifica a aparência do elemento, mas é aplicada após a conclusão da passagem de layout. Usando a propriedade RenderTransform em vez da propriedade LayoutTransform, você pode obter benefícios de desempenho.

Qual propriedade você deve usar? Devido aos benefícios de desempenho fornecidos, use a propriedade RenderTransform sempre que possível, especialmente quando você usar objetos de Transform animados. Use a propriedade LayoutTransform ao dimensionar, girar ou distorcer e para que o elemento pai se ajuste ao tamanho transformado do elemento. Observe que, quando eles são usados com a propriedade LayoutTransform, TranslateTransform objetos parecem não ter efeito sobre os elementos. Isso ocorre porque o sistema de layout retorna o elemento traduzido para sua posição original como parte de seu processamento.

Para obter informações adicionais sobre o layout no WPF (Windows Presentation Foundation), consulte Visão geral do layout.

Exemplo: Rotacionar um FrameworkElement em 45 graus

O exemplo a seguir usa um RotateTransform para girar um botão no sentido horário em 45 graus. O botão está contido em um StackPanel que tem dois outros botões.

Por padrão, um RotateTransform gira sobre o ponto (0, 0). Como o exemplo não especifica um valor central, o botão gira sobre o ponto (0, 0), que é o canto superior esquerdo. O RotateTransform é aplicado à propriedade RenderTransform. A ilustração a seguir mostra o resultado da transformação.

Um botão transformado usando RenderTransform
Rotação horária em 45 graus no canto superior esquerdo

<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>

O exemplo a seguir também usa um RotateTransform para girar um botão 45 graus no sentido horário, mas também define o RenderTransformOrigin do botão como (0,5, 0,5). O valor da propriedade RenderTransformOrigin é relativo ao tamanho do botão. Como resultado, a rotação é aplicada ao centro do botão, em vez de seu canto superior esquerdo. A ilustração a seguir mostra o resultado da transformação.

Um botão transformado ao redor do seu centro
Rotação de 45 graus no sentido horário em torno do 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>

O exemplo a seguir usa a propriedade LayoutTransform em vez da propriedade RenderTransform para girar o botão. Isso faz com que a transformação afete o layout do botão, que dispara uma passagem completa pelo sistema de layout. Como resultado, o botão é girado e reposicionado porque seu tamanho foi alterado. A ilustração a seguir mostra o resultado da transformação.

Um botão transformado usando LayoutTransform
LayoutTransform usado para girar o botão

<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>

Animando transformações

Pelo fato de herdarem da classe Animatable, as classes Transform podem ser animadas. Para animar um Transform, aplique uma animação de um tipo compatível à propriedade que você deseja animar.

O exemplo a seguir usa um Storyboard e um DoubleAnimation junto com um RotateTransform para fazer o Button girar no lugar quando clicado.

<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 obter o exemplo completo, consulte exemplo de transformações 2D. Para obter mais informações sobre animações, consulte a visão geral da animação .

Recursos congeláveis

Como ele herda da classe Freezable, a classe Transform fornece várias funcionalidades especiais: os objetos Transform podem ser declarados como recursos, compartilhados entre vários objetos, transformados em somente leitura para aprimorar o desempenho, clonados e transformados em thread-safe. Para obter mais informações sobre os diferentes recursos fornecidos por objetos Freezable, consulte a Visão Geral dos Objetos Congeláveis.

Consulte também