変換の概要

このトピックでは、2D Transform クラスを使用して、FrameworkElement オブジェクトを回転、拡大縮小、移動 (平行移動)、および傾斜させる方法について説明します。

変換とは

Transform は、ある座標空間上の点を別の座標空間に対応付ける (変換する) 方法を定義します。 このマッピングは、3 列の Double 値を持つ 3 つの行のコレクションである、Matrix 変換によって記述されます。

注意

Windows Presentation Foundation (WPF) では、行優先の行列が使用されます。 ベクターは、列ベクターではなく行ベクターとして表されます。

次の表は、WPF 行列の構造を示したものです。

2D 変換行列

X 軸 Y 軸 アフィン変換
M11

既定:1
M12

既定:0.0
0.0
M21

既定:0.0
M22

既定:1
0.0
OffsetX

既定:0.0
OffsetY

既定:0.0
1.0

行列の値を操作することで、オブジェクトを回転、拡大縮小、傾斜、移動 (平行移動) させることができます。 たとえば、3 番目の行の 1 列目の値 (OffsetX の値) を 100 に変更すると、それを使用して、オブジェクトを x 軸に沿って 100 単位移動させることができます。 2 番目の行の 2 列目の値を 3 に変更すると、オブジェクトの高さを現在の 3 倍に拡張できます。 両方の値を変更した場合は、オブジェクトが x 軸に沿って 100 単位移動し、高さが 3 倍に拡張されます。 Windows Presentation Foundation (WPF) ではアフィン変換しかサポートされていないため、右側の列の値は常に 0, 0, 1 になります。

Windows Presentation Foundation (WPF) では行列の値を直接操作できますが、一部の Transform クラスでは、基になる行列構造の構成がわかっていなくても、オブジェクトを変換すできます。 たとえば、ScaleTransform クラスでは、変換行列を操作する代わりに、ScaleXScaleY プロパティを設定することで、オブジェクトを拡大縮小できます。 同様に、RotateTransform クラスでは、Angle プロパティを設定するだけで、オブジェクトを回転させることができます。

変換クラス

Windows Presentation Foundation (WPF) では、一般的な変換操作用に、次の 2D Transform クラスが提供されています。

クラス 説明
RotateTransform 指定した Angle の分だけ、要素を回転させます。 オブジェクトを回転させる Rotate illustration
ScaleTransform 指定した ScaleXScaleY の分だけ、要素を拡大縮小します。 要素を拡大縮小する Scale illustration
SkewTransform 指定した AngleXAngleY の分だけ、要素を傾斜させます。 要素を傾斜させる Skew illustration
TranslateTransform 指定した XY の分だけ、要素を移動 (平行移動) します。 要素を平行移動する Translate illustration

より複雑な変換を作成する場合のために、Windows Presentation Foundation (WPF) では次の 2 つのクラスが提供されています。

クラス 説明
TransformGroup 複数の TransformGroup オブジェクトを、後で変換プロパティに適用できる単一の Transform にグループ化できます。 オブジェクトに複数の変換を適用する
MatrixTransform 他の Transform クラスで提供されていないカスタム変換を作成します。 MatrixTransform を使用すると、行列を直接操作することになります。 MatrixTransform を使用してカスタム変換を作成する

Windows Presentation Foundation (WPF) では、3D 変換も利用できます。 詳細については、Transform3D クラスを参照してください。

一般的な変換プロパティ

オブジェクトを変換する 1 つの方法は、適切な Transform 型を宣言し、それをオブジェクトの変換プロパティに適用することです。 オブジェクトの型ごとに、異なる型の変換プロパティがあります。 次の表は、一般的に使用される Windows Presentation Foundation (WPF) の型と、その変換プロパティをまとめたものです。

種類 変換プロパティ
Brush TransformRelativeTransform
ContainerVisual Transform
DrawingGroup Transform
FrameworkElement RenderTransformLayoutTransform
Geometry Transform
TextEffect Transform
UIElement RenderTransform

変換と座標系

オブジェクトを変換する場合は、単にオブジェクトを変換するのではなく、そのオブジェクトが存在する座標空間を変換することになります。 既定では、ターゲット オブジェクトの座標系の原点が変換の中心になります: (0,0)。 唯一の例外は TranslateTransform です。TranslateTransform には、設定する中心プロパティがありません。これは、中心の位置にかかわらず、変換の結果が同じであるためです。

次の例では、RotateTransform を使用して、既定の中心 (0, 0) を軸に Rectangle 要素 (FrameworkElement 型) を 45 度回転させています。 次の図は、回転の結果を示したものです。

