在WPF學習04:2D繪圖 使用Shape繪基本圖形中,我們了解了如何繪制基本的圖形。
這一次,我們進一步,研究如何將圖形變形。
例子
一個三角形,經Transform形成組合圖形:
XAML代碼:
<Window x:Class="Transforms.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"> <Canvas Name="MainCanvas"> </Canvas> </Window>
C#代碼:
for (int i = 0; i < 36; i++) { var polygon = new Polygon() { Fill = new SolidColorBrush(Colors.LightBlue), Points = new PointCollection() { new Point() {X = 0, Y = 0}, new Point(){X = 100, Y = 5}, new Point(){X = 0, Y = 10} } }; polygon.RenderTransform = new TransformGroup() { Children = new TransformCollection() { new RotateTransform(){ Angle = i * 10} } }; Canvas.SetTop(polygon, 100); Canvas.SetLeft(polygon, 200); MainCanvas.Children.Add(polygon); }
Shape簡介
WPF提供了Transform類,使我們得以對控件進行變形操作。
Transform提供了TranslateTransform(平移變形) RotateTransform(旋轉變形) ScaleTransform(縮放變形) SkewTransform(扭曲變形) MatrixTransform(矩陣變換變形)
回顧一下Shape的繼承結構:
UIElement提供了RenderTransform
FrameworkElement提供了LayoutTransform
兩者皆為Transform類型的屬性,本文將逐個介紹各類變形的使用方法,最后將說明這兩種Transform的區別。
TranslateTransform:
XAML實現:
<Canvas Name="MainCanvas"> <Polygon Points="0,0 100,25 0,50" Stroke="Black" StrokeThickness="2" StrokeDashArray="1 1"></Polygon> <TextBlock Canvas.Top="15" Canvas.Left="2">我是原圖形</TextBlock> <Polygon Points="0,0 100,25 0,50" Fill="#019AFF"> <Polygon.RenderTransform> <TransformGroup> <TranslateTransform X="50" Y="100"></TranslateTransform> </TransformGroup> </Polygon.RenderTransform> </Polygon> </Canvas>
后台代碼實現:
var polygon = new Polygon() { Fill = new SolidColorBrush(Color.FromRgb(0x01, 0x9A, 0xFF)), Points = new PointCollection() { new Point() {X = 0, Y = 0}, new Point(){X = 100, Y = 25}, new Point(){X = 0, Y = 50} }, RenderTransform = new TransformGroup() { Children = new TransformCollection() { new TranslateTransform(){X=50,Y=100} } } }; MainCanvas.Children.Add(polygon);
RotateTransform
XAML實現:
<Canvas Name="MainCanvas"> <Polygon Points="0,0 100,25 0,50" Stroke="Black" StrokeThickness="2" StrokeDashArray="1 1"></Polygon> <TextBlock Canvas.Top="15" Canvas.Left="2">我是原圖形</TextBlock> <Polygon Points="0,0 100,25 0,50" Fill="#019AFF"> <Polygon.RenderTransform> <TransformGroup> <TranslateTransform X="250" Y="100"></TranslateTransform> </TransformGroup> </Polygon.RenderTransform> </Polygon> <Polygon Points="0,0 100,25 0,50" Fill="#019AFF"> <Polygon.RenderTransform> <TransformGroup> <TranslateTransform X="50" Y="100"></TranslateTransform> <RotateTransform CenterX="50" CenterY="100" Angle="50"></RotateTransform> </TransformGroup> </Polygon.RenderTransform> </Polygon> </Canvas>
后台代碼實現:
var polygon = new Polygon() { Fill = new SolidColorBrush(Color.FromRgb(0x01, 0x9A, 0xFF)), Points = new PointCollection() { new Point() {X = 0, Y = 0}, new Point(){X = 100, Y = 25}, new Point(){X = 0, Y = 50} }, RenderTransform = new TransformGroup() { Children = new TransformCollection() { new TranslateTransform(){X=50,Y=100}, new RotateTransform(){Angle=50, CenterX=50, CenterY=100} } } };
注意,這里通過設置CenterX CenterY配置旋轉的參考中心點,改點默認為(0, 0)
ScaleTransform
XAML實現:
<Canvas Name="MainCanvas"> <Polygon Points="0,0 100,25 0,50" Stroke="Black" StrokeThickness="2" StrokeDashArray="1 1"></Polygon> <TextBlock Canvas.Top="15" Canvas.Left="2">我是原圖形</TextBlock> <Polygon Points="0,0 100,25 0,50" Fill="#019AFF"> <Polygon.RenderTransform> <TransformGroup> <TranslateTransform X="50" Y="100"></TranslateTransform> <ScaleTransform ScaleX="0.5" ScaleY="0.5"></ScaleTransform> </TransformGroup> </Polygon.RenderTransform> </Polygon> <Polygon Points="0,0 100,25 0,50" Fill="#019AFF"> <Polygon.RenderTransform> <TransformGroup> <TranslateTransform X="50" Y="100"></TranslateTransform> <ScaleTransform ScaleX="1.5" ScaleY="1.5"></ScaleTransform> </TransformGroup> </Polygon.RenderTransform> </Polygon> </Canvas>
后台代碼實現參考之前的代碼,類似。
SkewTransform
XAML實現:
<Canvas Name="MainCanvas"> <Polygon Points="0,0 100,25 0,50" Stroke="Black" StrokeThickness="2" StrokeDashArray="1 1"></Polygon> <TextBlock Canvas.Top="15" Canvas.Left="2">我是原圖形</TextBlock> <Polygon Points="0,0 100,25 0,50" Fill="#019AFF"> <Polygon.RenderTransform> <TransformGroup> <SkewTransform AngleY="40" ></SkewTransform> </TransformGroup> </Polygon.RenderTransform> </Polygon> </Canvas>
后台代碼實現參考之前的代碼,類似。
MatrixTransform
圖形變換的本質都是將各個點,映射到一個齊次坐標系,然后乘上一個3X3的矩陣進行變換。
這里只實現一個簡單的矩陣實現平移:
實現代碼:
var polygon = new Polygon() { Fill = new SolidColorBrush(Color.FromRgb(0x01, 0x9A, 0xFF)), Points = new PointCollection() { new Point(){X=0, Y = 0}, new Point(){X=0, Y = 50}, new Point(){X=100, Y = 25} }, RenderTransform = new TransformGroup() { Children = new TransformCollection() { new MatrixTransform() { Matrix = new Matrix() { M11 = 1, M12 = 0, M21 = 0, M22 = 1, OffsetX = 150, OffsetY = 100 } } } } }; MainCanvas.Children.Add(polygon);
RenderTransform與LayoutTransform
對於Canvas這樣使用絕對定位的Layout控件下的變形操作,兩者的效果是一致的。
而在其它的布局控件中,LayoutTransform是會影響到布局的。
XAML代碼:
<StackPanel Name="MainCanvas"> <Polygon Points="0,0 150,25 0,50" Stroke="Black" StrokeThickness="2" StrokeDashArray="1 1"> <Polygon.LayoutTransform> <RotateTransform Angle="50"></RotateTransform> </Polygon.LayoutTransform> </Polygon> <Polygon Points="0,0 150,25 0,50" Stroke="Black" StrokeThickness="2" StrokeDashArray="1 1"></Polygon> </StackPanel>
我們將LayoutTransform改為RenderTransform,結果如下: