WPF学习笔记3:动画
2022-08-28 22:25:34一、动画
- 补间动画:动画本质就是在一个时间段内对象尺寸、位移、旋转角度、缩放、颜色、透明度等属性值的连续变化。也包括图形变形的属性。时间、变化的对象、变化的值
- 工业应用场景:蚂蚁线、旋转、高度变化、指针偏移、小车 起始-》结束 多长时间
- 使用要求
- 必须针对依赖属性
- 对象必须派生自DependencyObject,并且实现IAnimatable接口
- 必须存在可用的兼容动画类(支持自定义)
二、简单线性动画
1. 类型
| 类型 | |||
|---|---|---|---|
| ByteAnimation | ColorAnimation | DecimalAnimation | DoubleAnimation |
| Int16Animation | Int32Animation | Int64Animation | Point3DAnimation |
| PointAnimation | QuaternionAnimation | RectAnimation | Rotation3DAnimation |
| SingleAnimation | SizeAnimation | ThicknessAnimation | VectorAnimation |
| Vector3DAnimation |
2. 动画类的选择
根据属性类型确定
变个大小、变个位置、变个颜色、变个显示(显示与隐藏)
3. 基本使用
- 创建类对象,设置相关属性,动画的执行
- Duration、From、To
- 动画的独立控制与整合
- StoryBoard
- 控制动画的运行:开始,停止,暂停,恢复
- 动画与对象的桥梁:动画对象与页面对象的关联
- MediaElement
4. 实操
<Window x:Class="AnimationLesson.LinearAniamtionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d" FontSize="20"
Title="LinearAniamtionWindow" Height="450" Width="800">
<Window.Resources>
<SolidColorBrush Color="Orange" x:Key="scb" x:Name="scb"/>
<Storyboard x:Key="sb">
<!--对象的尺寸变化动画-->
<!--<DoubleAnimation Duration="0:0:5" From="100" To="300"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Width"/>
<DoubleAnimation Duration="0:0:3" From="50" To="350"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Height"/>-->
<!--对象的位移变化动画-->
<!--<ThicknessAnimation Duration="0:0:5"
From="100,50,0,0"
To="300,150,0,0"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Margin"/>-->
<!--第二种方式-->
<!--<DoubleAnimation Duration="0:0:5"
From="100"
To="300"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Canvas.Left"/>-->
<!--第三种方式-->
<!--<DoubleAnimation Duration="0:0:5"
From="100" To="300"
Storyboard.TargetName="border"
Storyboard.TargetProperty="(Border.RenderTransform).(RotateTransform.Angle)"/>
<DoubleAnimation Duration="0:0:5"
From="100" To="300"
Storyboard.TargetName="tt"
Storyboard.TargetProperty="X"/>-->
<!--Brush画刷 包含颜色类型SolidColorBrush ** ImageBrush-->
<ColorAnimation Duration="0:0:3"
From="Orange"
To="Green"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"/>
<ColorAnimation Duration="0:0:3"
From="Green"
To="Red"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
BeginTime="0:0:3"/>
<!--不能直接变化资源对象,会找不到对象名称-->
<!--<ColorAnimation Duration="0:0:3"
From="Orange"
To="Green"
Storyboard.TargetName="scb"
Storyboard.TargetProperty="Color"/>-->
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
<BeginStoryboard Storyboard="{StaticResource sb}">
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="100" Height="50" Background="{StaticResource scb}" Name="border"
Margin="100,50,0,0"
Canvas.Left="100" Canvas.Top="50"
Visibility="Visible" Opacity="1">
<Border.RenderTransform>
<TranslateTransform X="10" Y="5" x:Name="tt"/>
<!--<RotateTransform Angle="0"/>-->
<!--<ScaleTransform ScaleX="2" ScaleY="2"/>-->
</Border.RenderTransform>
</Border>
<Button Content="开始" VerticalAlignment="Bottom" Name="btn"/>
<!--<Button Content="开始" VerticalAlignment="Bottom" Click="Button_Click"/>-->
</Grid>
</Window>
public partial class LinearAniamtionWindow : Window
{
public LinearAniamtionWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation widthAnimation = new DoubleAnimation();
widthAnimation.Duration = new TimeSpan(0, 0, 5);
widthAnimation.From = 100;
widthAnimation.To = 300;
//this.border.BeginAnimation(WidthProperty, widthAnimation);
DoubleAnimation heightAnimation = new DoubleAnimation();
heightAnimation.Duration = new TimeSpan(0, 0, 3);
heightAnimation.From = 50;
heightAnimation.To = 350;
//this.border.BeginAnimation(HeightProperty, heightAnimation);
// 如果多个动画需要同时执行,可以将相应是对象放到一个StoryBoard
// 多条故事线 同步推进
// Storyboard
Storyboard sb = new Storyboard();
sb.Children.Add(widthAnimation);
sb.Children.Add(heightAnimation);
// 这里指定相关的动画对象,与哪个页面对象相关
//
Storyboard.SetTarget(widthAnimation, this.border);
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath("Width"));
Storyboard.SetTarget(heightAnimation,this.border);
Storyboard.SetTargetProperty(heightAnimation, new PropertyPath("Height"));
sb.Begin();
}
private void btn_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("===btn_Click===");
}
}
二、关键帧动画
1. 类型
| 类型 | |||
|---|---|---|---|
| BooleanAnimationUsingKeyFrames | ByteAnimationUsingKeyFrames | CharAnimationUsingKeyFrames | ColorAnimationUsingKeyFrames |
| DecimalAnimationUsingKeyFrames | DoubleAnimationUsingKeyFrames | Int16AnimationUsingKeyFrames | Int32AnimationUsingKeyFrames |
| Int64AnimationUsingKeyFrames | MatrixAnimationUsingKeyFrames | ObjectAnimationUsingKeyFrames | Point3DAnimationUsingKeyFrames |
| PointAnimationUsingKeyFrames | QuaternionAnimationUsingKeyFrames | RectAnimationUsingKeyFrames | Rotation3DAnimationUsingKeyFrames |
| SingleAnimationUsingKeyFrames | SizeAnimationUsingKeyFrames | StringAnimationUsingKeyFrames | ThicknessAnimationUsingKeyFrames |
| Vector3DAnimationUsingKeyFrames | VectorAnimationUsingKeyFrames |
2. 大帧类型
Linear+【类型名称】+KeyFrame 线性变化关键帧,(简单线性动画的处理基本一样)
Discrete +【类型名称】+ KeyFrame 离散变化关键帧,不连续变化
Spline +【类型名称】+ KeyFrame 样条关键帧-》样条函数(二次贝塞尔曲线-Path)
Easing +【类型名称】+ KeyFrame 缓冲式关键帧,使用简单动画时介绍的缓动效果
ObjectAnimationUsingKeyFrames 理论让任意类型参与动画,只能离散形式的动画效果
3. 实操
<Window x:Class="AnimationLesson.KeyFrameAnnimationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d" FontSize="20"
Title="KeyFrameAnnimationWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb">
<!--1、如果动画对象的Duration时长大于子帧的时长,多出来的时间无变化-->
<!--2、如果动画对象的Duration时长小于子帧的时长,以对象时间为准,超出的子帧时间不执-->
<!--3、如果不指定动画对象的Duration属性,以子帧时间全部分执行-->
<!--注意事项:关键帧的时间,没有先后顺序要求,严格按照时间轴进行执行-->
<!--<ColorAnimationUsingKeyFrames Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color">
<LinearColorKeyFrame Value="Orange" KeyTime="0:0:0"/>
<LinearColorKeyFrame Value="Green" KeyTime="0:0:2"/>
<LinearColorKeyFrame Value="Red" KeyTime="0:0:4"/>
<DiscreteColorKeyFrame Value="Blue" KeyTime="0:0:6"/>
<DiscreteColorKeyFrame Value="Gray" KeyTime="0:0:8"/>
</ColorAnimationUsingKeyFrames>-->
<!--只有离散关键帧动画-->
<!--可以通过C#代码处理-->
<StringAnimationUsingKeyFrames Storyboard.TargetName="tb"
Storyboard.TargetProperty="Text">
<DiscreteStringKeyFrame Value="" KeyTime="0:0:0"/>
<DiscreteStringKeyFrame Value="H" KeyTime="0:0:0.3"/>
<DiscreteStringKeyFrame Value="He" KeyTime="0:0:0.6"/>
<DiscreteStringKeyFrame Value="Hel" KeyTime="0:0:0.9"/>
<DiscreteStringKeyFrame Value="Hell" KeyTime="0:0:1.2"/>
<DiscreteStringKeyFrame Value="Hello" KeyTime="0:0:1.5"/>
<DiscreteStringKeyFrame Value="Hello " KeyTime="0:0:1.8"/>
<DiscreteStringKeyFrame Value="Hello Z" KeyTime="0:0:2.1"/>
</StringAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="Margin">
<SplineThicknessKeyFrame Value="0,0,0,0" KeyTime="0:0:0"/>
<SplineThicknessKeyFrame KeyTime="00:00:04" Value="780,0,0,0" KeySpline="0.1,0.9,0.9,0.1">
<!--可以简化处理, 如上行KeySpline属性-->
<!--<SplineThicknessKeyFrame.KeySpline>
<KeySpline ControlPoint1="0.1,0.9" ControlPoint2="0.9,0.1"/>
</SplineThicknessKeyFrame.KeySpline>-->
</SplineThicknessKeyFrame>
</ThicknessAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames>
<SplineDoubleKeyFrame KeySpline="0.9,0.1,1,1"/>
<LinearDoubleKeyFrame />
<SplineDoubleKeyFrame KeySpline="0.9,0.1,1,1"/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames>
<DiscretePointKeyFrame Value="100,100" KeyTime="0:0:0"/>
</PointAnimationUsingKeyFrames>
<!--安排随机坐标线性变化案例-->
</Storyboard>
<ElasticEase x:Key="be"/>
<Storyboard x:Key="ease_sb">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetName="border"
Storyboard.TargetProperty="Margin">
<LinearThicknessKeyFrame Value="0" KeyTime="0:0:0"/>
<LinearThicknessKeyFrame Value="100,0,0,0" KeyTime="0:0:2"/>
<LinearThicknessKeyFrame Value="100,0,0,0" KeyTime="0:0:3"/>
<EasingThicknessKeyFrame Value="300,0,0,0" KeyTime="0:0:5" EasingFunction="{StaticResource be}">
<!--<EasingThicknessKeyFrame.EasingFunction>
<CircleEase EasingMode="EaseInOut"/>
</EasingThicknessKeyFrame.EasingFunction>-->
</EasingThicknessKeyFrame>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="obj_sb">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<Visibility>Hidden</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:2">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
<BeginStoryboard Storyboard="{StaticResource obj_sb}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Border VerticalAlignment="Center" HorizontalAlignment="Left"
Width="100" Height="50" Background="Orange" Name="border" Visibility="Visible"/>
<TextBlock Text="Hello" VerticalAlignment="Center" HorizontalAlignment="Center"
Name="tb"/>
<Ellipse Width="20" Height="20" Fill="Red" VerticalAlignment="Top" HorizontalAlignment="Left"
Margin="0,0,0,0" Name="ellipse"/>
<Button Content="开始" VerticalAlignment="Bottom" Name="btn"/>
</Grid>
</Window>
三、路径动画
1. 分类
- DoubleAnimationUsingPath:位移(TranslateTransform、Canvas LeftTop)、旋转(RoateTransform)
- PointAnimationUsingPath:位移
- MatrixAnimationUsingPath:合体,上面两个都包含
2. 使用方法
- 根据Path数据,限定动画路径
- 类型名称+ AnimationUsingPath
- 3个对象 Double、Point(X、Y)、Matrix(不需要记矩阵)
- 路径Path
3. 实操
<Window x:Class="AnimationLesson.PathAnimationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d" FontSize="30"
Title="PathAnimationWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb">
<DoubleAnimationUsingPath Duration="0:0:4"
Storyboard.TargetName="tt"
Storyboard.TargetProperty="X"
Source="X">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0 0 60,100 A100 50 0 0 1 400 150"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath Duration="0:0:4"
Storyboard.TargetName="tt"
Storyboard.TargetProperty="Y"
Source="Y">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0 0 60,100 A100 50 0 0 1 400 150"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath Duration="0:0:4"
Storyboard.TargetName="rt"
Storyboard.TargetProperty="Angle"
Source="Angle">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0 0 60,100 A100 50 0 0 1 400 150"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<!--<DoubleAnimationUsingPath Duration="0:0:4"
Storyboard.TargetName="rt1"
Storyboard.TargetProperty="Angle"
Source="Angle">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0 0 60,100 A100 50 0 0 1 400 150"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>-->
<PointAnimationUsingPath Duration="0:0:4"
Storyboard.TargetName="eg"
Storyboard.TargetProperty="Center">
<PointAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0 0 60,100 A100 50 0 0 1 400 150"/>
</PointAnimationUsingPath.PathGeometry>
</PointAnimationUsingPath>
<MatrixAnimationUsingPath Duration="0:0:4"
Storyboard.TargetName="mt"
Storyboard.TargetProperty="Matrix"
DoesRotateWithTangent="True">
<MatrixAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0 0 60,100 A100 50 0 0 1 400 150"/>
</MatrixAnimationUsingPath.PathGeometry>
</MatrixAnimationUsingPath>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
<BeginStoryboard Storyboard="{StaticResource sb}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Path Data="M0 0 60,100 A100 50 0 0 1 400 150" Stroke="Gray" StrokeThickness="2">
</Path>
<Path Fill="Orange" Visibility="Collapsed">
<Path.Data>
<EllipseGeometry Center="0,0" RadiusX="50" RadiusY="25" x:Name="eg">
<EllipseGeometry.Transform>
<RotateTransform x:Name="rt1"/>
</EllipseGeometry.Transform>
</EllipseGeometry>
<!--以下案例处理报错-->
<!--<RectangleGeometry x:Name="rg">
<RectangleGeometry.Rect>
<Rect Location="0,0" Width="100" Height="50"/>
</RectangleGeometry.Rect>
</RectangleGeometry>-->
</Path.Data>
</Path>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="100" Height="50" Background="Orange" Name="border" Visibility="Collapsed">
<Border.RenderTransform>
<TransformGroup>
<RotateTransform Angle="0" x:Name="rt"/>
<TranslateTransform X="0" Y="0" x:Name="tt"/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="100" Height="50" Background="Green">
<Border.RenderTransform>
<MatrixTransform x:Name="mt"/>
</Border.RenderTransform>
</Border>
<Button Content="开始" VerticalAlignment="Bottom" Name="btn"/>
</Grid>
</Window>
四、辅助属性
1. 属性介绍
- SpeedRatio:播放速度
- AccelerationRatio:加速速率
- DecelerationRatio:减速速率
- AutoReverse:是否执行相反的动画
- FillBehavior:动画结束状态:HoldEnd、Stop
- RepeatBehavior:动画重复方式,包括三种值:Forever、次数、时间
前面这些属性在Animation对象中也可以设置
IsAddtive:将目标属性的当前值添加到动画的起始值
IsCumulative:如果动画不断重复,就累积动画值
BeginTime:动画线启动等待时长
EasingFunction:动画缓动属性,EasingMode
BackEase、CircleEase、CubicEase、ElasticEase、ExponentialEase、PowerEase、QuadraticEase、QuarticEase、QuinticEase、SineEase
Timeline.DesiredFrameRate:设置帧率
2. 实操
public class ViewModel : INotifyPropertyChanged
{
public Thickness Value { get; set; } = new Thickness(300, 0, 0, 0);
public event PropertyChangedEventHandler? PropertyChanged;
public ViewModel()
{
Task.Run(async () =>
{
await Task.Delay(5000);
Value = new Thickness(100, 0, 0, 0);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
});
}
}
<Window x:Class="AnimationLesson.AnimationPropertyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d"
Left="0"
Title="AnimationPropertyWindow" Height="450" Width="800" Name="win">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Window.Resources>
<Storyboard x:Key="sb">
<!--动画控制窗口位置-->
<!--<DoubleAnimation Duration="0:0:4"
Storyboard.TargetName="win"
Storyboard.TargetProperty="Left"
From="0"
To="300"/>-->
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border1"
Storyboard.TargetProperty="Margin"
From="{Binding Value}" To="400,0,0,0"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border2"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0"
SpeedRatio="2"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border3"
Storyboard.TargetProperty="Margin"
From="{Binding}" To="400,0,0,0"
AccelerationRatio="0.3"
DecelerationRatio="0.7"/>
<!--自动返回起点-->
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border4"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0"
AutoReverse="True"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border5"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0"
FillBehavior="Stop"/>
<!--RepeatBehavior三个类型的参数值:Forever永远重复、指定重复次数(2x)、指定重复执行时间-->
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border6"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0"
RepeatBehavior="0:0:5" AutoReverse="True"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border7"
Storyboard.TargetProperty="Margin"
From="0" To="200,0,0,0"
IsAdditive="True"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border8"
Storyboard.TargetProperty="Margin"
To="200,0,0,0"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border9"
Storyboard.TargetProperty="Margin"
From="0" To="200,0,0,0"
IsCumulative="True"
RepeatBehavior="3x"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border10"
Storyboard.TargetProperty="Margin"
To="200,0,0,0"
IsCumulative="True"/>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
<BeginStoryboard Storyboard="{StaticResource sb}">
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<StackPanel>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Orange" Name="border1">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Green" Name="border2">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Gray" Name="border3">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Blue" Name="border4">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Red" Name="border5">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Brown" Name="border6">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Pink" Name="border7">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Pink" Name="border8">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Aqua" Name="border9">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Aqua" Name="border10">
</Border>
</StackPanel>
<Button Content="开始" VerticalAlignment="Bottom" Name="btn"/>
</Grid>
</Window>
五、生命周期事件
1. 事件介绍
- Completed
- CurrentGlobalSpeedInvalidated:速度变化
- CurrentStateInvalidated:状态变化
- CurretnTimeInvalidated:时间线
2. 实操
<Window x:Class="AnimationLesson.AnimationProperty2Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d"
Title="AnimationProperty2Window" Height="500" Width="800">
<Window.Resources>
<Storyboard x:Key="sb" Timeline.DesiredFrameRate="60"
Completed="Storyboard_Completed"
CurrentGlobalSpeedInvalidated="Storyboard_CurrentGlobalSpeedInvalidated"
CurrentStateInvalidated="Storyboard_CurrentStateInvalidated"
CurrentTimeInvalidated="Storyboard_CurrentTimeInvalidated">
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border1"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0"/>
<!--<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border2"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0"
BeginTime="0:0:2"/>-->
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border2"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0"/>
<ThicknessAnimation Duration="0:0:4"
Storyboard.TargetName="border3"
Storyboard.TargetProperty="Margin"
From="0" To="400,0,0,0">
</ThicknessAnimation>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="btn" >
<BeginStoryboard Storyboard="{StaticResource sb}">
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt1">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:1" From="0" To="500,0,0,0" Storyboard.TargetName="bor1" Storyboard.TargetProperty="Margin"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt2">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor2" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<BounceEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt3">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor3" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<BackEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt4">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor4" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<CircleEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt5">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor5" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<CubicEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt6">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor6" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<ElasticEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt7">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor7" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<ExponentialEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt8">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor8" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<PowerEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt9">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor9" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<QuadraticEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt10">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor10" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<QuarticEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt11">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor11" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<QuinticEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="bt12">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:5" From="0" To="500,0,0,0" Storyboard.TargetName="bor12" Storyboard.TargetProperty="Margin">
<ThicknessAnimation.EasingFunction>
<SineEase/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<StackPanel>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Orange" Name="border1">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Green" Name="border2">
</Border>
<Border VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Height="30" Background="Gray" Name="border3">
</Border>
<Grid Height="0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="无" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Text="BounceEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1"/>
<TextBlock Text="BackEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="2"/>
<TextBlock Text="CircleEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="3"/>
<TextBlock Text="CubicEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="4"/>
<TextBlock Text="ElasticEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="5"/>
<TextBlock Text="ExponentialEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="6"/>
<TextBlock Text="PowerEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="7"/>
<TextBlock Text="QuadraticEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="8"/>
<TextBlock Text="QuarticEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="9"/>
<TextBlock Text="QuinticEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="10"/>
<TextBlock Text="SineEase" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="11"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Name="bor1"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="1" Name="bor2"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="2" Name="bor3"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="3" Name="bor4"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="4" Name="bor5"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="5" Name="bor6"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="6" Name="bor7"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="7" Name="bor8"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="8" Name="bor9"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="9" Name="bor10"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="10" Name="bor11"/>
<Border Width="30" Height="30" Background="Orange" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="11" Name="bor12"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Name="bt1"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="1" Name="bt2"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="2" Name="bt3"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="3" Name="bt4"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="4" Name="bt5"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="5" Name="bt6"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="6" Name="bt7"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="7" Name="bt8"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="8" Name="bt9"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="9" Name="bt10"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="10" Name="bt11"/>
<Button Width="40" Height="30" Content="开始" Grid.Column="1" VerticalAlignment="Center" Grid.Row="11" Name="bt12"/>
</Grid>
<Button Content="开始" VerticalAlignment="Bottom" Name="btn"/>
<Button Content="Button" VerticalAlignment="Bottom" Click="Button_Click"/>
</StackPanel>
</Window>
public partial class AnimationProperty2Window : Window
{
public AnimationProperty2Window()
{
InitializeComponent();
}
private void Storyboard_Completed(object sender, EventArgs e)
{
Debug.WriteLine("===========Storyboard_Completed============");
}
private void Storyboard_CurrentGlobalSpeedInvalidated(object sender, EventArgs e)
{
Debug.WriteLine("===========Storyboard_CurrentGlobalSpeedInvalidated============");
}
private void Storyboard_CurrentStateInvalidated(object sender, EventArgs e)
{
Debug.WriteLine("===========Storyboard_CurrentStateInvalidated============");
}
private void Storyboard_CurrentTimeInvalidated(object sender, EventArgs e)
{
Debug.WriteLine("===========Storyboard_CurrentTimeInvalidated============");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var v1 = this.border1.Margin;
var v2 = this.border2.Margin;
var v3 = this.border3.Margin;
this.border1.Margin = new Thickness(200, 0, 0, 0);
// 对象先进行动画变化 完成之后进行相关的属性设置,发现 ,设置不了?
}
}
六、动画控制
1. 动画控制方式
- 动画的启动:事件、触发器、视觉管理器
- 事件控制
- BeginStoryboard:开始中一个故事板
- PauseStoryboard:暂停
- ResumeStoryboard:恢复
- StopStoryboard:停止
- SeekStoryboard:跳转某一帧,某个时刻
- SetStoryboardSpeedRatio:加速、减速
- 触发器控制
- EnterActions
- ExitActions
2. 事件控制实操
<Window x:Class="AnimationLesson.AnimationControlWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d"
Title="AnimationControlWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb">
<ThicknessAnimation Duration="0:0:5"
From="0" To="600,0,0,0"
Storyboard.TargetName="bor_1"
Storyboard.TargetProperty="Margin"/>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<!--开始-->
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_1">
<BeginStoryboard Storyboard="{StaticResource sb}" Name="bsb"/>
</EventTrigger>
<!--暂停-->
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_2">
<PauseStoryboard BeginStoryboardName="bsb"/>
</EventTrigger>
<!--恢复-->
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_3">
<ResumeStoryboard BeginStoryboardName="bsb"/>
</EventTrigger>
<!--停止-->
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_4">
<StopStoryboard BeginStoryboardName="bsb"/>
</EventTrigger>
<!--跳转到某个时刻-->
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_5">
<SeekStoryboard BeginStoryboardName="bsb" Offset="0:0:3"/>
</EventTrigger>
<!--加速-->
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_6">
<SetStoryboardSpeedRatio BeginStoryboardName="bsb" SpeedRatio="3"/>
</EventTrigger>
<!--减速-->
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_7">
<SetStoryboardSpeedRatio BeginStoryboardName="bsb" SpeedRatio="0.3"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Border Background="Orange" Width="50" Height="50" Name="bor_1" HorizontalAlignment="Left"/>
<UniformGrid Rows="1" VerticalAlignment="Bottom">
<Button Content="开始" Name="btn_1"/>
<Button Content="暂停" Name="btn_2"/>
<Button Content="恢复" Name="btn_3"/>
<Button Content="停止" Name="btn_4"/>
<Button Content="跳转某一帧" Name="btn_5"/>
<Button Content="加速" Name="btn_6"/>
<Button Content="减速" Name="btn_7"/>
</UniformGrid>
</Grid>
</Window>
3. 触发器控制实操
<Window x:Class="AnimationLesson.AnimationTriggerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d"
Title="AnimationTriggerWindow" Height="450" Width="800">
<Window.Resources>
<ControlTemplate TargetType="CheckBox" x:Key="cbTemp">
<Border Background="{TemplateBinding Background}" Name="border"
Width="50" Height="50">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="border" Property="Background" Value="Orange"/>
<!--触发器条件满足的时候执行-->
<!--执行时机:这个对象的IsChecked属性为True的时候-->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:2"
From="50" To="100"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Width"/>
<DoubleAnimation Duration="0:0:2"
From="50" To="100"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Height"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!--触发器条件不满足的时候执行-->
<!--没有写From:表示动画执行的起始值从对象当前状态下的相关属性值开始变化-->
<!--没有写To:表示动画执行的目标值以对象的初始状态下的相关属性值为结束-->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:2"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Width"/>
<DoubleAnimation Duration="0:0:2"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Height"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<Grid>
<CheckBox Background="Gray" Template="{StaticResource cbTemp}"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Window>
七、视觉状态管理器
1. 视图状态相关属性介绍
- VisualState: 视图状态(Visual States)表示控件在一个特殊的逻辑状态下的样式、外观;
- VisualStateGroup: 状态组由相互排斥的状态组成,状态组与状态组并不互斥;
- VisualTransition: 视图转变 (Visual Transitions) 代表控件从一个视图状态向另一个状态转换时的过渡;
- VisualStateManager: 由它负责在代码中来切换到不同的状态;
- GoToState:针对控件模板中的视觉状态进行切换
- GoToElementState:针对某个对象中的视觉状态进行切换
2. 实操
<Window x:Class="AnimationLesson.AnimationStateWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d"
Title="AnimationStateWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb">
<ThicknessAnimation Duration="0:0:5"
From="0" To="600,0,0,0"
Storyboard.TargetName="bor_1"
Storyboard.TargetProperty="Margin"/>
</Storyboard>
</Window.Resources>
<VisualStateManager.VisualStateGroups>
<!--这里可以存放多个Group-->
<VisualStateGroup>
<VisualState Name="state_1">
<Storyboard>
<ThicknessAnimation Duration="0:0:2"
From="0" To="600,0,0,0"
Storyboard.TargetName="bor_1"
Storyboard.TargetProperty="Margin"/>
</Storyboard>
</VisualState>
<VisualState Name="state_2">
<Storyboard>
<ColorAnimation Duration="0:0:2"
To="Green"
Storyboard.TargetName="bor_1"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</VisualState>
<VisualState Name="state_3"/>
</VisualStateGroup>
<!--<VisualStateGroup>
</VisualStateGroup>-->
</VisualStateManager.VisualStateGroups>
<Grid>
<Border Background="Orange" Width="50" Height="50" Name="bor_1" HorizontalAlignment="Left"/>
<StackPanel VerticalAlignment="Bottom">
<Button Content="执行第一个状态" Click="Button_Click"/>
<Button Content="执行第二个状态" Click="Button_Click_1"/>
<Button Content="执行第三个状态" Click="Button_Click_2"/>
</StackPanel>
</Grid>
</Window>
public partial class AnimationStateWindow : Window
{
public AnimationStateWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToElementState(this, "state_1", true);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToElementState(this, "state_2", true);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToElementState(this, "state_3", true);
}
}
八、案例
1. 菜单隐藏
<Window x:Class="AnimationLesson.Example.DrawerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson.Example"
mc:Ignorable="d"
Title="DrawerWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb">
<ThicknessAnimation Duration="0:0:0.5"
To="0"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Margin"/>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_1">
<BeginStoryboard Storyboard="{StaticResource sb}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="btn_2">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.5"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Margin"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Button Width="30" Height="30" VerticalAlignment="Top" HorizontalAlignment="Left"
Name="btn_1"/>
<Border Width="180" Background="#DDD" HorizontalAlignment="Left"
Margin="-180,0,0,0" Name="border">
<Button Width="30" Height="30" VerticalAlignment="Top" HorizontalAlignment="Right"
Name="btn_2"/>
</Border>
</Grid>
</Window>
2. 进度等待
<Window x:Class="AnimationLesson.Example.LoadingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson.Example"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
Title="LoadingWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb" RepeatBehavior="Forever">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetName="ellipse_1"
Storyboard.TargetProperty="Margin">
<SplineThicknessKeyFrame Value="0,0,0,0" KeyTime="0:0:0"/>
<SplineThicknessKeyFrame KeyTime="00:00:02" Value="315,0,0,0" KeySpline="0.1,0.7,0.3,0.1"/>
</ThicknessAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetName="ellipse_2"
Storyboard.TargetProperty="Margin" BeginTime="0:0:0.3">
<SplineThicknessKeyFrame Value="0,0,0,0" KeyTime="0:0:0"/>
<SplineThicknessKeyFrame KeyTime="00:00:02" Value="315,0,0,0" KeySpline="0.1,0.7,0.3,0.1"/>
</ThicknessAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetName="ellipse_3"
Storyboard.TargetProperty="Margin" BeginTime="0:0:0.6">
<SplineThicknessKeyFrame Value="0,0,0,0" KeyTime="0:0:0"/>
<SplineThicknessKeyFrame KeyTime="00:00:02" Value="315,0,0,0" KeySpline="0.1,0.7,0.3,0.1"/>
</ThicknessAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetName="ellipse_4"
Storyboard.TargetProperty="Margin" BeginTime="0:0:0.9">
<SplineThicknessKeyFrame Value="0,0,0,0" KeyTime="0:0:0"/>
<SplineThicknessKeyFrame KeyTime="00:00:02" Value="315,0,0,0" KeySpline="0.1,0.7,0.3,0.1"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="sb_2">
<RectAnimation Duration="0:0:1"
To="20,0,20,15"
Storyboard.TargetName="vb"
Storyboard.TargetProperty="Viewport"
RepeatBehavior="Forever"/>
</Storyboard>
<SolidColorBrush x:Key="ProgressBar.Progress" Color="#FF06B025"/>
<SolidColorBrush x:Key="ProgressBar.Background" Color="#FFE6E6E6"/>
<SolidColorBrush x:Key="ProgressBar.Border" Color="#FFBCBCBC"/>
<Style x:Key="ProgressBarStyle1" TargetType="{x:Type ProgressBar}">
<Setter Property="Foreground" Value="{StaticResource ProgressBar.Progress}"/>
<Setter Property="Background" Value="{StaticResource ProgressBar.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource ProgressBar.Border}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid x:Name="TemplateRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate"/>
<VisualState x:Name="Indeterminate">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Animation" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0" Value="0.25"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.25"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0.25"/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Animation" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)">
<EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5"/>
</PointAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
<Rectangle x:Name="PART_Track"/>
<Grid x:Name="PART_Indicator" ClipToBounds="true" HorizontalAlignment="Left">
<Rectangle x:Name="Indicator" Fill="{TemplateBinding Foreground}"/>
<Rectangle x:Name="Animation" Fill="{TemplateBinding Foreground}" RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="LayoutTransform" TargetName="TemplateRoot">
<Setter.Value>
<RotateTransform Angle="-90"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsIndeterminate" Value="true">
<Setter Property="Visibility" TargetName="Indicator" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource sb_2}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid VerticalAlignment="Center" Width="300" Background="#EEE" ClipToBounds="True">
<Ellipse Width="15" Height="15" Fill="Red" HorizontalAlignment="Left"
Margin="-15,0,0,0" Name="ellipse_1"/>
<Ellipse Width="15" Height="15" Fill="Red" HorizontalAlignment="Left"
Margin="-15,0,0,0" Name="ellipse_2"/>
<Ellipse Width="15" Height="15" Fill="Red" HorizontalAlignment="Left"
Margin="-15,0,0,0" Name="ellipse_3"/>
<Ellipse Width="15" Height="15" Fill="Red" HorizontalAlignment="Left"
Margin="-15,0,0,0" Name="ellipse_4"/>
</Grid>
<ProgressBar Style="{DynamicResource ProgressBarStyle1}" Height="15" Width="200" VerticalAlignment="Top"
Value="40">
<ProgressBar.Foreground>
<VisualBrush TileMode="Tile" Viewport="0,0,20,15" ViewportUnits="Absolute" x:Name="vb">
<VisualBrush.Visual>
<Border Background="Transparent">
<Border.RenderTransform>
<SkewTransform AngleX="-40"/>
</Border.RenderTransform>
<Border Width="20" Height="15" Margin="3,0" Background="Orange"/>
</Border>
</VisualBrush.Visual>
</VisualBrush>
</ProgressBar.Foreground>
</ProgressBar>
</Grid>
</Window>
3. 机械臂控制
<Window x:Class="AnimationLesson.Example.RobotWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson.Example"
mc:Ignorable="d"
Title="RobotWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb" AutoReverse="True" RepeatBehavior="Forever">
<DoubleAnimation Duration="0:0:2"
To="200"
Storyboard.TargetName="tt"
Storyboard.TargetProperty="X"/>
<DoubleAnimation Duration="0:0:3"
From="-40"
To="20"
Storyboard.TargetName="rt1"
Storyboard.TargetProperty="Angle"/>
<DoubleAnimation Duration="0:0:2"
From="30"
To="70"
Storyboard.TargetName="rt2"
Storyboard.TargetProperty="Angle"/>
</Storyboard>
<TranslateTransform x:Key="tt" X="50"/>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource sb}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Border Width="50" Height="50" Background="Orange" CornerRadius="10">
<Border.RenderTransform>
<TranslateTransform X="0" x:Name="tt"/>
</Border.RenderTransform>
<Canvas>
<Border Height="20" Width="120" Background="Green" Canvas.Left="13" Canvas.Top="-10"
CornerRadius="10">
<Border.RenderTransform>
<RotateTransform Angle="-40" x:Name="rt1" CenterX="10" CenterY="10"/>
</Border.RenderTransform>
<Canvas HorizontalAlignment="Right">
<Border Height="13" Width="100" Background="Red" Canvas.Left="-15" Canvas.Top="3"
CornerRadius="7">
<Border.RenderTransform>
<RotateTransform Angle="50" x:Name="rt2" CenterX="7.5" CenterY="7.5"/>
</Border.RenderTransform>
</Border>
</Canvas>
</Border>
</Canvas>
</Border>
<Border Width="50" Height="50" Background="Gray" VerticalAlignment="Bottom"
RenderTransform="{StaticResource tt}">
</Border>
<Border Width="30" Height="100" Background="Orange" VerticalAlignment="Bottom">
<Border.RenderTransform>
<TransformGroup>
<TranslateTransform/>
<RotateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border Width="130" Height="20" Background="Green" VerticalAlignment="Bottom"
RenderTransform="{StaticResource tt}">
</Border>
</Grid>
</Window>
4. 蚂蚁线
<Window x:Class="AnimationLesson.Example.AntLineWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson.Example"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
Title="AntLineWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb" RepeatBehavior="Forever">
<DoubleAnimation Duration="0:0:1"
To="-6"
Storyboard.TargetName="path"
Storyboard.TargetProperty="StrokeDashOffset"/>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource sb}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Path Data="M0,0 100 100A50 50 0 0 0 200 150" Stroke="Orange" StrokeThickness="5"
StrokeDashArray="3,3" StrokeDashOffset="0" Name="path"/>
</Grid>
</Window>
5. 液面
<Window x:Class="AnimationLesson.Example.WaterWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationLesson"
mc:Ignorable="d"
Title="WaterWindow" Height="450" Width="800">
<Window.Resources>
<Storyboard x:Key="sb">
<DoubleAnimation Duration="0:0:1"
To="-100"
Storyboard.TargetName="tt"
Storyboard.TargetProperty="X" RepeatBehavior="Forever"/>
<DoubleAnimation Duration="0:0:1.6"
To="-100"
Storyboard.TargetName="tt1"
Storyboard.TargetProperty="X"
BeginTime="0:0:0.2" RepeatBehavior="Forever"/>
<DoubleAnimation Duration="0:0:1.2"
To="0"
Storyboard.TargetName="tt2"
Storyboard.TargetProperty="X"
BeginTime="0:0:0.4" RepeatBehavior="Forever"/>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource sb}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Border Width="100" Height="100" Background="#DDD" CornerRadius="50">
<Border.Clip>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50"/>
</Border.Clip>
<Canvas ClipToBounds="True">
<Path Data="
M0 0
A40 40 0 0 0 50 0
A40 40 0 0 1 100 0
A40 40 0 0 0 150 0
A40 40 0 0 1 200 0
L200 100 0 100" Fill="#9F90">
<Path.RenderTransform>
<TranslateTransform X="0" Y="40" x:Name="tt1"/>
</Path.RenderTransform>
</Path>
<Path Data="
M0 0
A50 50 0 0 0 50 0
A50 50 0 0 1 100 0
A50 50 0 0 0 150 0
A50 50 0 0 1 200 0
L200 100 0 100" Fill="Orange">
<Path.RenderTransform>
<TranslateTransform X="0" Y="40" x:Name="tt"/>
</Path.RenderTransform>
</Path>
<Path Data="
M0 0
A50 50 0 0 0 50 0
A50 50 0 0 1 100 0
A50 50 0 0 0 150 0
A50 50 0 0 1 200 0
L200 100 0 100" Fill="Green" Opacity="0.2">
<Path.RenderTransform>
<TranslateTransform X="-100" Y="40" x:Name="tt2"/>
</Path.RenderTransform>
</Path>
</Canvas>
</Border>
</Grid>
</Window>
