WPF中的动画——(一)基本概念

WPF中的动画——(二)From/To/By 动画

WPF中的动画——(三)时间线(TimeLine)

WPF中的动画——(四)缓动函数

WPF中的动画——(五)关键帧动画

 

 线性插值动画类 适合单个动画,若要在两个以上的目标值之间使用其他内插方法或者进行动画处理,请使用 DoubleAnimationUsingKeyFrames 对象。

 

本文将介绍WPF 中三种基本动画,线性插值、关键帧和路径动画。

  在 System.Windows.Media.Animation 这个命名空间中,包含了三种动画类:线性插值动画类(17个,简单单个动画)、关键帧动画(22个,几个动画组合起来的复杂动画)、路径动画(3个)。

  在C#代码中使用Animation类,需要引入命名空间:System.Windows.Media.Animation

  using System.Windows.Media.Animation;

1、线性插值动画

  该动画表现为,元素的某个属性,在开始值和结束值之间逐步增加,是一种线性插值的过程。比如,实现一个按钮的淡入效果,让它的透明度Opacity在0~1之间线性增长,就可以实现预期效果。 

  以下是 System.Windows.Media.Animation 命名空间中,17个线性插值动画类。  

ByteAnimation

ColorAnimation

DecimalAnimation

DoubleAnimation

Int16Animation

Int32Animation

Int64Animation

Point3DAnimation

PointAnimation

QuaternionAnimation

RectAnimation

Rotation3DAnimation

SingleAnimation

SizeAnimation

ThicknessAnimation

Vector3DAnimation

VectorAnimation

示例1:以 DoubleAnimation 为例,实现文字的淡入效果。

  在XAML中可以直接定义动画,以下示例是以后台代码形式实现的动画。

  XAML

<TextBlock Height="50" Width="220" Foreground="#326939" FontSize="36" Name="textBlock1" Text="文字淡入效果"/>

  CS  

DoubleAnimation da = new DoubleAnimation();
da.From = 0;    //起始值
da.To = 1;      //结束值
da.Duration = TimeSpan.FromSeconds(3);         //动画持续时间
this.textBlock1.BeginAnimation(TextBlock.OpacityProperty, da);//开始动画

动画基础,3种动画方式
    


            
WPF编程学习——动画

 

 

<StackPanel>
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation
          Storyboard.TargetName="MyAnimatedRectangle"
          Storyboard.TargetProperty="Opacity"
          From="1.0" To="0.0" Duration="0:0:5" 
          AutoReverse="True" RepeatBehavior="Forever" />
        </Storyboard>
    </StackPanel.Resources>

    <Rectangle Loaded="Start_Animation" x:Name="MyAnimatedRectangle"
     Width="100" Height="100" Fill="Blue" />

</StackPanel>

 

  

示例2:利用 ThicknessAnimation ,实现元素平移效果。

  XMAL

<TextBlock Height="50" Foreground="#326939" Margin="0,100,0,0" FontSize="36" Name="textBlock1" Text="文字平移"/>

  CS

//文字平移,Margin属性是Thickness类型,选择ThicknessAnimation
ThicknessAnimation ta = new ThicknessAnimation();
ta.From = new Thickness(0, 100, 0, 0);             //起始值
ta.To = new Thickness(240, 100, 0, 0);        //结束值
ta.Duration = TimeSpan.FromSeconds(3);         //动画持续时间
this.textBlock1.BeginAnimation(TextBlock.MarginProperty, ta);//开始动画

动画基础,3种动画方式
    


            
WPF编程学习——动画动画基础,3种动画方式
    


            
WPF编程学习——动画

2、关键帧动画

  关键帧动画是以时间为节点,在指定时间节点上,属性达到某个值。

  以下是 System.Windows.Media.Animation 命名空间中,22个关键帧动画类。  

BooleanAnimationUsingKeyFrames

ByteAnimationUsingKeyFrames

CharAnimationUsingKeyFrames

ColorAnimationUsingKeyFrames

DecimalAnimationUsingKeyFrames

DoubleAnimationUsingKeyFrames

Int16AnimationUsingKeyFrames

Int32AnimationUsingKeyFrames

Int64AnimationUsingKeyFrames

MatrixAnimationUsingKeyFrames

ObjectAnimationUsingKeyFrames

Point3DAnimationUsingKeyFrames

PointAnimationUsingKeyFrames

QuaternionAnimationUsingKeyFrames

RectAnimationUsingKeyFrames

Rotation3DAnimationUsingKeyFrames

SingleAnimationUsingKeyFrames

SizeAnimationUsingKeyFrames

StringAnimationUsingKeyFrames

ThicknessAnimationUsingKeyFrames

Vector3DAnimationUsingKeyFrames

VectorAnimationUsingKeyFrames

