原文:WPF编程,通过KeyFrame 类型制作控件线性动画的一种方法。

版权声明:我不生产代码,我只是代码的搬运工。 https://blog.csdn.net/qq_43307934/article/details/87271931

From/To/By类型的动画仅支持从一个值到另一个值的线性内插,

或者有限形式的非线性内插(AccelerationRatio和DecelerationRatio)。

如果要描述一个更复杂的动画,如希望一个动画的属性从A值到B值再到C值,则用Key frame动画。

它在指定的时间提供指定的值。

 这里以一个球动态移动为例

 1、前台

   <Canvas Background="AntiqueWhite">
<Ellipse Name="elips"
Width="48"
Height="48"
Fill="Red"
Canvas.Left="480"
Canvas.Top="96" />
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard TargetName="elips"
TargetProperty="(Canvas.Left)">
<DoubleAnimationUsingKeyFrames RepeatBehavior="Forever"
AutoReverse="True"
Duration="0:0:10">
<LinearDoubleKeyFrame KeyTime="0:0:5"
Value="0" />
<LinearDoubleKeyFrame KeyTime="0:0:5.5"
Value="48" />
<DiscreteDoubleKeyFrame KeyTime="0:0:8"
Value="244" />
<DiscreteDoubleKeyFrame KeyTime="0:0:9"
Value="480" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>

以上是对控件的单个属性值进行变化。

如果需要对控件的多个属性值进行更改,代码如下:

 

        <Canvas Background="AntiqueWhite"
>
<Ellipse Name="elips"
Width="48"
Height="48"
Fill="Red"
Canvas.Left="480"
Canvas.Top="96" />
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard >
<DoubleAnimationUsingKeyFrames RepeatBehavior="Forever"
AutoReverse="True"
Duration="0:0:10"
Storyboard.TargetName="elips"
Storyboard.TargetProperty="(Canvas.Left)">
<LinearDoubleKeyFrame KeyTime="0:0:5"
Value="0" />
<LinearDoubleKeyFrame KeyTime="0:0:5.5"
Value="48" />
<LinearDoubleKeyFrame KeyTime="0:0:8"
Value="244" />
<LinearDoubleKeyFrame KeyTime="0:0:9"
Value="480" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames RepeatBehavior="Forever"
AutoReverse="True"
Duration="0:0:10"
Storyboard.TargetName="elips"
Storyboard.TargetProperty="(Canvas.Top)">
<LinearDoubleKeyFrame KeyTime="0:0:2"
Value="0" />
<LinearDoubleKeyFrame KeyTime="0:0:4"
Value="58" />
<LinearDoubleKeyFrame KeyTime="0:0:6"
Value="0" />
<LinearDoubleKeyFrame KeyTime="0:0:9"
Value="96" />
</DoubleAnimationUsingKeyFrames>
</Storyboard> </BeginStoryboard>
</EventTrigger> </Canvas.Triggers>
</Canvas>

RepeatBehavior="Forever" 为一直重复这个动画。

 AutoReverse="True" 为来回运行。如果为false则只单程运行。

 Duration="0:0:10"  为运行总时间。

2、解释:

球的开始位置是(480,96),这是通过Canvas.Left和Canvas.Top两个附加属性设置的。

动画改变Canvas.Left属性值,

第1个LinearDoubleKeyFrame 表示在动画的前5秒Canvas.Left 属性值从480改变为0,意味着球会匀速地向左运动直到Canvas的最左侧;

第2个LinearDoubleKeyFrame表示在接下来的0.5秒Canvas.Left属性值从0改变为48,意味着球会向右匀速运动;

第3个KeyFrame是一个DiscreteDoubleKeyFrame,表示在2.5秒后,Canvas.Left属性值会从48直接变化为244;

第4个DiscreteDoubleKeyFrame,表示Canvas.Left会在下秒直接变化为480。

即球在6秒时突然由横坐标48的位置突然跳到144的位置,然后在7秒时突然从144的位置跳到240的位置。

下一轮开始的时候,球回原路返回至起点。

开始下一轮的循环。

3、其它

DoubleKeyFrame对应的几种插值算法的关键帧为:

LinearDoubleKeyFrame、DiscreteDoubleKeyFrame、SplineDoubleKeyFrame、EasingDoubleKeyFrame。

在关键帧动画中,我们除了定义关键帧外,还需要定义两个关键帧之间的插值算法,这样系统才能根据关键帧和插值算法生成中间状态。WPF系统内置四种插值算法:

  • 线性:    两个关键帧之间均匀变化

  • 离散:    两个关键帧之间突变(到达时间点的时候硬切换,没有过渡效果)

  • 样条:    使用贝塞尔曲线实现更精确的加速和减速控制

  • 缓动:    使用缓动函数曲线实现弹性变化

综上来看,线性算法最常用,样条算法能实现精准加速和减速控制。离散的这种硬切换的效果虽然看起来没有什么动画效果,但用于连接关键帧还是比较常用的。另外在一些硬过渡的地方也是能用到的,例如实现闪烁效果。

这几种算法的具体效果这里就不做更多的介绍了,感兴趣的朋友可以看看如下两个链接中的描述和例子:

值得一提的是,并不是所有关键帧动画都支持这几种算法的,具体支持情况请参看MSDN:关键帧动画概述。 当然,对于不支持的也是可以自己手动实现的。

关键帧的时间点(KeyTime)

关键帧的时间点由IKeyFrame.KeyTime属性指定。它是一个KeyTime类型,它有如下几种取值类型:

  • 时间点TimeSpan: 靠TimeSpan直接决定时间点,可以通过函数KeyTime.FromTimeSpan()创建,也可以直接用TimeSpan隐式转换。

  • 相对时间Percent:  指定的是百分比,通过时间线的Duration来联合决定对应的时间点。通过函数KeyTime.FromPercent()创建。

  • 特殊值Uniform:    时间线平均分布每个关键帧所需要的时间。通过函数KeyTime.Uniform创建。

  • 特殊值Paced:      间线按固定的帧率分配所需时间,这种情况下,变化大的关键帧分配时间长,变化小的关键帧分配时间段。通过函数KeyTime.Paced创建。

用代码创建的方式这儿就不举例了,这里就仅仅列举一下如何在XAML中表示这几种时间:

    <LinearDoubleKeyFrame Value="100" KeyTime="0:0:3" />

    <LinearDoubleKeyFrame Value="100" KeyTime="30%" />

    <LinearDoubleKeyFrame Value="100" KeyTime="Uniform" />

    <LinearDoubleKeyFrame Value="100" KeyTime="Paced" />

4、后台实现

例如,改变按钮宽度的例子,如果我们要实现如下效果:

  • 在2秒时将宽度从 0变为350

  • 在7秒时将宽度变为50

  • 在9秒的时候将其宽度变为200

    var widthAnimation = new DoubleAnimationUsingKeyFrames();
    var keyFrames = widthAnimation.KeyFrames;     keyFrames.Add(new LinearDoubleKeyFrame(0, TimeSpan.FromSeconds(0)));
    keyFrames.Add(new LinearDoubleKeyFrame(350, TimeSpan.FromSeconds(2)));
    keyFrames.Add(new LinearDoubleKeyFrame(50, TimeSpan.FromSeconds(7)));
    keyFrames.Add(new LinearDoubleKeyFrame(200, TimeSpan.FromSeconds(9)));     button.BeginAnimation(WidthProperty, widthAnimation);

推荐:https://www.cnblogs.com/TianFang/p/4050845.html

