【WPF学习】第五十四章 关键帧动画

  到目前为止,看到的所有动画都使用线性插值从起点到终点。但如果需要创建具有多个分段的动画和不规则移动的动画。例如,可能希望创建一个动画,快速地将一个元素滑入到视图中,然后慢慢地将它移到正确位置。可通过创建两个连续的动画,并使用BeginTime属性在第一个动画之后开始第二个动画来实现这种效果。然而,还有更简单的方法——可使用关键帧动画。

  关键帧动画是由许多较短的段构成的动画。每段表示动画中的初始值,最终值或中间值当运行动画时,它平滑地从一个值移到另一个值。

  例如,分析下面的将RadialGradientBrush画刷的中心点从一个位置移到另一个位置的Point动画:

<PointAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin"
                                    From="0.7,0.3" To="0.3,0.7" Duration="0:0:10" AutoReverse="True" RepeatBehavior="Forever">
                    </PointAnimation>

  可使用一个效果相同的PointAnimationUsingKeyFrames对象代替这个PointAnimation对象,如下所示:

<PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin" AutoReverse="True" RepeatBehavior="Forever"> 
  <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></LinearPointKeyFrame> 
  <LinearPointKeyFrame Value="0.3,0.7" KeyTime="0:0:10"></LinearPointKeyFrame>
</PointAnimationUsingKeyFrames>

  这个动画包含两个关键帧。当动画首次启动时第一个关键帧设置Point值(如果希望使用在RadialGradientBrush画刷中设置的当前值,可省略这个关键帧)。第二个关键帧定义结束值,这是10秒之后达到的数值。PointAnimationUsingKeyFrames对象执行线性插值。从第一个关键帧平滑移到第二个关键帧,就像PointAnimation对象对From和To值执行的操作一样。

  可使用一系列关键帧创建更有趣的示例。下面的动画通过在不同的时刻到达的一系列位置经历中心点。中心点的移动速度根据关键帧之间的持续时间以及需要移动的距离而改变。

<PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin"
                                           RepeatBehavior="Forever">
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.3,0.7" KeyTime="0:0:5"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.8,0.2" KeyTime="0:0:12"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:14"></LinearPointKeyFrame>
</PointAnimationUsingKeyFrames>

  这个动画不是可反转的,但可以重复。为确保在一次迭代的最后数据和下一次迭代的开始数值之间不会出现跳跃,应使动画的结束点和开始点位于相同的中心点。

一、离散的关键帧动画

  上面示例中的关键帧动画使用线性关键帧。所以,它在关键帧值之间平滑地过渡,另一种选择是使用离散的关键帧。对于这种情况,不进行插值。当到达关键时间时,属性突然改变为新值。

  线性关键帧类使用“Linear+数据类型+KeyFrame”的形式进行命名。离散关键帧类使用“Discrete+数据类型+KeyFrame”的形式命名。下面是RadialGradientBrush画刷示例的修改版本,在该修改版本中使用的是离散关键帧:

<PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin"
                                           RepeatBehavior="Forever">
                        <DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.3,0.7" KeyTime="0:0:5"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.8,0.2" KeyTime="0:0:12"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:14"></DiscretePointKeyFrame>
</PointAnimationUsingKeyFrames>

  当运行这个动画时,中心点在适当的时间从一个位置跳到下一个位置。这是戏剧性的(但是不平稳的)效果。

  所有关键帧动画类都支持离散关键帧,但只有一部分关键帧动画类支持线性关键帧。这完全取决于数据类型。支持线性关键帧的数据类型也支持线性插值,并提供了相应的DataTypeAnimation类,如Point、Color以及double。不支持线性插值的数据类型包括字符串和对象。

二、缓动关键帧

  通过“【WPF学习】第五十一章 动画缓动 ”的学习,看到了如何使用缓动函数改进普通动画。尽管关键帧动画被分割成多段,但每段仍使用普遍的、令人厌烦的线性插值。

  如果这不是希望的结果,可使用缓动函数为每个关键帧添加加速和减速的效果。然而,普通的线性插值关键帧类和离散关键帧类不支持该特征。相反,需要使用缓动关键帧,如EasingDoubleKeyFrame、EasingColorKeyFrame或EasingPointKeyFrame。每个缓动关键帧类和对应的线性插值关键帧类的工作方式相同,但是额外提供了EasingFunction属性。

  下面的示例使用动画缓动为前5秒得关键帧动画应用加速效果:

<PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin"
                                           RepeatBehavior="Forever">
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></LinearPointKeyFrame>
                        <EasingPointKeyFrame Value="0.3,0.7" KeyTime="0:0:5">
                            <EasingPointKeyFrame.EasingFunction>
                                <CircleEase></CircleEase>
                            </EasingPointKeyFrame.EasingFunction>
                        </EasingPointKeyFrame>
                        <LinearPointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.8,0.2" KeyTime="0:0:12"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:14"></LinearPointKeyFrame>