A FrameworkElement rotated 45 degrees about (0,0)
ポイント (0, 0) を軸に 45 度回転した四角形要素

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

既定では、要素は左上隅 (0, 0) を軸に回転します。 RotateTransformScaleTransform、および SkewTransform クラスでは、変換の適用先となるポイントを指定するための、CenterX と CenterY プロパティが提供されます。

次の例でも、RotateTransform を使用して Rectangle 要素を 45 度回転させています。ただし今回は、RotateTransform の中心が (25, 25) になるように、CenterXCenterY プロパティが設定されています。 次の図は、回転の結果を示したものです。

A Geometry rotated 45 degrees about (25, 25)
ポイント (25, 25) を軸に 45 度回転した四角形要素

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

FrameworkElement の変換

FrameworkElement に変換を適用するには、Transform を作成し、それを、FrameworkElement クラスで提供されている 2 つのプロパティのいずれかに適用します。

  • LayoutTransform – レイアウト パスの前に適用される変換です。 変換が適用されると、レイアウト システムは変換後のサイズと要素の位置を処理します。

  • RenderTransform – 要素の外観を変更する変換です。ただしこれは、レイアウト パスの完了後に適用されます。 LayoutTransform プロパティの代わりに RenderTransform プロパティを使用することで、パフォーマンス上のメリットを得ることができます。

どちらのプロパティを使用すればよいのでしょうか。 パフォーマンス上のメリットがあるため、可能な場合は常に RenderTransform プロパティを使用してください (特にアニメーション化された Transform オブジェクトを使用する場合)。 拡大縮小、回転、または傾斜を実行する場合で、要素の親を、要素の変換後のサイズに調整する必要がある場合は、LayoutTransform プロパティを使用してください。 なお、LayoutTransform プロパティと共に使用した場合、TranslateTransform オブジェクトは要素に影響を与えないように見えます。 これは、レイアウト システムがその処理の一環として、変換後の要素を元の位置に返すためです。

Windows Presentation Foundation (WPF) のレイアウトの追加情報については、「レイアウト」の概要を参照してください。

例:FrameworkElement を 45 度回転させる

次の例では、RotateTransform を使用して、ボタンを時計回りに 45 度回転させています。 このボタンは、他に 2 つのボタンがある StackPanel に含まれています。

既定では、RotateTransform はポイント (0, 0) を軸に回転します。 この例では中心の値を指定していないので、ボタンは左上隅のポイント (0, 0) を軸に回転します。 RotateTransformRenderTransform プロパティに適用されます。 次の図は、変換の結果を示したものです。

A button transformed using RenderTransform
左上隅を軸とした、時計回り 45 度の回転

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

次の例でも、RotateTransform を使用してボタンを 45 度時計回りに回転させています。ただし、ここでは、ボタンの RenderTransformOrigin を (0.5, 0.5) に設定しています。 RenderTransformOrigin プロパティの値は、ボタンのサイズに対する相対値です。 その結果、回転は左上隅ではなく、ボタンの中心に適用されています。 次の図は、変換の結果を示したものです。

A button transformed about its center
中心を軸とした、時計回り 45 度の回転

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

次の例では、RenderTransform プロパティの代わりに LayoutTransform プロパティを使用してボタンを回転させています。 そのため、変換がボタンのレイアウトに影響し、レイアウト システムによるフル パスがトリガーされています。 その結果、ボタンが回転された後、位置が変更されています。これは、サイズが変更されたためです。 次の図は、変換の結果を示したものです。

A button transformed using LayoutTransform
LayoutTransform を使用したボタンの回転

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

変換のアニメーション化

Transform クラスは Animatable クラスを継承しているため、アニメーション化できます。 Transform をアニメーション化するには、互換性のある型のアニメーションを、アニメーション化するプロパティに適用します。

次の例では、StoryboardDoubleAnimationRotateTransform と共に使用して、Button のクリック時にスピンが起こるようにしています。

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

完全なサンプルについては、「2D 変換のサンプル」をご覧ください。 アニメーション化について詳しくは、「アニメーションの概要」をご覧ください。

Freezable 機能

Transform クラスは Freezable クラスを継承するため、いくつかの特殊な機能を備えています。つまり、Transform オブジェクトをリソースとして宣言すること、複数のオブジェクト間で共有すること、読み取り専用にしてパフォーマンスを高めること、複製すること、スレッド セーフにすることができます。 Freezable オブジェクトで提供されるさまざまな機能について詳しくは、「Freezable オブジェクトの概要」をご覧ください。

関連項目