WPF编程,通过KeyFrame 类型制作控件线性动画的一种方法。的更多相关文章

  1. 一、winForm-DataGridView操作——控件绑定事件的两种方法

    在winForm窗体中绑定(注册)事件的方法有两种: 一.绑定事件 双击控件,即进入.cs的代码编辑页面,会出现 类似于“ private void 控件名称_Click(object sender, ...

  2. C#实现Dll(OCX)控件自动注册的两种方法 网上找的 然后 自己试了试 还是可以用的

    尽管MS为我们提供了丰富的.net framework库,我们的程序C#开发带来了极大的便利,但是有时候,一些特定功能的控件库还是需要由第三方提供或是自己编写.当需要用到Dll引用的时候,我们通常会通 ...

  3. ASP.NET中GridView控件删除数据的两种方法

      今天在用GridView控件时,发现了一个问题,就是使用GridView控件在删除数据时的问题.接下来我们通过模板列方式和CommandField方式删除某条数据讲解下两者之间的区别. 方式一:通 ...

  4. C#实现Dll(OCX)控件自动注册的两种方法

    尽管MS为我们提供了丰富的.net framework库,我们的程序C#开发带来了极大的便利,但是有时候,一些特定功能的控件库还是需要由第三方提供或是自己编写.当需要用到Dll引用的时候,我们通常会通 ...

  5. Android中动态改变控件的大小的一种方法

    在Android中有时候我们需要动态改变控件的大小.有几种办法可以实现  一是在onMeasure中修改尺寸,二是在onLayout中修改位置和尺寸.这个是可以进行位置修改的,onMeasure不行. ...

  6. 用css3制作旋转加载动画的几种方法

    以WebKit为核心的浏览器,例如Safari和Chrome,对html5有着很好的支持,在移动平台中这两个浏览器对应的就是IOS和Android.最近在开发一个移动平台的web app,那么就有机会 ...

  7. robotframework 时间控件的操作的几种方法总结。

  8. WPF编程,通过Path类型制作沿路径运动的动画另一种方法。

    原文:WPF编程,通过Path类型制作沿路径运动的动画另一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/d ...

  9. WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案

    首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如  WPF中不规则窗体与WebBrowser控件的兼 ...

随机推荐

  1. selector设置按钮或者一些点击控件在点击时的效果

    <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="ht ...

  2. 腾讯TBS X5 WebView的简单使用

    工作中经常涉及H5网页的加载工作,最多使用的就是安卓系统控件WebView,但是当网页内容比较多的时候,需要等待很久才能加载完,加载完后用户才能看到网页中的内容,这样用户需要等很久,体验很差. 那能不 ...

  3. 解决 jQuery validation插件 valid()方法总是返回true的问题

    在表单元素验证方法中加入了 remote 方法,调试一直返回true,后来才知道因为是异步验证,所以才会出现此问题,解决方法就是在 remote 方法中,禁用 异步和缓存,具体代码如下 : ..... ...

  4. hashCode()与equals()方法的对比

        Java对于eqauls方法和hashCode方法是这样规定的: 1.如果两个对象相同,那么它们的hashCode值一定要相同: 2.如果两个对象的hashCode相同,它们并不一定相同(上面 ...

  5. HDFS Lease Recovey 和 Block Recovery

    这篇分析一下Lease Recovery 和 Block Recovery hdfs支持hflush后,需要保证hflush的数据被读到,datanode重启不能简单的丢弃文件的最后一个block,而 ...

  6. 参数innodb_force_recovery影响了整个InnoDB存储引擎的恢复状况

    参数innodb_force_recovery影响了整个InnoDB存储引擎的恢复状况.该值默认为0,表示当需要恢复时执行所有的恢复操作.当不能进行有效恢复时,如数据页发生了corruption,My ...

  7. 远程监控tomcat内存使用

    边界远程Tomcat服务器的Tomcat配置文件,如下: vi /etc/init.d/tomcatd8_test export JAVA_OPTS="-Xms1024m -Xmx4056m ...

  8. sql注入--access

    access数据库结构: 表名  -->  列名  -->  数据 access注入攻击片段 联合查询法: (1)  判断注入点:  ?id=1 and 1=1 ; ?id=1 and 1 ...

  9. Balanced Search Trees

    平衡搜索树 前面介绍的二叉搜索树在最坏情况下的性能还是很糟糕,而且我们不能控制操作的顺序,有时根本就不是随机的,我们希望找到有更好性能保证的算法. 2-3 search trees 于是先来了解下 2 ...

  10. SDN 第五次上机作业

    1.搭建如下拓扑并连接控制器 2.下发相关流表和组表实现负载均衡 s1: s2: s3: s4: 3.抓包分析验证负载均衡 s4-eth1: s4-eth2: s4-eth3