</PointAnimationUsingKeyFrames>

  结合使用关键帧和动画缓动是构建复杂动画模型的简便方式,但仍可能无法提供所需的控制。不使用动画缓动,可创建数学公式指示动画的进度。

三、样条关键帧动画

  还有一种关键帧类型:样条关键帧。每个支持线性关键帧的类也支持样条关键帧,它们使用“Spline+数据类型+KeyFrame”的形式进行命名。

  与线性关键帧一样,样条关键帧使用插值从一个键值平滑地移到另一个键值。区别是每个样条关键帧都是KeySpline属性。可使用该属性定义能影响插值方式的三次贝塞尔曲线。尽管为了得到希望的效果这样做有些繁琐,但这种技术能创建更加连贯的加速和减速以及更逼真的动画效果。

  在前面章节学习过,贝塞尔曲线由起点、终点以及两个控制点定义。对于关键样条,起点总是(0,0),终点总是(1,1)。用户只需要提供两个控制点。创建的曲线描述了时间(X轴)和动画值(Y值)之间的关系。

  下面的示例通过对比Canvas面板上两个椭圆的移动,演示了一个关键帧样条动画。第一个椭圆使用DoubleAnimation动画缓慢匀速地再窗口上移动。第二个椭圆使用具有两个SplineDoubleKeyFrame对象的DoubleAnimationUsingKeyFrames动画。两个椭圆同时到达目的位置(10秒后),但第二个椭圆在运动过程中会有明显的加速和减速,减速时会超过第一个椭圆而减速时又会落后于第一个椭圆。

 <DoubleAnimationUsingKeyFrames
             Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Canvas.Left)" >
         <SplineDoubleKeyFrame KeyTime="0:0:5" Value="250" KeySpline="0.25,0 0.5,0.7"></SplineDoubleKeyFrame>
         <SplineDoubleKeyFrame KeyTime="0:0:10" Value="500" KeySpline="0.25,0.8 0.2,0.4"></SplineDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>

 <DoubleAnimation
            Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Canvas.Left)"
            To="500" Duration="0:0:10">
</DoubleAnimation>

  最快的加速发生在5秒后不久,也就是当进入第二个SplineDoubleKeyFrame关键帧时。贝塞尔曲线的第一个控制点将较大的表示动画进度(0.8)的Y轴值与较小的表示时间的X轴值相匹配。所以,在再次减慢速度前,椭圆在一小段距离内会增加速度。

  下图以图形方式显示了两条控制椭圆运动的曲线。为理解这些曲线,请记住它们从顶部到底部描述了动画过程。观察第一条曲线可以发现,它相对均匀地下降,在开始处有较短的暂停,在末尾处平缓下降。然而第二条曲线快速下降,运动了一个大段距离,然后对于剩余的动画部分,曲线缓缓下降。

  示例的完整XAML标记如下所示:

<Window x:Class="Animation.KeySplineAnimation"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="KeySplineAnimation" Height="300" Width="624" WindowStartupLocation="CenterScreen">
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames
             Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Canvas.Left)" >
                            <SplineDoubleKeyFrame KeyTime="0:0:5" Value="250" KeySpline="0.25,0 0.5,0.7"></SplineDoubleKeyFrame>
                            <SplineDoubleKeyFrame KeyTime="0:0:10" Value="500" KeySpline="0.25,0.8 0.2,0.4"></SplineDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>

                        <DoubleAnimation
            Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Canvas.Left)"
            To="500" Duration="0:0:10">
                        </DoubleAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </Window.Triggers>
    <Canvas Margin="10">
        <Ellipse Name="ellipse1" Canvas.Left="0" Fill="Red" Width="10" Height="10"></Ellipse>

        <Path Stroke="Blue" StrokeThickness="1" StrokeDashArray="2 1" Canvas.Top="25">
            <Path.Data>
                <PathGeometry>
                    <PathFigure>
                        <BezierSegment Point1="25,0" Point2="50,70" Point3="100,100" />
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
            <Path.RenderTransform>
                <ScaleTransform ScaleX="2.5"></ScaleTransform>
            </Path.RenderTransform>
        </Path>
        <Path Stroke="Blue" StrokeThickness="1" StrokeDashArray="2 1" Canvas.Left="250" Canvas.Top="25">
            <Path.Data>
                <PathGeometry>
                    <PathFigure>
                        <BezierSegment Point1="25,80" Point2="20,40" Point3="100,100" />
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
            <Path.RenderTransform>
                <ScaleTransform ScaleX="2.5"></ScaleTransform>
            </Path.RenderTransform>
        </Path>

        <Ellipse Name="ellipse2" Canvas.Top="150" Canvas.Left="0" Fill="Red" Width="10" Height="10"></Ellipse>
    </Canvas>
</Window>
KeySplineAnimation

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WPF(Windows Presentation Foundation)是微软公司推出的一种开发Windows应用程序的技术框架,它通过使用XAML(eXtensible Application Markup Language)来描述应用程序的界面和UI元素,并结合C#或其他编程语言来实现应用程序的逻辑功能。WPF提供了丰富的UI控件库、布局管理器、数据绑定、样式和模板等功能,使开发者能够快速创建功能强大且美观的应用程序。 WPF动画功能是其重要的特性之一,通过使用WPF动画功能,开发者可以在应用程序中创建各种各样的动画效果,为应用程序的用户界面增添生动和交互性。WPF动画可以应用于UI元素的位置、大小、颜色等属性,以及控件的形状、透明度、旋转、缩放等变化。开发者可以使用XAML或C#代码来定义动画效果,并通过设定起始值和结束值之间的过渡方式来控制动画的播放速度和效果。 CSDN(China Software Development Network)是中国最大的IT社区和专业的技术开发者网络平台,提供全面的技术文档、下载资源、技术问答、博客分享等服务,是广大开发者学习、交流和分享经验的重要平台之一。在CSDN上,开发者可以找到关于WPF动画的详细教程、例子代码和实践经验分享,了解如何使用WPF动画功能创建各种各样的动画效果。 通过在CSDN上学习和掌握WPF动画的相关知识,开发者可以深入了解WPF动画的原理和使用方法,并能够灵活运用WPF动画功能来打造出独特、富有创意的应用程序界面。通过参与CSDN的讨论和交流,开发者还可以与其他开发者分享自己的学习心得和经验,并从他人的经验中学到更多有关WPF动画的技巧和最佳实践。总之,WPF动画和CSDN为开发者提供了一个良好的学习和交流平台,使开发者能够更好地掌握和应用WPF动画功能。 ### 回答2: WPF是一种用于构建 Windows 客户端应用程序的技术,它提供了丰富的功能和灵活的界面设计选项。而动画WPF中非常重要的一部分,可以为界面元素添加各种动态效果和交互效果。 在CSDN上,我们可以找到大量关于WPF动画学习资源和教程,有助于我们深入了解和掌握WPF动画的原理和使用方法。CSDN的WPF动画专栏中,不仅有详细的动画基础知识介绍,还有具体的代码示例和案例分析,可以帮助我们快速上手和实践。 WPF中的动画可以通过多种方式实现,包括属性动画、路径动画、触发器动画等。属性动画可以实现元素的平移、缩放、旋转等效果,路径动画可以让元素沿着预定义路径移动,而触发器动画可以根据特定的条件触发元素的动画效果。通过CSDN上的相关教程,我们可以学习到这些动画的具体用法和实现方法。 此外,CSDN上还有许多WPF动画相关的博客和经验分享,可以帮助我们解决在实际开发中遇到的问题,并提供一些建议和技巧。 总的来说,WPF动画是一项非常实用和有趣的技术,它可以为我们的应用程序增加各种视觉效果,提高用户体验。而CSDN作为一个IT技术社区,提供了丰富的WPF动画学习资源,可以帮助我们更好地掌握和应用这项技术。无论是初学者还是有经验的开发者,都可以通过CSDN上的教程和资源,更好地使用WPF动画来设计出更加吸引人的用户界面。 ### 回答3: WPF(Windows Presentation Foundation)是一种用于创建高性能、现代化用户界面的框架。它提供了强大的图形渲染功能和灵活的布局系统,使开发人员能够创建出各种功能丰富且美观的应用程序。 在WPF中,动画是一种非常重要的特性。它可以让界面元素以流畅而连续的方式移动、旋转、缩放和淡入淡出等效果。WPF动画机制非常灵活,可以通过代码或XAML来定义动画效果。而CSDN是一个知名的IT技术社区,WPF动画方面的教程和文章在CSDN上非常丰富。 CSDN上的WPF动画教程可以帮助开发人员掌握WPF动画的使用方法和技巧。其中会介绍WPF动画的基本概念、属性和类型,以及如何使用关键帧动画、路径动画、缩放动画等。教程中还会涉及到WPF动画的常见应用场景,如创建动态图标、实现按钮交互效果等。 在CSDN上,还可以找到一些WPF动画的示例代码和案例讲解。这些实例可以帮助开发人员更好地理解WPF动画的实现原理和技术细节。通过学习这些示例,开发人员可以逐步提升自己的WPF动画开发能力,并将其应用于自己的实际项目中。 总之,WPF动画在用户界面的设计和交互中起到很重要的作用,开发人员可以通过CSDN上的资源来学习和掌握WPF动画的使用。无论是初学者还是有一定WPF开发经验的开发人员,CSDN上的WPF动画教程和文章都会给予帮助和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值