変換の概要
このトピックでは、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 クラスでは、変換行列を操作する代わりに、ScaleX と ScaleY プロパティを設定することで、オブジェクトを拡大縮小できます。 同様に、RotateTransform クラスでは、Angle プロパティを設定するだけで、オブジェクトを回転させることができます。
変換クラス
Windows Presentation Foundation (WPF) では、一般的な変換操作用に、次の 2D Transform クラスが提供されています。
クラス | 説明 | 例 | 図 |
---|---|---|---|
RotateTransform | 指定した Angle の分だけ、要素を回転させます。 | オブジェクトを回転させる | |
ScaleTransform | 指定した ScaleX と ScaleY の分だけ、要素を拡大縮小します。 | 要素を拡大縮小する | |
SkewTransform | 指定した AngleX と AngleY の分だけ、要素を傾斜させます。 | 要素を傾斜させる | |
TranslateTransform | 指定した X と Y の分だけ、要素を移動 (平行移動) します。 | 要素を平行移動する |
より複雑な変換を作成する場合のために、Windows Presentation Foundation (WPF) では次の 2 つのクラスが提供されています。
クラス | 説明 | 例 |
---|---|---|
TransformGroup | 複数の TransformGroup オブジェクトを、後で変換プロパティに適用できる単一の Transform にグループ化できます。 | オブジェクトに複数の変換を適用する |
MatrixTransform | 他の Transform クラスで提供されていないカスタム変換を作成します。 MatrixTransform を使用すると、行列を直接操作することになります。 | MatrixTransform を使用してカスタム変換を作成する |
Windows Presentation Foundation (WPF) では、3D 変換も利用できます。 詳細については、Transform3D クラスを参照してください。
一般的な変換プロパティ
オブジェクトを変換する 1 つの方法は、適切な Transform 型を宣言し、それをオブジェクトの変換プロパティに適用することです。 オブジェクトの型ごとに、異なる型の変換プロパティがあります。 次の表は、一般的に使用される Windows Presentation Foundation (WPF) の型と、その変換プロパティをまとめたものです。
変換と座標系
オブジェクトを変換する場合は、単にオブジェクトを変換するのではなく、そのオブジェクトが存在する座標空間を変換することになります。 既定では、ターゲット オブジェクトの座標系の原点が変換の中心になります: (0,0)。 唯一の例外は TranslateTransform です。TranslateTransform には、設定する中心プロパティがありません。これは、中心の位置にかかわらず、変換の結果が同じであるためです。
次の例では、RotateTransform を使用して、既定の中心 (0, 0) を軸に Rectangle 要素 (FrameworkElement 型) を 45 度回転させています。 次の図は、回転の結果を示したものです。
ポイント (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) を軸に回転します。 RotateTransform、ScaleTransform、および SkewTransform クラスでは、変換の適用先となるポイントを指定するための、CenterX と CenterY プロパティが提供されます。
次の例でも、RotateTransform を使用して Rectangle 要素を 45 度回転させています。ただし今回は、RotateTransform の中心が (25, 25) になるように、CenterX と CenterY プロパティが設定されています。 次の図は、回転の結果を示したものです。
ポイント (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) を軸に回転します。 RotateTransform は 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 プロパティの値は、ボタンのサイズに対する相対値です。 その結果、回転は左上隅ではなく、ボタンの中心に適用されています。 次の図は、変換の結果を示したものです。
中心を軸とした、時計回り 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 プロパティを使用してボタンを回転させています。 そのため、変換がボタンのレイアウトに影響し、レイアウト システムによるフル パスがトリガーされています。 その結果、ボタンが回転された後、位置が変更されています。これは、サイズが変更されたためです。 次の図は、変換の結果を示したものです。
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 をアニメーション化するには、互換性のある型のアニメーションを、アニメーション化するプロパティに適用します。
次の例では、Storyboard と DoubleAnimation を RotateTransform と共に使用して、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 オブジェクトの概要」をご覧ください。
関連項目
.NET Desktop feedback