示例3:Border宽度的关键帧动画

XAML

<Border Height="32" Width="0" Background="#326939"  Name="border1"/>

CS

动画基础,3种动画方式
    


            
WPF编程学习——动画
//Border长度关键帧动画
DoubleAnimationUsingKeyFrames dak = new DoubleAnimationUsingKeyFrames();
//关键帧定义
dak.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
dak.KeyFrames.Add(new LinearDoubleKeyFrame(240, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(3))));
dak.KeyFrames.Add(new LinearDoubleKeyFrame(240, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(6))));
dak.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(9))));
            
dak.BeginTime = TimeSpan.FromSeconds(2);//从第2秒开始动画
dak.RepeatBehavior = new RepeatBehavior(3);//动画重复3次
//开始动画
this.border1.BeginAnimation(Border.WidthProperty, dak);
动画基础,3种动画方式
    


            
WPF编程学习——动画

  (程序运行时开始计时,第0秒)

  0~5:动画尚未开始;

  5~8:border1宽度从0增加到240;

  8~11:border1宽度保持240不变;

  11~14:border1宽度从240减少到0;

  14-17:又从0增加到240……(即5~14的过程循环3次)

动画基础,3种动画方式
    


            
WPF编程学习——动画动画基础,3种动画方式
    


            
WPF编程学习——动画

3、路径动画

  基于路径的动画,比起前两种更加专业一些。它的表现方式是,修改数值使其符合PathGeometry对象描述的形状,并且让元素沿着路径移动。以下是 System.Windows.Media.Animation 命名空间中,3个路径动画类。

DoubleAnimationUsingPath

MatrixAnimationUsingPath

PointAnimationUsingPath

示例4:基于路径动画的演示

XMAL(该动画是在XAML中定义,使用事件触发器,窗体加载时开始动画)

动画基础,3种动画方式
    


            
WPF编程学习——动画
<Window x:Class="WpfApplication9.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="360" Width="480">
    <Window.Resources>
        <!--路径资源-->
        <PathGeometry x:Key="path">
            <PathFigure IsClosed="True">
                <ArcSegment Point="200,200" Size="30,10" SweepDirection="Clockwise"></ArcSegment>
                <ArcSegment Point="300,200" Size="5,5"></ArcSegment>
            </PathFigure>
        </PathGeometry>
    </Window.Resources>
    <!---事件触发器,窗体加载时动画开始,周期6秒,无限循环-->
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimationUsingPath Storyboard.TargetName="image" Storyboard.TargetProperty="(Canvas.Left)"
                     PathGeometry="{StaticResource path}" Duration="0:0:6" RepeatBehavior="Forever" Source="X"></DoubleAnimationUsingPath>
                    <DoubleAnimationUsingPath Storyboard.TargetName="image" Storyboard.TargetProperty="(Canvas.Top)"
                     PathGeometry="{StaticResource path}" Duration="0:0:6" RepeatBehavior="Forever" Source="Y"></DoubleAnimationUsingPath>
                </Storyboard>                
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Canvas>
        <!--显示路径-->
        <Path Margin="30" Stroke="#ddd" Data="{StaticResource path}"></Path>
        <!--动画元素-->
        <Image Name="image" Source="me.png" Width="48" Height="48" />
    </Canvas>
</Window>
动画基础,3种动画方式
    


            
WPF编程学习——动画

  我的头像将沿着曲线路径进行移动,由于RepeatBehavior属性设置为Forever,则动画将无限循环。

