当前位置: 首页 > news >正文

WPF中的变换(Transform)功能详解

Transform

在WPF中,我们可以通过变换(Transform),对UI对象进行旋转、缩放、移动(平移)和倾斜等操作

通过使用变换(transform),许多绘图任务将更趋简单;

在 WPF 中,变换由继承自System.Windows.Media.Transform抽象类的类表示,

常用的Transform派生类如下所示

类型描述常用属性示意图
RotateTransform

旋转坐标系统。正常绘制的形状绕着选择的中心点旋转

Angle:角度

CenterX:旋转中心坐标-X

CenterY:旋转中心坐标-Y

Rotate illustration

ScaleTransform

放大或缩小坐标系统,从而绘制更大或更小的图形。

可在X和Y方向应用不同的缩放度,从而拉伸或压缩形状

ScaleX:X方向的缩放度

ScaleY:Y方向的缩放度

CenterX:缩放中心坐标-X

CenterY:缩放中心坐标-Y

Scale illustration

SkewTransform

通过倾斜一定的角度扭曲坐标系统。

例如,如果绘制正方形,通过该变换正方形会变成平行四边形

AngleX:X方向的倾斜度

AngleY:Y方向的倾斜度

CenterX:倾斜中心坐标-X

CenterY:倾斜中心坐标-Y

Skew illustration

TranslateTransform

将坐标系统移动一定距离。

X:X方向偏移距离 

Y:Y方向偏移距离 

Translate illustration

另外还有两种复杂一点的派生类型

类型描述
TransformGroup

组合多个变换,从而可以一次应用所有这些变换。应用变换的顺序是很重要的,因为这会影响最终结果。

例如,首先使用RotateTransform旋转形状,然后使用TranslateTransform移动形状,这样做的结果和先移动再旋转的结果是不同的

MatrixTransform

使用提供的矩阵的乘积修改坐标系统。这是最复杂的选择——为实现该变换,需要掌握一些数学技巧

Transform的原理

从技术角度看,所有变换都使用矩阵数学改变形状的坐标。不过,使用预先构建好的变换,如TranslateTransform 、 RotateTransformScaleTransform以及SkewTransform ,

比使用MatrixTransform并尝试为希望执行的操作构造正确的矩阵要简单得多。

底层调用来说,都是使用了MILCMD_MATRIXTRANSFORM类型作为最终传递的数据结构

1 [StructLayout(LayoutKind.Explicit, Pack=1)]
2 internal struct MILCMD_MATRIXTRANSFORM
3 {
4     [FieldOffset(0)] internal MILCMD Type;
5     [FieldOffset(4)] internal DUCE.ResourceHandle Handle;
6     [FieldOffset(8)] internal MilMatrix3x2D Matrix;
7     [FieldOffset(56)] internal DUCE.ResourceHandle hMatrixAnimations;
8 };

当使用TransformGroup执行一系列变换时,WPF将所有变换融合到单独的MatrixTransform变换中以确保获得最佳性能。

在win32编程或winform中,没有提供类似的变换功能,需要我们进行重绘才能实现。

简而言之,就是为了方便用户使用,RotateTransformScaleTransform等类型是对MatrixTransform类型进行了再封装。

变换元素(Transforming a FrameworkElement)

这里分为了两种类型

  • LayoutTransform – 在布局过程开始前应用的变换。 应用转换后,布局系统将处理元素的转换大小和位置。

  • RenderTransform – 修改元素外观的转换,但在布局处理完成后应用。 通过使用属性 RenderTransform 而不是 LayoutTransform 属性,可以获得性能优势。

这两种类型的应用场景:

尽可能使用 RenderTransform 属性,尤其是在使用动画 Transform 对象时。

如果需要元素在进行缩放、旋转或倾斜时,父级调整为元素变换后的大小,可以使用LayoutTransform属性,

下面我们来演示一下

我们在界面上放置一个Image控件,然后来看一下当使用不同Transform时,它呈现的效果。

1      <Border Grid.Row="1" BorderThickness="1" BorderBrush="Black" VerticalAlignment="Center">
2          <StackPanel>
3              <Label Content="未进行变换 图像宽=200 高=150"></Label>
4              <Image Source="img.jpg" Height="200" Width="150"></Image>
5          </StackPanel>
6      </Border>

RotateTransform

 1        <Border BorderThickness="1" BorderBrush="Black" >2            <StackPanel>3                <Label Content="RotateTransform Angle=90 CenterX=75 CenterY=100"></Label>4                <Image Source="img.jpg" Height="200" Width="150">5                    <Image.RenderTransform>6                        <!--旋转中心点75,100-->7                        <!--角度:90度-->8                        <RotateTransform Angle="90" CenterX="75" CenterY="100"></RotateTransform>9                    </Image.RenderTransform>
10                </Image>
11            </StackPanel>
12        </Border>

ScaleTransform 

 1  <Border BorderThickness="1" BorderBrush="Black" Grid.Row="1">2      <StackPanel>3          <Label Content="ScaleTransform ScaleX=0.8 ScaleY=0.8 CenterX=75 CenterY=100"></Label>4          <Image Source="img.jpg" Height="200" Width="150">5              <Image.RenderTransform>6                  <!--缩放中心点是75,100-->7                  <!--水平缩放0.8 垂直缩放0.7-->8                  <ScaleTransform ScaleX="0.8" ScaleY="0.8" CenterX="75" CenterY="100"></ScaleTransform>9              </Image.RenderTransform>
10          </Image>
11      </StackPanel>
12  </Border>

SkewTransform

 1    <Border BorderThickness="1" BorderBrush="Black" Grid.Row="2">2        <StackPanel>3            <Label Content="SkewTransform AngleX=10 AngleY=10 CenterX=75 CenterY=100"></Label>4            <Image Source="img.jpg" Height="200" Width="150">5                <Image.RenderTransform>6                    <!--倾斜中心点是75,100-->7                    <!--水平倾斜10度 垂直倾斜10度-->8                    <SkewTransform AngleX="10" AngleY="10" CenterX="75" CenterY="100"></SkewTransform>9                </Image.RenderTransform>
10            </Image>
11        </StackPanel>
12    </Border>

TranslateTransform 

 1    <Border BorderThickness="1" BorderBrush="Black" Grid.Row="3">2        <StackPanel>3            <Label Content="TranslateTransform X=50 Y=20"></Label>4            <Image Source="img.jpg" Height="200" Width="150">5                <Image.RenderTransform>7                    <!--水平偏移100 垂直偏移20-->8                    <TranslateTransform X="100" Y="20"></TranslateTransform>9                </Image.RenderTransform>
10            </Image>
11        </StackPanel>
12    </Border>

TransformGroup

 1    <Border BorderThickness="1" BorderBrush="Black" Grid.Row="1">2        <StackPanel>3            <Label Content="ScaleTransform ScaleX=0.8 ScaleY=0.8 CenterX=75 CenterY=100"></Label>4            <Image Source="img.jpg" Height="200" Width="150">5                <Image.RenderTransform>6                    <TransformGroup>7                        <!--缩放中心点是75,100-->8                        <!--水平缩放0.8 垂直缩放0.7-->9                        <ScaleTransform ScaleX="0.8" ScaleY="0.8" CenterX="75" CenterY="100"></ScaleTransform>
10                        <!--倾斜中心点是75,100-->
11                        <!--水平倾斜10度 垂直倾斜10度-->
12                        <TranslateTransform X="100" Y="20"></TranslateTransform>
13                    </TransformGroup>
14                </Image.RenderTransform>
15            </Image>
16        </StackPanel>
17    </Border>

MatrixTransform

 1     <Border BorderThickness="1" BorderBrush="Black" Grid.Row="2">2         <StackPanel>3             <Label Content="Matrix OffsetX=15 OffsetY=10 M11=1 M12=1 M21=0.1 M22=1"></Label>4             <Image Source="img.jpg" Height="200" Width="150">5                 <Image.RenderTransform>6                     <MatrixTransform x:Name="myMatrixTransform">7                         <MatrixTransform.Matrix >8                             <Matrix OffsetX="15" OffsetY="10" M11="1" M12="1" M21="0.1" M22="1"/>9                         </MatrixTransform.Matrix>
10                     </MatrixTransform>
11                 </Image.RenderTransform>
12             </Image>
13         </StackPanel>
14     </Border>

关于MatrixTransform,本文没有做详细介绍,可以参考下面的链接

https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.matrixtransform?view=windowsdesktop-9.0

运行结果:

image

转换和坐标系统

在对WPF中的对象进行转换(Transform)时,不仅仅是转换了这个对象,而且还包括了该对象所在的坐标空间。

默认情况下,转换以目标对象的坐标系的原点为中心:(0,0)

使用RotateTransform 的 CenterX和 CenterY属性时存在明显的限制。

这些属性是使用绝对坐标定义的,也就是说我们需要知道内容的中心点的准确位置。

如果正在显示动态内容(例如,可变维度的图片或可改变尺寸的元素),就会出现问题。

这个时候我们可以通过UIElement.RenderTransformOrigin属性使用相对坐标系统设置中心点。相对坐标系统在两个方向上的范围都是从0到1。

换句话说,点(0,0)被指定为左上角,点(1,1)表示右下角(如果形状区域不是正方形,那么会相应地拉伸坐标系统)。

借助于RenderTransformOrigin属性,可使用如下所示的代码,绕中心点旋转任意元素:

 1   <Border BorderThickness="1" BorderBrush="Black" Grid.Row="3">2       <StackPanel>3           <Label Content="RotateTransform Angle=90 通过RenderTransformOrigin指定中心点"></Label>4           <Image Source="img.jpg" Height="200" Width="150" RenderTransformOrigin="0.5,0.5">5               <Image.RenderTransform>6                   <RotateTransform Angle="90"></RotateTransform>7               </Image.RenderTransform>8           </Image>9       </StackPanel>
10   </Border>

注意:在WPF中只有少量元素不能使用Transform,例如WindowsFormHost和WebView2 

示例代码

下载

参考资料:

https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/transforms-overview

http://www.dtcms.com/a/495582.html

相关文章:

  • 北京做网站主机开通成功网站建设中
  • 工业显示器在微铣削机床中的应用
  • 合肥手机网站建设陕西网站建设平台
  • 东莞网站推广及优化平台营销策略
  • exp4j并发解决
  • 学习博弈本身过程脑是怎么看的?
  • 风险感知中枢:监测预警系统的架构与核心
  • 使用ROS2 + Qt编写一个简易计算器
  • 校园资料分享平台|基于SpringBoot和Vue的校园资料分享平台(源码+数据库+文档)
  • 企业花钱做的网站出现违禁词本地wordpress 手机浏览器
  • 网站建设最基础是什么广东网站建设服务商
  • 如何模仿一个网站云手机免费版无限挂机
  • Vue2 + Office Add-in关于用vue项目于加载项控制excel单元格内容(Demo版)
  • TS在Vue3中的使用实例集合
  • 储能技术适配绿电直连场景深度对比
  • React + Ant Design 日期选择器避免显示“Invalid Date“的解决方案
  • Vue 3 多实例 + 缓存复用:理念及实践
  • 手机网站自适应布局怎么做wordpress背景图片下载
  • Java基础——面向对象进阶复习知识点3
  • wordpress资讯站模板网站建设 智能建站
  • NoSQL介绍
  • 【实时Linux实战系列】FPGA 与实时 Linux 的协同设计
  • 可以做翻译兼职的网站wordpress icp链接
  • 【系统分析师】高分论文:数据库集群技术及应用
  • 西安知名高端网站建设服务企业郑州做系统集成的公司网站
  • 基于Matlab实现双目图计算深度图
  • sysctl -w net.ipv4.ip_forward=1 是一个Linux系统命令,用于开启IP转发功能
  • 信息检索4
  • 简述建设电子商务网站步骤苏州住房与城乡建设网站
  • 437路径总和III(dfs+前缀和)