前言:
昨天说到了利用基于帧的动画来实现效果,这其实与WPF提供的图形与动画功能没有太大关系,在这里我们还是要关注一下WPF为我们提供的高级方法来解决问题。
本次主题将简述WPF中有关“图形效果”与“动画基础”的知识。
(上一篇:小人快跑之WPF基础——图形与动画(一))
1.任务的改进:
WPF不提倡使用基于帧的动画功能,缺点在之前已经说到:(1)绘制大量图片(2)没有提供方法或属性调节帧速(3)没有具体的时间线概念
此外,WPF告诉我们如果要想有类似图片切换的效果,淡入淡出是一个比较友好的选择,它能让效果看起来更加舒服流畅,而不是一个图片隐藏一个图片显示(设置Visiblity)
(在后来我发现这个功能其实完全不是用来做这种动画效果的,只是一次学习的经历并由此完成“图形效果”与“动画基础”知识的学习)
2.本次需要准备的知识:
2.1 动画(Animation)
2.2 Image标签(控件),元素的不透明度(Opacity)
简单说明一下,Image标签(控件)用来呈现图像,使用source特性获取图片的URI,就完成了图片的显示(相比第一次,我们使用了BitmapImage方法进行绘图),而相对与标签(控件),元素这个概念相对复杂一点,这牵涉到WPF的系统结构。简单来说,所有界面元素(UIElement)都拥有Opacity属性,而绝大部分上层元素都继承了UIElement,其中就包括了Image控件。
Opacity则是利用不透明的效果来完成图片的切换。0表示全透明,1表示全不透明
(其实在之后没多久我就发现淡入淡出效果这么用是不太合理的,但是也算是走岔路完成了图形到动画的学习过程,大家看看这个demo和我关注的知识点就好了,实际中这么去做非常消耗资源。)
2.3 基于属性的动画(WPF Property Animation System)
这里需要了解的更多:
2.3.1 属性。WPF的依赖属性与常说的CLR属性其实差不多,只是WPF所有元素都继承了Dependency Property,WPF的动画模型完全建立在依赖属性这个概念之上,如果您有认真的学习依赖属性的概念,您将知道,WPF是能够通过Binding完成数据驱动,即:UI界面实时的随着数据的变化而变化,在这里,数据指依赖属性。而WPF的属性动画本质上就是在一段时间间隔内修改依赖属性的值,这是WPF动画的第一规则。
2.3.2 AnimaitonClass 。属性就代表有值,而修改属性就是修改值,不论怎样值都是一种数据类型,所以产生了动画类族,也就是适用于改变不同类型值的动画类,在这里我们讲一个DoubleAnimation,懂一个就懂全部的了。
2.4 了解布局层次
一个简单的小提示,在WPF中,二维平面图形是拥有层次概念的,其实就是在同一个位置放置了两幅图片,第二幅会掩盖第一幅,这个还与Panel的ZIndex相关。
3.简述一下步骤:
利用Opacity(0为透明,1为不透明)的特点,咱们放好两张之前做好的图片(还用那两张随手画的小人),第二张图片因为ZIndex的关系,会掩盖第一张,所以把第二张图片反复的淡入淡出,然后两张图片就会交替出现,这样就能够比较好的模拟动画的效果(如果两张按照一定时间顺便淡入淡出,效果会非常好)
4.具体代码如下:
首先先写好我们的XAML:
代码非常简单,两个Image标签固定了图片的位置
<Window x:Class="WpfApplication2.OpacityAnimation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OpacityAnimation" Height="300" Width="500">
<Grid>
<Canvas Grid.Row="0" x:Name="canvas1">
<Image Height="auto" Width="auto" x:Name="img1" Source="/Image/1.bmp"></Image>
<Image x:Name="img2" Source="/Image/2.bmp" Opacity="0"></Image>
</Canvas>
</Grid>
</Window>
在后台使用DoubleAnimation进行动画操作:
因为对小人变化来说,其实是改变Image的Opacity属性,而Opacity是一个Double型的,使用DoubleAnimation
public OpacityAnimation()
{
InitializeComponent();
Img1Animation();
Img2Animation();
}
double timeSpan = 0.1;
int repeatCount = 100;
private void Img1Animation()
{
//声明动画类
DoubleAnimation animation = new DoubleAnimation();
//属性的初始值
animation.From = 0;
//属性的终值
animation.To = 1;
//属性变化持续的时间
animation.Duration = TimeSpan.FromSeconds(timeSpan);
//反过来动画一次
animation.AutoReverse = true;
animation.RepeatBehavior = new RepeatBehavior(repeatCount);
img1.BeginAnimation(Image.OpacityProperty, animation);
}
你没有看错,代码就这么一点,因为Animation很好的帮我们解决了动画的所有关键点:设置时间,设置好值范围,Animation解决检查,Animation解决计算,Animation解决重绘,完全不需要我们做太多逻辑处理,相比第一次,简直是有了突飞猛进的精简!
同样的道理可以运用在小人移动上,具体实现我没有写,大家随便写写就可以出来了。
5.小结
6.参考引用
以及其他
PS:具体代码等明天把最后一个也是WPF动画模型最核心部分的文章写完了再打包上传