WPF—动画详解

WPF动画

介绍:

Windows Presentation Foundation (WPF) 提供了一组强大的图形和布局功能,使用户能够创建引起注意的用户界面和有吸引力的文档。 动画不仅可以使引起注意的用户界面更加引人注目,还可以使其更加便于使用。 只需对背景色进行动画处理或应用经过动画处理的 Transform,即可创造出生动的屏幕过渡效果或提供有帮助的视觉提示。

WPF提供了强大的动画功能,让我们开发者可以用其创建出比较酷炫的界面。

小提示: (如果想让两个动画一起执行则需要将两个动画写在一块并且设置时间对应,分开执行的话则需要先执行第一个动画后再调用第二段动画)

动画学习网站 : https://blog.csdn.net/qq_39847278/article/details/129721822


目录

WPF动画

WPF动画

动画的分类

插值(基本)动画 < 类型>Animation

实例:

From、by和To

关键帧动画 < 类型>AnimationUsingKeyFrames

实例:

Value和KeyTime :

路径动画 < 类型>AnimationUsingPath

动画基类 <类型>AnimationBase 

动画类型

Double类型 实例:

Object类型 对象关键帧实例:

Color类型 关键帧实例:

String类型 字符串关键帧实例:

定义动画的两种方式

第一种方式:在控件内部定义动画

第二种方式:在资源中定义动画,在窗体的Triggers中定义触发器

设置动画的属性

变换动画(平移,旋转,缩放)

一、平移动画Translate(平移交换)

标签写法

CS写法1

CS写法2

二、旋转动画Rotate(旋转)

标签写法

CS写法

三、缩放动画scale(缩放变换)

标签写法

CS写法

实例 旋转缩放和平移变换一起实现

CS后台动画操作代码(完整版) / 基本动画FromTo/by动画


WPF动画

动画的分类

< 类型>Animation

插值(基本)动画

< 类型>AnimationUsingKeyFrames

关键帧动画

< 类型>AnimationUsingPath

路径动画

<类型>AnimationBase ,是from/to和关键帧动画的基类,实现自定义动画可以实现该类

动画基类

插值(基本)动画 < 类型>Animation

AnimationTimeline 类型,可在起始值和终止值之间创建转换。 完成转换所需的时间取决于该动画的 Duration。 From/To/By 动画的目标值不能超过两个。 如果需要具有两个以上目标值的动画,请使用关键帧。

实例:
<Rectangle Name="MyRectangle"
           Width="100"
           Height="100"
           Fill="Blue"
           Margin="10">
    <Rectangle.Triggers>
        <EventTrigger RoutedEvent="MouseLeftButtonDown"
                      SourceName="MyRectangle">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="MyRectangle"
                                     Storyboard.TargetProperty="Width"
                                     From="100"
                                     To="220"
                                     Duration="0:0:2"
                                     AutoReverse="True"
                                     RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>
</Rectangle >
From、by和To

假如原始值或From属性值设置为100,By属性值设置为200,那么相当隐式设置了To为300,那么动画就是100-300之间的动态变化。

关键帧动画 < 类型>AnimationUsingKeyFrames

介绍: From/To/By 动画可以在两个值之间创建过渡,而单个关键帧动画可以在任意数量的目标值之间创建过渡。 关键帧动画的目标值使用关键帧对象进行描述,因此称作“关键帧动画”。

实例:
<Rectangle Name="rect"
           Width="70"
           Height="100"
           HorizontalAlignment="Left"
           Opacity="1"
           Fill="Blue">
    <Rectangle.Triggers>
        <!--标签加载的时候触发动画-->
        <EventTrigger RoutedEvent="Rectangle.Loaded">
            <!--开始添加动画版 把动画添加到动画版上进行管理动画-->
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimationUsingKeyFrames AutoReverse="True"
                                                   RepeatBehavior="0:0:9"
                                                   Storyboard.TargetName="rect"
                                                   Storyboard.TargetProperty="Width"
                                                   >
                        <!--其中一帧的状态 keytime 对应的时间,value做动画属性值-->
                        <EasingDoubleKeyFrame KeyTime="0:0:0"
                                              Value="0">
                        </EasingDoubleKeyFrame>
                        <EasingDoubleKeyFrame KeyTime="0:0:3"
                                              Value="400">
                        </EasingDoubleKeyFrame>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>
</Rectangle>
Value和KeyTime :

Value 属性指定关键帧的目标值。

KeyTime 属性指定何时(在动画的 Duration 内)到达关键帧的 Value。

路径动画 < 类型>AnimationUsingPath

介绍: 路

径动画可用于沿着复杂路径移动和旋转对象。 路径动画是一种使用 PathGeometry 作为输入的 AnimationTimeline。

动画基类 <类型>AnimationBase 

是from/to和关键帧动画的基类,实现自定义动画可以实现该类


动画类型

objectanimationusingkeyframes Object类型的关键帧动画 (用于给对象类型赋值)

Double类型 实例:

<Rectangle Name="MyRectangle"
           Width="100"
           Height="100"
           Fill="Blue"
           Margin="10">
    <Rectangle.Triggers>
        <EventTrigger RoutedEvent="MouseLeftButtonDown"
                      SourceName="MyRectangle">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="MyRectangle"
                                     Storyboard.TargetProperty="Width"
                                     From="100"
                                     To="220"
                                     Duration="0:0:2"
                                     AutoReverse="True"
                                     RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>
</Rectangle>

Object类型 对象关键帧实例:

<Button Width="100" Height="100" Name="btn">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.MouseLeave">
            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="btn"
                                                   Storyboard.TargetProperty="(UIElement.Visibility)">
                        <DiscreteObjectKeyFrame KeyTime="0" 
                                                Value="{x:Static Visibility.Hidden}"></DiscreteObjectKeyFrame>
                        <DiscreteObjectKeyFrame KeyTime="0:0:3"
                                                Value="{x:Static Visibility.Visible}"></DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

Color类型 关键帧实例:

<Button Name="btn" Width="200" Height="200">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimationUsingKeyFrames AutoReverse="True"
                                                  RepeatBehavior="Forever"
                                                  Storyboard.TargetName="btn"
                                                  Storyboard.TargetProperty="Background.(SolidColorBrush.Color)">
                        <LinearColorKeyFrame KeyTime="0:0:1" Value="Red"></LinearColorKeyFrame>
                        <LinearColorKeyFrame KeyTime="0:0:2"
                                             Value="Blue"></LinearColorKeyFrame>
                        <LinearColorKeyFrame KeyTime="0:0:3"
                                             Value="Pink"></LinearColorKeyFrame>
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

String类型 字符串关键帧实例:

<!--字符串关键帧动画-->
<Button Width="100"
        Height="100"
        Name="btn">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <StringAnimationUsingKeyFrames FillBehavior="HoldEnd"
                                                   Storyboard.TargetName="btn"
                                                   Storyboard.TargetProperty="(Button.Content)">
                        <!--离散型关键帧-->
                        <DiscreteStringKeyFrame KeyTime="0:0:0"
                                                Value="5s"></DiscreteStringKeyFrame>
                        <DiscreteStringKeyFrame KeyTime="0:0:1"
                                                Value="4s"></DiscreteStringKeyFrame>
                        <DiscreteStringKeyFrame KeyTime="0:0:2"
                                                Value="3s"></DiscreteStringKeyFrame>
                    </StringAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>


定义动画的两种方式

第一种方式:在控件内部定义动画

 <Rectangle Name="MyRectangle" Width="100" Height="100" Fill="Blue" Margin="10">
            <Rectangle.Triggers>
                <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="MyRectangle">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation
                                    Storyboard.TargetName="MyRectangle" 
                                    Storyboard.TargetProperty="Width"
                                    From="100" To="220" Duration="0:0:2" 
                                    AutoReverse="True" RepeatBehavior="Forever" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Rectangle.Triggers>
</Rectangle>

第二种方式:在资源中定义动画,在窗体的Triggers中定义触发器

     <Window.Resources>
        <!--1 首先在Window.Resources定义动画和演示图版-->
        <Storyboard x:Key="myAnimation">
            <DoubleAnimation Storyboard.TargetName="rect" 
                             Storyboard.TargetProperty="Width" 
                             By="200" Duration="0:0:2"
                             AutoReverse="True" RepeatBehavior="Forever"/>
        </Storyboard>
    </Window.Resources>
    
    <Window.Triggers>
        <!--2 再者在Window.Triggers定义触发器以及关联触发器与演示图版-->
        <EventTrigger RoutedEvent="MouseLeftButtonDown" SourceName="rect">
            <BeginStoryboard Storyboard="{StaticResource myAnimation}"/>
        </EventTrigger>
    </Window.Triggers>

    <StackPanel>
        <Rectangle Name="rect" Width="100" Height="100" Fill="Green" Margin="10"/>
    </StackPanel>


设置动画的属性

<!--AutoReverse="True"   动画是否支持相反方向的动画

RepeatBehavior="0:0:9"   重复的行为:Forever永远

Storyboard.TargetName="rect"   确定动画元素

Storyboard.TargetProperty="Width"   做动画的属性-->

Duration="0:0:2"   设置此时间线播放的时间长度,而不是计数重复。(一般用于基本动画)

FillBehavior="Stop"   动画停止的时候保持的状态 stop:停止时候恢复到初始状态 holEnd:停止时候保持动画结束状态

AccelerationRatio=“1”   获取或设置一个值,该值指定将时间从零加速到最大速率所花费的时间线的持续时间的百分比。

DecelerationRatio="1"   动画过程中减速的比例0-1

Completed   动画完成的事件可以在回调函数设置第二个动画


变换动画(平移,旋转,缩放)

介绍: 动画常用的效果是变换效果:Translate(平移交换)、Rotate(旋转)、scale(缩放变换), 比直接修改元素大小或者位置方法要快 变换的方式分为两种: RenderTransform :渲染变换,不影响页面布局,一般使用动画效果 LayoutTransform :布局变换,导致窗体布局重新绘算,这种性能比较低,一般用于变形上面不做动画 变换动画

详细介绍网站: https://www.cnblogs.com/Peter-Luo/p/12399126.html

一、平移动画Translate(平移交换)

标签写法
<Button Width="100"
        Height="100"
        VerticalAlignment="Top"
        HorizontalAlignment="Left"
        Name="b1">
// 设置平移交换
    <Button.RenderTransform>
        <TranslateTransform x:Name="t1"
                            X="0"
                            Y="0" />
    </Button.RenderTransform>

    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                  //使用TargetName调用平移交换的name属性
                    <DoubleAnimation Storyboard.TargetName="t1"
                                     Storyboard.TargetProperty="X"
                                     From="0"
                                     To="680"
                                     Completed="DoubleAnimation_Completed"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>
CS写法1
// 第一步先设置标签布局
<Button Width="100"
        Height="100"
        VerticalAlignment="Top"
        HorizontalAlignment="Left"
        Name="b1">
    <Button.RenderTransform>
        <TranslateTransform x:Name="t1"
                            X="0"
                            Y="0" />
    </Button.RenderTransform>

    <Button.Triggers>

        <EventTrigger RoutedEvent="Button.Click">
            // 使用Storyboard="{StaticResource sto}" 调用资源中的动画

            <BeginStoryboard Storyboard="{StaticResource sto}">
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

// 第二步设置在资源中定义动画
<Window.Resources>
    // 资源1
    <Storyboard x:Key="sto">
        <DoubleAnimation Storyboard.TargetName="t1"
                         Storyboard.TargetProperty="X"
                         From="0"
                         To="680"
                         // 使用Completed事件在cs中调用资源2
                         Completed="DoubleAnimation_Completed" />
    </Storyboard>
    // 资源2
<Storyboard x:Key="sto2">
    <DoubleAnimation Storyboard.TargetName="t1"
                     Storyboard.TargetProperty="Y"
                     To="300"
                     ></DoubleAnimation>
</Storyboard>
</Window.Resources>

// 第三步在Cs中调用资源2动画
private void DoubleAnimation_Completed(object sender, EventArgs e)
{
    Storyboard sb = (Storyboard)this.FindResource("sto2");
    sb.Begin(b1); // 将资源2动画在b1标签执行
}
CS写法2
// 第一步设置标签布局
<Button Width="100" Height="40" Click="Button_Click" HorizontalAlignment="Left" VerticalAlignment="Top" >
    <Button.RenderTransform>
        <TranslateTransform x:Name="bu"></TranslateTransform>
    </Button.RenderTransform>
</Button>

// 第二步在CS中设置动画
private void Button_Click(object sender, RoutedEventArgs e)
{
    //创建平移对象 参数1: from 初始值   参数2: to最终值    参数3: 执行时间
    DoubleAnimation animation = new DoubleAnimation(0.0, 686.0, new Duration(new TimeSpan(0, 0, 0, 2, 0))); 
    by.AutoReverse = true;//反向运动
    by.RepeatBehavior = RepeatBehavior.Forever;//无限循环
    animation.Completed += ONe; // 通过Competed事件调用第二段动画方法
    bu.BeginAnimation(TranslateTransform.XProperty, animation); // 执行动画
    animation.FillBehavior = FillBehavior.HoldEnd;
}
// 第二段动画
private void ONe(object sender, EventArgs e)
{
    DoubleAnimation m = new DoubleAnimation(0.0, 350, new Duration(new TimeSpan(0, 0, 0, 2, 0)));
    bu.BeginAnimation(TranslateTransform.YProperty, m);
    m.FillBehavior = FillBehavior.HoldEnd;
}

二、旋转动画Rotate(旋转)

标签写法
// RenderTransformOrigin属性 设置旋转的中心点
<Button Width="200" Height="50" RenderTransformOrigin="0.5,0.5">
    <Button.RenderTransform>
        <!--开始的旋转效果-->
        <RotateTransform Angle="0"
                         x:Name="b" />
    </Button.RenderTransform>

    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="b"
                                     Storyboard.TargetProperty="Angle"
                                     From="0"
                                     By="360"
                                     Duration="0:0:2"></DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>
CS写法
// 标签布局
<Button Width="100"
        Height="40"
        Name="b"
        Click="Button_Click111">
</Button>

// Cs按钮点击事件中创建旋转对象和动画处理对象
private void Button_Click111(object sender, RoutedEventArgs e)
{
    RotateTransform roate1 = new RotateTransform();//创建旋转对象
    b.RenderTransform = roate1;//将旋转对象赋值给bord3控件的位置
    b.RenderTransformOrigin = new Point(0.5, 0.5);//旋转的位置为中心点旋转
    DoubleAnimation double1 = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromMinutes(0.3)));//创建处理动画对象并赋值
    double1.RepeatBehavior = RepeatBehavior.Forever;//重复旋转的这个行为
    roate1.BeginAnimation(RotateTransform.AngleProperty, double1); // 开启动画
}

三、缩放动画scale(缩放变换)

标签写法
<Button Width="200" Height="50" RenderTransformOrigin="0.5,0.5">
<!--RenderTransformOrigink:获取或设置由 RenderTransform 声明的任何可能呈现转换的中心点,相对于元素的边界。这是依赖项属性。-->
    <Button.RenderTransform>
        <!--开始的旋转效果-->
        <RotateTransform Angle="0"
                         x:Name="b"></RotateTransform>
    </Button.RenderTransform>

    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="b"
                                     Storyboard.TargetProperty="Angle"
                                     From="0"
                                     By="360"
                                     Duration="0:0:2"></DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.RenderTransform>
</Button>
CS写法
//宽度放大
            DoubleAnimation dda = new DoubleAnimation(100,150,new Duration(TimeSpan.FromSeconds(3)));
            //实例化动画处理对象
            dda.AutoReverse = true;//返回
            dda.RepeatBehavior = RepeatBehavior.Forever;//重复这个行为
            bord4.BeginAnimation(Border.WidthProperty, dda);//启动动画
提示:(bord是标签)

实例 旋转缩放和平移变换一起实现

