总目录



一、RenderTransform(渲染变换)

1 RenderTransform介绍

  <Border Height="100" Width="100" Background="Red" RenderTransformOrigin="0.5,0.5">
          <Border.RenderTransform>
                 <TransformGroup>
                      <ScaleTransform/>
                      <SkewTransform/>
                      <RotateTransform/>
                      <TranslateTransform/>
                 </TransformGroup>
          </Border.RenderTransform>
  </Border>

WPF提供了下表种的2D Transform 类,用于常见的转换操作

名称描述重要属性
TranslateTranform让对象的位置发生水平方向或竖直方向的直线运动X、Y
RotateTranform让对象的位置围绕中心发生旋转的运动Angle、CenterX、CenterY
ScaleTranform让对象的大小发生变化,放大对象或者缩小对象ScaleX、ScaleY、CenterX、CenterY
SkewTranform让对象的按照设置的角度倾斜AngleX、AngelY、CenterX、CenterY

WPF提供了下表中的类,用于创建复杂的转换效果

名称描述重要属性
MatrixTranform矩阵变换,包含以上所有的变换效果。Matrix
TransformGroup变换组合,可以随意组合上述的各种变换效果,让对象一次应用所有这些变换。
需要注意:应用变换的顺序,因为这会影响最终的变换结果。如:首先使用RotateTranform,然后再使用TranslateTranform,那么就是先旋转控件对象,然后再控件对象。

2 RenderTransformOrigin(中心点)

默认 RenderTransformOrigin=“0.5,0.5”,下面通过图形理解一下:
在这里插入图片描述
以Image控件的RenderTransformOrigin的属性为例: RenderTransformOrigin是一个比例尺寸,X 和Y 的值,范围均是从0到1

3 RenderTransform 和LayoutTransform

可以通过以下两种方式之一向元素应用转换:

  • 如果不希望转换影响布局,请使用该元素的 RenderTransform 属性。
  • 如果希望转换影响布局,请使用该元素的 LayoutTransform 属性。

在这里插入图片描述

二、TranslateTransform(平移)

1 TranslateTransform介绍

TranslateTransform的作用就是让对象的位置发生水平方向或竖直方向的直线运动
在这里插入图片描述
上面动图中,只是在项目未运行状态下,在【转换】这一项属性内调整属性值的效果,当我们调整TranslateTransform的X属性和Y属性的时候,会发现控件会在水平方向和竖直方向做直线运动

2 基于TranslateTransform的滑动动画

在这里插入图片描述
以上动画主要就是通过修改对象的TranslateTransform 的X属性值,来实现水平移动的动画效果。

上图侧滑栏代码如下:

<UserControl x:Class="MvvmDemo.Views.ExploreView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MvvmDemo.Views"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
    
    	<!--【1】首先在资源中定义动画-->

        <Storyboard x:Key="SlipOutStoryboard">
            <DoubleAnimation Duration="0:0:0.2" To="-100" Storyboard.TargetName="tt" Storyboard.TargetProperty="X"/>
        </Storyboard>
        <Storyboard x:Key="SlipInStoryboard">
            <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetName="tt" Storyboard.TargetProperty="X"/>
        </Storyboard>
    </UserControl.Resources>
    <UserControl.Triggers>
    
    	<!--【2】然后在触发器中定义触发动画的路由事件-->
    	
        <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="mainBorder" >
            <BeginStoryboard Storyboard="{StaticResource SlipInStoryboard}"></BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="sideBorder" >
            <BeginStoryboard Storyboard="{StaticResource SlipOutStoryboard}"></BeginStoryboard>
        </EventTrigger>
    </UserControl.Triggers>
    <Grid  Background="LightGreen">
        <StackPanel  Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Border x:Name="mainBorder" Height="200" Width="200" Background="Green"></Border>
            <Border x:Name="sideBorder" Height="100" Width="100" Background="Red" RenderTransformOrigin="0.5,0.5">
                <Border.RenderTransform>
                    <TransformGroup>
                        <TranslateTransform x:Name="tt" X="0"/>
                    </TransformGroup>
                </Border.RenderTransform>
            </Border>
        </StackPanel>
    </Grid>
</UserControl>

三 、RotateTransform(旋转)

1 RotateTransform介绍

RotateTransform的作用就是让对象的围绕中心发生旋转的运动
在这里插入图片描述

  • 当我们调整RotateTransform的Angle属性的时候,控件对象会绕控件中心旋转
  • 当我们的控件上,具有RenderTransformOrigin(中心点)的属性的时候,是无法设置RotateTransform中的CenterX和CenterY的属性值的,设置时会提示无效
  • 只有去掉控件的RenderTransformOrigin属性,才可设置RotateTransform中的CenterX和CenterY
  • 当设置 <RotateTransform x:Name="rt" Angle="0" CenterX="0" CenterY="0"/>后效果如下:

在这里插入图片描述

2 CenterX和CenterY

对于CenterX和CenterY的属性值的理解:
在这里插入图片描述
CenterX和CenterY的属性值 设置的是实际 尺寸,而非比例,注意与RenderTransformOrigin区分

3 基于RotateTransform的 加载动画

可以考虑使用一个loading的PNG图片,或者从iconfont上下载图标资源,然后使用RotateTransform实现一个简单的加载动画
在这里插入图片描述
该动画主要是通过动态改变RotateTransform 的Angle值来实现加载动画的旋转,然后辅以AccelerationRatio="0.55" DecelerationRatio="0.45" 属性值的设置,让加载动画显得更自然

加载动画代码如下:

<UserControl x:Class="MvvmDemo.Views.ExploreView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MvvmDemo.Views"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <Storyboard x:Key="StartLoadingStoryboard">
            <DoubleAnimation Duration="0:0:2" To="360" AccelerationRatio="0.55" DecelerationRatio="0.45" RepeatBehavior="Forever" Storyboard.TargetName="rt" Storyboard.TargetProperty="Angle"/>
        </Storyboard>
    </UserControl.Resources>
    <UserControl.Triggers>
        <EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
            <BeginStoryboard Storyboard="{StaticResource StartLoadingStoryboard}"></BeginStoryboard>
        </EventTrigger>
    </UserControl.Triggers>
    <Grid  Background="LightGreen">
        <StackPanel  Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Image x:Name="img" Height="50" Source="/MvvmDemo;component/Res/Images/loading.png" RenderTransformOrigin="0.5,0.5">
                <Image.RenderTransform>
                    <TransformGroup>
                        <RotateTransform x:Name="rt" Angle="0"/>
                    </TransformGroup>
                </Image.RenderTransform>
            </Image>
            <Button x:Name="btn" Height="60" Width="160" Margin="50" Content="测试"></Button>
        </StackPanel>
    </Grid>
</UserControl>

四、ScaleTransform(缩放)

1 ScaleTransform介绍

ScaleTransform的作用就是让对象的大小发生变化,放大或缩小对象
在这里插入图片描述
当我们调整ScaleTransform的ScaleX属性和ScaleY属性的时候,控件就会放大或缩小

2 基于ScaleTransform的放大缩小,翻转和展开的动画

  • 当我们同时变换ScaleTransform 的ScaleX 和ScaleY属性值的就可实现放大和缩小的变化
  • 当我们将<ScaleTransform ScaleX="1"/> 逐渐变换为 <ScaleTransform ScaleX="-1"/>的过程就是一个沿着水平X轴翻转动画
  • 当我们将<ScaleTransform ScaleX="0"/> 逐渐变换为 <ScaleTransform ScaleX="1"/> 的过程就是一个逐渐展开的动画

1 放大缩小动画

在这里插入图片描述
以上动画主要通过动画动态同时调整ScaleTransform 的ScaleX 和ScaleY属性值,实现放大缩小的效果。

放大缩小动画代码如下(示例):

<UserControl x:Class="MvvmDemo.Views.ExploreView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MvvmDemo.Views"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <Storyboard x:Key="BigStoryboard">
            <DoubleAnimation Duration="0:0:1" To="1.5" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleX"/>
            <DoubleAnimation Duration="0:0:1" To="1.5" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleY"/>
        </Storyboard>
        <Storyboard x:Key="SmallStoryboard">
            <DoubleAnimation Duration="0:0:1" To="0.5" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleX"/>
            <DoubleAnimation Duration="0:0:1" To="0.5" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleY"/>
        </Storyboard>
    </UserControl.Resources>
    <UserControl.Triggers>
        <EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
            <BeginStoryboard Storyboard="{StaticResource BigStoryboard}"></BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="img" >
            <BeginStoryboard Storyboard="{StaticResource SmallStoryboard}"></BeginStoryboard>
        </EventTrigger>
    </UserControl.Triggers>
    <Grid  Background="LightGreen">
        <StackPanel  Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Border x:Name="mainBorder" Height="200" Width="200" Background="White" CornerRadius="15">
                <Image x:Name="img" Margin="15" Source="/MvvmDemo;component/Res/Images/lg.png" RenderTransformOrigin="0.5,0.5">
                    <Image.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform x:Name="st" ScaleX="1"/>
                        </TransformGroup>
                    </Image.RenderTransform>
                </Image>
            </Border>
            <Button x:Name="btn" Height="60" Width="160" Margin="50" Content="测试"></Button>
        </StackPanel>
    </Grid>
</UserControl>

2 翻转动画

在这里插入图片描述
以上动画主要通过动画动态同时调整ScaleTransform 的ScaleX 属性值,实现翻转的效果。

翻转动画代码如下(示例):

<UserControl x:Class="MvvmDemo.Views.ExploreView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MvvmDemo.Views"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <Storyboard x:Key="XturnStoryboard">
            <DoubleAnimation Duration="0:0:2" To="-1" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleX"/>
        </Storyboard>
        <Storyboard x:Key="XturnBackStoryboard">
            <DoubleAnimation Duration="0:0:2" To="1" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleX"/>
        </Storyboard>
    </UserControl.Resources>
    <UserControl.Triggers>
        <EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
            <BeginStoryboard Storyboard="{StaticResource XturnStoryboard}"></BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="img" >
            <BeginStoryboard Storyboard="{StaticResource XturnBackStoryboard}"></BeginStoryboard>
        </EventTrigger>
    </UserControl.Triggers>
    <Grid  Background="LightGreen">
        <StackPanel  Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Border x:Name="mainBorder" Height="200" Width="200" Background="White" CornerRadius="15">
                <Image x:Name="img" Margin="15" Source="/MvvmDemo;component/Res/Images/lg.png" RenderTransformOrigin="0.5,0.5">
                    <Image.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform x:Name="st" ScaleX="1"/>
                        </TransformGroup>
                    </Image.RenderTransform>
                </Image>
            </Border>
            <Button x:Name="btn" Height="60" Width="160" Margin="50" Content="测试"></Button>
        </StackPanel>
    </Grid>
</UserControl>

3 展开动画

在这里插入图片描述
以上动画主要通过动画动态同时调整ScaleTransform 的ScaleX 属性值,将ScaleY 由0.1动态变换到1,实现展开的效果。

翻转动画代码如下(示例):

<UserControl x:Class="MvvmDemo.Views.ExploreView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MvvmDemo.Views"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <Storyboard x:Key="OpenStoryboard">
            <DoubleAnimation Duration="0:0:2" To="1" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleY"/>
        </Storyboard>
        <Storyboard x:Key="CloseStoryboard">
            <DoubleAnimation Duration="0:0:2" To="0.1" Storyboard.TargetName="st" Storyboard.TargetProperty="ScaleY"/>
        </Storyboard>
    </UserControl.Resources>
    <UserControl.Triggers>
        <EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
            <BeginStoryboard Storyboard="{StaticResource OpenStoryboard}"></BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="img" >
            <BeginStoryboard Storyboard="{StaticResource CloseStoryboard}"></BeginStoryboard>
        </EventTrigger>
    </UserControl.Triggers>
    <Grid  Background="LightGreen">
        <StackPanel  Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Border x:Name="mainBorder" Height="200" Width="200" Background="White" CornerRadius="15">
                <Image x:Name="img" Margin="15" Source="/MvvmDemo;component/Res/Images/lg.png" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Top">
                    <Image.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform x:Name="st" ScaleY="0.1"/>
                        </TransformGroup>
                    </Image.RenderTransform>
                </Image>
            </Border>
            <Button x:Name="btn" Height="60" Width="160" Margin="50" Content="测试"></Button>
        </StackPanel>
    </Grid>
</UserControl>

但是这种效果,图像都有些变形了,并不是最佳的动画效果!

4 扫描效果动画

在这里插入图片描述
优化动画,该动画与本章内容关联不大,作为展开动画的优化版了解一下;
以上动画主要通过OpacityMask与LinearGradientBrush(径向渐变) 的组合应用来实现。

翻转动画代码如下(示例):

<UserControl x:Class="MvvmDemo.Views.ExploreView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MvvmDemo.Views"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <Storyboard x:Key="ScanStoryboard" FillBehavior="Stop">
            <DoubleAnimation Duration="0:0:2"  To="1" Storyboard.TargetName="gs2" Storyboard.TargetProperty="Offset"></DoubleAnimation>
            <DoubleAnimation Duration="0:0:2"  To="1" Storyboard.TargetName="gs3" Storyboard.TargetProperty="Offset"></DoubleAnimation>
            <ThicknessAnimation Duration="0:0:2" To="0,200,0,0" Storyboard.TargetName="scan" Storyboard.TargetProperty="Margin"></ThicknessAnimation>
        </Storyboard>
    </UserControl.Resources>
    <UserControl.Triggers>
        <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="grid" >
            <BeginStoryboard Storyboard="{StaticResource ScanStoryboard}" ></BeginStoryboard>
        </EventTrigger>
    </UserControl.Triggers>
    <Grid x:Name="grid" Background="White">
        <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Grid Height="200" Width="200">
                <Grid.Background>
                    <ImageBrush ImageSource="/MvvmDemo;component/Res/Images/2.png"/>
                </Grid.Background>
                <Rectangle x:Name="scan" Height="8" Margin="0,-4,0,0" VerticalAlignment="Top" Panel.ZIndex="2" RadiusX="20" RadiusY="20">
                    <Rectangle.Fill>
                        <RadialGradientBrush Opacity="0.8">
                            <GradientStop Color="#FF7BF58C" Offset="0"/>
                            <GradientStop Color="#FF2CF53E" Offset="0.5"/>
                            <GradientStop Color="#80DEF7BA" Offset="1"/>
                        </RadialGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
                <Rectangle>
                    <Rectangle.OpacityMask>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop x:Name="gs1" Color="#ff000000" Offset="0"/>
                            <GradientStop x:Name="gs2" Color="#ff000000" Offset="0"/>
                            <GradientStop x:Name="gs3" Color="#00000000" Offset="0"/>
                        </LinearGradientBrush>
                    </Rectangle.OpacityMask>
                    <Rectangle.Fill>
                        <ImageBrush ImageSource="/MvvmDemo;component/Res/Images/lg.png"/>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
        </StackPanel>
    </Grid>
</UserControl>

这种效果,以前做人脸识别签到的项目的时候,经常会用到;比如当前画面本身为摄像头的时候画面,当检测到人脸后,需要显示人脸签到的信息,停留片刻,再回到摄像头的界面上!
实现这种效果,关键是:OpacityMask与LinearGradientBrush(径向渐变) 运用的结合

<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop x:Name="gs1" Color="#ff000000" Offset="0"/>
    <GradientStop x:Name="gs2" Color="#ff000000" Offset="0"/>
    <GradientStop x:Name="gs3" Color="#00000000" Offset="0"/>
</LinearGradientBrush>

想要使用LinearGradientBrush 做这种动画,必须有三个渐变点GradientStop ,
我们知道当每个渐变点的Offset值不一样,就会产生渐变,
然而,当其中两个渐变点的Offset值一样,表示这两个点重合,那么这两个重合渐变点与第三个渐变点,如果颜色不一样的话,就会从视觉上产生两个区域。再辅以渐变点颜色的设置,弄一个透明区域和一个不透明区域即可。
在这里插入图片描述

五、SkewTransform(倾斜)

1 SkewTransform介绍

ScaleTransform的作用就是让对象的按照设置的角度倾斜
在这里插入图片描述
当我们调整SkewTransform的AngleX属性和AngleY属性的时候,控件会根据设置的角度倾斜

六、MatrixTranform(矩阵变换)

1 MatrixTranform介绍

表示用于在二维空间中进行转换的 3x3 仿射转换矩阵。通过操作矩阵值,可以旋转、缩放、倾斜和移动(转换)对象。
在方法和属性中,转换矩阵通常指定为只有六个成员的向量:(M11, M12, M21, M22, OffsetX, OffsetY)

		<!--方式1,指定成员名赋值-->
        <Button Width="100" Height="50" Content="Button">
            <Button.RenderTransform>
                <MatrixTransform x:Name="myMatrixTransform">
                    <MatrixTransform.Matrix >
                        <Matrix M11="3" M12="2" M21="1" M22="2" OffsetX="10" OffsetY="100"/>
                    </MatrixTransform.Matrix>
                </MatrixTransform>
            </Button.RenderTransform>
        </Button>
		<!--方式2:按照指定格式给Matrix属性赋值-->
		<!--语法格式:”m11, m12, m21, m22, offsetX, offsetY“ -->
        <Button Width="100" Height="50" Content="Button">
            <Button.RenderTransform>
                <MatrixTransform x:Name="myMatrixTransform2" Matrix="3,2,1,2,10,100"/>
            </Button.RenderTransform>
        </Button>
  • 更改Matrix的 OffsetX, OffsetY的值,如同修改TranslateTransform的X和Y

2 使用MatrixTranform 实现平移,旋转,缩放,倾斜

在这里插入图片描述

七、TransformGroup(变换组)

使用 TransformGroup 将两个或更多 Transform 对象合并为一个复合 Transform。

    <Button Content="Button" Height="30" Width="100">
        <Button.RenderTransform>
            <TransformGroup>
                <RotateTransform Angle="45" />
                <ScaleTransform  ScaleX="2" ScaleY="2"/>
                <SkewTransform AngleX="10" AngleY="20"/>
                <TranslateTransform X="20"/>
            </TransformGroup>
        </Button.RenderTransform>
    </Button>

八、其他

2D 变换,即是使用 2D Transform 类旋转、缩放、移动(转换)和倾斜 FrameworkElement 对象。

下表是常见转换属性
在这里插入图片描述


结语

以上就是本文的内容,希望以上内容可以帮助到您,如文中有不对之处,还请批评指正。


参考文档:
变换概述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