动画基础,3种动画方式
    


            
WPF编程学习——动画

 

 Storyboard animationTab = new Storyboard();
               DoubleAnimationUsingKeyFrames da1 = new DoubleAnimationUsingKeyFrames();
               Storyboard.SetTarget(da1, gridA);
               Storyboard.SetTargetProperty(da1, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));
               EasingDoubleKeyFrame edk1_1 = new EasingDoubleKeyFrame();
               edk1_1.KeyTime = TimeSpan.FromSeconds(0.5);
               edk1_1.Value = zoomNum;
               da1.KeyFrames.Add(edk1_1);
               EasingDoubleKeyFrame edk1_2 = new EasingDoubleKeyFrame();
               edk1_2.KeyTime = TimeSpan.FromSeconds(1);
               edk1_2.Value = narrowNum;
               // edk1_2.EasingFunction = new QuinticEase() { EasingMode = EasingMode.EaseOut };
               da1.KeyFrames.Add(edk1_2);

               animationTab.Children.Add(da1);

               DoubleAnimationUsingKeyFrames da2 = new DoubleAnimationUsingKeyFrames();
               Storyboard.SetTarget(da2, gridA);
               Storyboard.SetTargetProperty(da2, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));
               EasingDoubleKeyFrame edk2_1 = new EasingDoubleKeyFrame();
               edk2_1.KeyTime = TimeSpan.FromSeconds(0.5);
               edk2_1.Value = zoomNum;
               da2.KeyFrames.Add(edk2_1);
               EasingDoubleKeyFrame edk2_2 = new EasingDoubleKeyFrame();
               edk2_2.KeyTime = TimeSpan.FromSeconds(1);
               edk2_2.Value = narrowNum;
               //edk2_2.EasingFunction = new QuinticEase() { EasingMode = EasingMode.EaseOut };
               da2.KeyFrames.Add(edk2_2);
               animationTab.Children.Add(da2);

               DoubleAnimationUsingKeyFrames da3 = new DoubleAnimationUsingKeyFrames();
               Storyboard.SetTarget(da3, gridA);
               Storyboard.SetTargetProperty(da3, new PropertyPath("(Canvas.Left)"));
               EasingDoubleKeyFrame edk3_1 = new EasingDoubleKeyFrame();
               edk3_1.KeyTime = TimeSpan.FromSeconds(0.5);
               edk3_1.Value = (double)gridA.GetValue(Canvas.LeftProperty);
               da3.KeyFrames.Add(edk3_1);
               EasingDoubleKeyFrame edk3_2 = new EasingDoubleKeyFrame();
               edk3_2.KeyTime = TimeSpan.FromSeconds(1.5);
               edk3_2.Value = ttfX;
               da3.KeyFrames.Add(edk3_2);
               animationTab.Children.Add(da3);

               DoubleAnimationUsingKeyFrames da4 = new DoubleAnimationUsingKeyFrames();
               Storyboard.SetTarget(da4, gridA);
               Storyboard.SetTargetProperty(da4, new PropertyPath("(Canvas.Top)"));
               EasingDoubleKeyFrame edk4_1 = new EasingDoubleKeyFrame();
               edk4_1.KeyTime = TimeSpan.FromSeconds(0.5);
               edk4_1.Value = (double)gridA.GetValue(Canvas.TopProperty);
               da4.KeyFrames.Add(edk4_1);
               EasingDoubleKeyFrame edk4_2 = new EasingDoubleKeyFrame();
               edk4_2.KeyTime = TimeSpan.FromSeconds(1.5);
               edk4_2.Value = ttfY;
               da4.KeyFrames.Add(edk4_2);
               animationTab.Children.Add(da4);

               DoubleAnimationUsingKeyFrames da5 = new DoubleAnimationUsingKeyFrames();
               Storyboard.SetTarget(da5, gridA);
               Storyboard.SetTargetProperty(da5, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"));
               EasingDoubleKeyFrame edk5_1 = new EasingDoubleKeyFrame();
               edk5_1.KeyTime = TimeSpan.FromSeconds(0.5);
               edk5_1.Value = 0;
               da5.KeyFrames.Add(edk5_1);
               EasingDoubleKeyFrame edk5_2 = new EasingDoubleKeyFrame();
               edk5_2.KeyTime = TimeSpan.FromSeconds(1.5);
               edk5_2.Value = 180;
               da5.KeyFrames.Add(edk5_2);
               animationTab.Children.Add(da5);

               PointAnimationUsingKeyFrames da6 = new PointAnimationUsingKeyFrames();
               Storyboard.SetTarget(da6, gridA);
               Storyboard.SetTargetProperty(da6, new PropertyPath("(UIElement.RenderTransformOrigin)"));
               EasingPointKeyFrame edk6_1 = new EasingPointKeyFrame();
               edk6_1.KeyTime = TimeSpan.FromSeconds(0.5);
               edk6_1.Value = new Point(0.5, 0.5);
               da6.KeyFrames.Add(edk6_1);
               EasingPointKeyFrame edk6_2 = new EasingPointKeyFrame();
               edk6_2.KeyTime = TimeSpan.FromSeconds(1);
               edk6_2.Value = new Point(0, 0);
               da6.KeyFrames.Add(edk6_2);
               animationTab.Children.Add(da6);

               animationTab.Completed += (o, e) =>
               {
                   animationTab.Stop();
                   gridA.Visibility = Visibility.Collapsed;
                  mWindow.canvasSB.Children.Remove(gridA);
                   if (aEnum != AnimationFlyEnum.None)
                       buttonAnimationAddOne(aEnum, horSet);
                   if (ac != null)
                       ac.Invoke();
               };
               animationTab.Begin();

 

相关文章:

  • 2022-12-23
  • 2022-02-19
  • 2021-05-30
  • 2021-05-18
  • 2021-07-07
  • 2021-08-09
  • 2021-12-26
猜你喜欢
  • 2021-07-14
  • 2021-12-12
  • 2022-12-23
  • 2021-04-25
  • 2021-07-12
  • 2021-06-25
  • 2022-12-23
相关资源
相似解决方案