<Button Width="50" Height="50" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left">
    <Button.RenderTransform>
        <!--TransformGroup 可以支持多个变换 支持平移 也支持旋转-->
        <TransformGroup>
            <!--开始的旋转效果-->
            <RotateTransform Angle="0"
                             x:Name="b"></RotateTransform>
            <!--平移变换-->
            <TranslateTransform X="0"
                                x:Name="vv"></TranslateTransform>
            <!--缩放变换-->
            <ScaleTransform x:Name="ss"></ScaleTransform>
        </TransformGroup>
    </Button.RenderTransform>

    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <!--移动效果-->
                    <DoubleAnimation Storyboard.TargetName="vv"
                                     Storyboard.TargetProperty="X"
                                     From="0"
                                     By="360"
                                     AutoReverse="True"
                                     Duration="0:0:2"></DoubleAnimation>
                    <!--旋转效果-->
                    <DoubleAnimation Storyboard.TargetName="b"
                                     Storyboard.TargetProperty="Angle"
                                     From="0"
                                     By="360"
                                     AutoReverse="True"
                                     Duration="0:0:2"></DoubleAnimation>
                    <!--缩放效果-->
                    <DoubleAnimation Storyboard.TargetName="ss"
                                     Storyboard.TargetProperty="ScaleX"
                                     To="1.5"
                                     AutoReverse="True"
                                     Duration="0:0:2"></DoubleAnimation>
                    <DoubleAnimation Storyboard.TargetName="ss"
                                     Storyboard.TargetProperty="ScaleY"
                                     To="1.5"
                                     AutoReverse="True"
                                     Duration="0:0:2"></DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTriggers>
    </Button.Triggers>
</Button>


CS后台动画操作代码(完整版) / 基本动画FromTo/by动画

private void Button_Click(object sender, RoutedEventArgs e)
{
    // 1 创建动画对象
    DoubleAnimation 动画1 = new DoubleAnimation();

    // 2 创建标签动画开始的状态
    动画1.From = b2.Width;

    // 3 设置动画结束状态
    // 动画1.To = 250;

    // By 通过多少变成To值, To值-初始值=250-100=150
    动画1.By = 150;

    // 4 动画的时间 TimeSpan.FromSeconds(5) 5s
    动画1.Duration = new Duration(TimeSpan.FromSeconds(5));

    // 6 设置一些常用的属性
    // 动画结束的时候保持结束状态值/开始的状态值
    // 动画1.FillBehavior = FillBehavior.Stop; // 开始的状态值
    动画1.FillBehavior = FillBehavior.HoldEnd; // 结束状态

    // 7 动画无限重复执行
    动画1.RepeatBehavior = RepeatBehavior.Forever;

    // 8 支持相反方向的动画
     动画1.AutoReverse = true;

    // 9 延迟执行动画
     动画1.BeginTime = TimeSpan.FromSeconds(2);

    // 10 AccelerationRatio 速度变快这个过程所占的事件的比例边框
    // 和DecelerationRatio 速度变慢的过程所占时间的比例
    // 加速的过程是 5 * 0.3 = 1.5s 减速 5 * 0.3 = 1.5,剩余2s匀速 
     动画1.AccelerationRatio = 0.3;
    // 动画1.DecelerationRatio = 0.3;

    // 11动画结束的事件,当一个动画结束之后可以在时间函数在开启另一个动画
    // 这两个动画就是相互独立的
    // 必须写在动画开启之前,BeginAnimation
    动画1.Completed += 动画1_Completed;

    // 12 开启动画 参数1是做动画的属性 参数2是动画实例对象,参数2也可以写成null,写成null是停止动画
    b2.BeginAnimation(Button.WidthProperty, 动画1);

    // 第二个动画 如果直接写在动画的后面,这两个动画是同时执行的 
    DoubleAnimation 动画2 = new DoubleAnimation();
    动画2.From = b2.Height;
    动画2.To = 250;
    动画2.Duration = new Duration(TimeSpan.FromSeconds(5));
    b2.BeginAnimation(Button.HeightProperty, 动画2);

}



private void 动画1_Completed(object sender, EventArgs e)
{
    DoubleAnimation 动画2 = new DoubleAnimation();
    动画2.From = b2.Height;
    动画2.To = 250;
    动画2.AutoReverse = true;
    动画2.Duration = new Duration(TimeSpan.FromSeconds(5));
    b2.BeginAnimation(Button.HeightProperty,动画2);
}


本文部分内容来源网络,如有侵权请联系删除!!!

  • 48
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值