21.2.1 Animation类
根据目前为止提到的动画类型-- DoubleAnimation动画类和ColorAnimation动画类-- 您可能会认为所有的动画类都是以"类型名+Animation"的方式命名的。这种观点很接近实际,但不是非常准确。
实际上有两种类型的动画-- 在一个开始值和结束值之间以逐步增加的方式(被称为线性插值的过程)改变属性的动画,以及从一个值突然改变到另外一个值的动画。DoubleAnimation动画类和ColorAnimation动画类属于第一种动画,它们使用插值平滑地改变数值。然而,当改变特定的数据类型时,如String类型和引用类型的对象,插值是没有意义的。但这些类型却使用一种称为关键帧动画的技术从一个数值突然改变到另一个数值。所有的关键帧动画类都使用"类型名+AnimationUsingKeyFrames"的形式进行命名,如StringAnimationUsingKeyFrames类和ObjectAnimationUsingKey Frames类。
某些数据类型有关键帧动画类,但是没有插值动画类。例如,可以使用关键帧动画类为一个字符串应用动画,但是不能使用插值动画类为字符串应用动画。然而,每个具有常规的使用插值的动画类的数据类型(例如DoubleAnimation动画类和ColorAnimation动画类)也有一个相应的用于关键帧动画的动画类(如DoubleAnimationUsingKeyFrames动画类和ColorAnimationUsing KeyFrames动画类)。
实际上,还有另外一种动画类型。这种类型被称为基于路径的动画,并且它比使用插值或关键帧的动画更加专业。基于路径的动画修改数值使其符合由PathGeometry对象描述的形状,并且它主要用于沿着路径移动元素。基于路径的动画类使用"类型名+AnimationUsingPath"的形式进行命名,如DoubleAnimationUsingPath动画类和PointAnimationUsingPath动画类。
注意:
尽管目前WPF可以为动画使用三种方法(线性插值、关键帧以及路径),但是也完全可以创建更多的使用完全不同的方式来修改数值的动画类。唯一需要的是自定义的动画类必须根据时间修改数值。
总之,在System.Windows.Media.Animation名称空间中将会发现以下内容:
17个线性插值动画类,这些类使用线性插值动画
22个关键帧动画类,这些类使用关键帧动画
3个路径动画类,这些类使用基于路径的动画
这三种类中的每个类都继承自抽象的TypeNameAnimationBase类,这些基类实现了一些基本功能。从而为创建自己的动画类提供了一个快捷方式。如果数据类型支持多种类型的动画,那么所有的动画类都继承自抽象的基类。例如,DoubleAnimation动画类和DoubleAnimationUsingKeyFrames动画类都继承自DoubleAnimationBase基类。
注意:
这42个类并不是System.Windows.Media.Animation名称空间中的唯一内容。每个关键帧动画还使用自己的关键帧类和关键帧集合类,这两部分类会导致一些混乱。总之,在System. Windows.Media.Animation名称空间中有100多个类。
可以通过查看这42个类快速决定哪些数据类型为动画提供了本地支持。下面是这42个类的完整列表:
BooleanAnimationUsingKeyFrames | PointAnimationUsingKeyFrames |
ByteAnimation ByteAnimationUsingKeyFrames | PointAnimationUsingPath Point3DAnimation |
CharAnimationUsingKeyFrames | Point3DAnimationUsingKeyFrames |
ColorAnimation | QuarternionAnimation |
ColorAnimationUsingKeyFrames | QuarternionAnimationUsingKeyFrames |
DecimalAnimation | RectAnimation |
DecimalAnimationUsingKeyFrames | RectAnimationUsingKeyFrames |
DoubleAnimation | Rotation3DAnimation |
DoubleAnimationUsingKeyFrames | Rotation3DAnimationUsingKeyFrames |
DoubleAnimationUsingPath | SingleAnimation |
Int16Animation | SingleAnimationUsingKeyFrames |
Int16AnimationUsingKeyFrames | SizeAnimation |
Int32Animation | SizeAnimationUsingKeyFrames |
Int32AnimationUsingKeyFrames | StringAnimationUsingKeyFrames |
Int64Animation | ThicknessAnimation |
Int64AnimationUsingKeyFrames | ThicknessAnimationUsingKeyFrames |
MatrixAnimationUsingKeyFrames | VectorAnimation |
MatrixAnimationUsingPath | VectorAnimationUsingKeyFrames |
ObjectAnimationUsingKeyFrames | Vector3DAnimation |
PointAnimation | Vector3DAnimationUsingKeyFrames |
其中的许多类都是自解释的。例如,一旦掌握了DoubleAnimation类,就不需要再分析SingleAnimation类、Int16Animation类、Int32Animation类以及所有用于其他简单数字类型的动画类,它们都以相同的方式工作。除了这些用于数值类型的动画类之外,还会发现一些使用其他基本数据类型(如byte、bool、string以及char)的动画类,以及更多的处理二维和三维Drawing图元(Point、Size、Rect、Vector等)的动画类。还可以发现用于所有元素的Margin属性和Padding属性的动画类(ThicknessAnimation类)、一个用于颜色的动画类(ColorAnimation类)、一个用于所有引用类型对象的动画类(ObjectAnimationUsingKey Frames类)。在本章将通过示例分析这些动画类型中的许多类。
混乱的Animation名称空间
如果查看System.Windows.Media.Animation名称空间,可能会感到有些震惊。在该名称空间中充满了针对不同数据类型的不同动画类。效果有些重复。如果能够将所有这些动画特性组合到几个核心类中可能会更好。难道开发人员不能实现合适的能够用于所有数据类型的通用Animate<T>类?由于有许多原因,使得这种模型在目前还行不通。例如,ColorAnimation类使用将颜色值从一种颜色褪色到另外一种颜色的方式,与DoubleAnimation类修改单个数值的方式就不同。换句话说,尽管动画类提供了相同的公有接口,但是它们的内部工作可能是不同的。这些接口通过继承进行标准化,因为所有的动画类都继承自相同的基类。
然而,还不止如此。许多动画类共享大量的代码,并且只有较少的代码不同,例如,大约有100个类使用关键帧和关键帧集合。在现实世界中,动画类通过它们执行的动画类型进行区别,所以可以使用和NumericAnimation<T>、KeyFrameAnimation<T>或LinearInterpolation Animation<T>类似的类。唯一能够假定的是,阻止这种解决方法的深层次原因是XAML缺乏对这种通用性的支持。