动画简介
动画是快速播放一系列图像(其中每个图像与下一个图像略微不同)给人造成的一种幻觉。大脑感觉这组图像是一个变化的场景。在电影中,摄像机每秒钟拍摄许多照片(帧),便可使人形成这种幻觉。用投影仪播放这些帧时,观众便可以看电影了。在 Silverlight 中,通过对对象的个别属性应用动画,可以对对象进行动画处理。例如,若要使 UIElement 增大,需对其 Width 和 Height 属性进行动画处理。若要使 UIElement 逐渐从视野中消失,可以对其 Opacity 属性进行动画处理。可以对 Silverlight 中许多对象的属性进行动画处理。
说明:在 Silverlight 中,您只能对值类型为 Double、Color或 Point 的属性执行简单的动画处理。此外,还可以使用 ObjectAnimationUsingKeyFrames 对其他类型的属性进行动画处理,但是这需要使用离散内插(从一个值跳到另一个值),而多数人认为这不是真正的动画。
使 UIElement 逐渐进入视野并从视野中逐渐消失
此示例演示如何使用 Silverlight 动画通过对属性值进行动画处理,使 Rectangle 逐渐进入视野并从视野中逐渐消失。本示例使用 (一种生成 Double 值的动画类型)对 Rectangle 的 Opacity 属性进行动画处理。因此,Rectangle 将逐渐进入视野并逐渐从视野中消失。若要查看您将演练的动画的预览,请单击下面的链接来运行示例,然后单击矩形开始运行动画。
<Rectangle MouseLeftButtonDown="Mouse_Clicked"
x:Name="MyAnimatedRectangle"
Width="100" Height="100" Fill="Blue" />
</StackPanel>
若要创建动画并将其应用于矩形的 Opacity 属性,请执行以下操作:
-
创建 Storyboard
-
开始 Storyboard 以响应事件
以下各节将详细讨论这些步骤。有关完整的示例,请参见完整示例一节。
创建 DoubleAnimation
由于 Opacity 属性的类型是 Double,因此需要一个生成 Double 值的动画。DoubleAnimation 就是这样一种动画;它可以创建两个 Double 值之间的过渡。若要指定 DoubleAnimation 的起始值,可设置其 From 属性。若要指定其终止值,可设置其 To 属性。
-
不透明度值 1.0 使对象完全不透明,不透明度值 0.0 使对象完全不可见。若要使动画的不透明度值从 1.0 过渡为 0.0,可以将其 From 属性设置为 1.0,将其 To 属性设置为 0.0。
<DoubleAnimation From="1.0" To="0.0" /> -
为该动画指定 Duration。动画的 Duration 属性指定了从其起始值过渡为目标值所需的时间。下面的示例将动画的持续时间设置为一秒钟。
-
上面的示例创建了不透明度值从 1.0 向 0.0 过渡的动画,此过渡使目标元素从完全不透明逐渐转变为完全不可见。若要使元素在消失后再逐渐回到视野中,请将 AutoReverse 属性设置为 true。若要使动画无限期地重复,请将其 RepeatBehavior 属性设置为 Forever。 <DoubleAnimation From="1.0" To="0.0" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever"/>
-
..
创建演示图板
若要向对象应用动画,请创建 Storyboard 对象并使用 TargetName 和 TargetProperty 附加属性指定要进行动画处理的对象和属性。
创建 Storyboard 并将动画添加为其子项.
<DoubleAnimation From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
使用 TargetName 附加属性指定要进行动画处理的对象。在下面的代码中,为 DoubleAnimation 指定了一个目标名称 myAnimatedRectangle,这是要进行动画处理的对象的名称。
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
使用 TargetProperty 附加属性指定要进行动画处理的属性。在下面的代码中,动画被配置为面向 Rectangle 的 Opacity 属性。
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 200;
myRectangle.Height = 200;
Color myColor = Color.FromArgb(255, 255, 0, 0);
SolidColorBrush myBrush = new SolidColorBrush();
myBrush.Color = myColor;
myRectangle.Fill = myBrush;
// Add the rectangle to the tree.
LayoutRoot.Children.Add(myRectangle);
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
DoubleAnimation myDoubleAnimation2 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
myDoubleAnimation2.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(myDoubleAnimation1);
sb.Children.Add(myDoubleAnimation2);
Storyboard.SetTarget(myDoubleAnimation1, myRectangle);
Storyboard.SetTarget(myDoubleAnimation2, myRectangle);
// Set the attached properties of Canvas.Left and Canvas.Top
// to be the target properties of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("(Canvas.Left)"));
Storyboard.SetTargetProperty(myDoubleAnimation2, new PropertyPath("(Canvas.Top)"));
myDoubleAnimation1.To = 200;
myDoubleAnimation2.To = 200;
// Make the Storyboard a resource.
LayoutRoot.Resources.Add("unique_id", sb);
// Begin the animation.
sb.Begin();
}
不要试图在页面的构造函数中调用 Storyboard 方法,如 Begin。这将导致动画失败,且无任何提示。
上面的示例使用了 DoubleAnimation 对属性进行动画处理。除了 DoubleAnimation 类型,Silverlight 还提供其他几种动画对象。由于动画生成属性值,因此对于不同的属性类型,会有不同的动画类型。若要对采用 Double 值的属性(例如元素的 Width 属性)进行动画处理,请使用生成 Double 值(DoubleAnimation)的动画。若要对采用 Point 值的属性进行动画处理,请使用生成 Point 值(如 PointAnimation 等)的动画。
Silverlight 提供两大类动画类型,From/To/By 动画和关键帧动画。下表说明这些动画类别及其命名约定。
类别 |
说明 |
命名约定 |
---|---|---|
From/To/By 动画 |
在起始值和结束值之间进行动画处理:
此概述中的示例使用这些动画,因为这些动画最容易实现。 |
typeAnimation |
关键帧动画 |
在使用关键帧对象指定的一系列值之间播放动画。关键帧动画的功能比 From/To/By 动画的功能更强大,因为您可以指定任意多个目标值,甚至可以控制它们的插值方法。关键帧动画中详细描述了关键帧动画。 |
typeAnimationUsingKeyFrames |
下表显示了一些常用动画类型以及与这些类型一起使用的一些属性。
属性类型 |
对应的基本 (From/To/By) 动画 |
对应的关键帧动画 |
用法示例 |
---|---|---|---|
对 SolidColorBrush 或 GradientStop 的 Color 进行动画处理。 |
|||
对 Rectangle 的 Width 或 Ellipse 的 Height(或任意 FrameworkElement)进行动画处理。 |
|||
对 EllipseGeometry 的 Center 位置进行动画处理。 |
|||
无 |
对 Fill 属性进行动画处理,使其在不同的 GradientBrush 之间进行转换。 |
动画是时间线
所有动画均继承自 Timeline 对象,因此所有动画都是专用类型的时间线。Timeline 定义时间段。您可以指定时间线的以下"计时行为":其 Duration 和重复次数,甚至可以为时间线指定时间走得多快。
因为动画是 Timeline,所以它还表示一个时间段。在动画的指定时间段(即 Duration)内运行动画时,动画会计算输出值。在运行或"播放"动画时,动画将更新与其关联的属性。
Duration、AutoReverse 和 RepeatBehavior 是三个常用的计时属性。
Duration 属性
时间线(以及继承自时间线的动画)表示一个时间段。该时间段的长度由时间线的 Duration 属性(通常用 TimeSpan 值指定)来决定。当时间线达到其持续时间的终点时,表示时间线完成了一次重复。
动画使用其 Duration 属性来确定其当前值。如果没有为动画指定 Duration 值,它将使用默认值(1 秒)。
下面的语法显示了 Duration 属性 (Property) 的 XAML 属性 (Attribute) 语法的简化版本。
小时 : 分钟 : 秒 |
下表显示了一些 Duration 设置及其结果值。
设置 |
所得值 |
---|---|
0:0:5.5 |
5.5 秒。 |
0:30:5.5 |
30 分 5.5 秒。 |
1:30:5.5 |
1 小时 30 分 5.5 秒。 |
AutoReverse 属性
AutoReverse 属性指定时间线在到达其 Duration 的终点后是否倒退。如果将此动画属性设置为 true,则动画在到达其 Duration 的终点后将倒退,即从其终止值向其起始值反向播放。默认情况下,该属性为 false。
RepeatBehavior 属性
RepeatBehavior 属性指定时间线的播放次数。默认情况下,时间线的重复次数为 1.0,即播放一次时间线,不进行重复。
前面几节描述动画的不同类型及其计时属性。本节演示如何对要进行动画处理的属性应用动画。Storyboard 对象提供了对属性应用动画的一种方法。Storyboard 是一个为其所包含的动画提供目标信息的容器时间线。
以对象和属性为目标
Storyboard 类提供 TargetName 和 TargetProperty 附加属性。通过在动画上设置这些属性,您将告诉动画对哪些内容进行动画处理。不过,在动画以对象作为处理目标之前,必须使用 x:Name 属性为该对象提供一个名称(如上例所示),否则必须间接以属性作为目标。下面的示例演示如何间接以属性作为目标。
Loaded="Start_Animation">
<StackPanel.Resources>
<Storyboard x:Name="colorStoryboard">
<!-- Animate the background color of the canvas from red to green
over 4 seconds. -->
<ColorAnimation BeginTime="00:00:00" Storyboard.TargetName="myStackPanel"
Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"
From="Red" To="Green" Duration="0:0:4" />
</Storyboard>
</StackPanel.Resources>
</StackPanel>
请注意,正在进行动画处理的属性值 (Color) 属于未命名甚至未显式声明的 SolidColorBrush 对象。此间接目标是使用下面的特殊语法完成的。
或者,可以显式创建 SolidColorBrush,对其进行命名,然后直接以其 Color 属性为目标。下面的示例演示如何创建与前面的示例相同的动画,但是使用直接属性目标。
<StackPanel.Resources>
<Storyboard x:Name="colorStoryboard">
<!-- Animate the background color of the canvas from red to green
over 4 seconds. -->
<ColorAnimation BeginTime="00:00:00" Storyboard.TargetName="mySolidColorBrush"
Storyboard.TargetProperty="Color" From="Red" To="Green" Duration="0:0:4" />
</Storyboard>
</StackPanel.Resources>
<StackPanel.Background>
<SolidColorBrush x:Name="mySolidColorBrush" Color="Red" />
</StackPanel.Background>
</StackPanel>
一些更有趣的动画(如旋转、扭曲和重新缩放对象)是通过对 Transform 对象的属性进行动画处理实现的。
下面的示例将 Storyboard 和 DoubleAnimation 与 RotateTransform 一起使用,以便使 Rectangle 旋转到位。
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:5"
RepeatBehavior="Forever" />
</Storyboard>
</StackPanel.Resources>
<Rectangle Width="50" Height="50" Fill="RoyalBlue"
MouseLeftButtonDown="StartAnimation">
<Rectangle.RenderTransform>
<RotateTransform x:Name="myTransform" Angle="45" CenterX="25" CenterY="25" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
FillBehavior 属性指定时间线结束时的行为方式。此属性的默认值为 HoldEnd,表示在动画结束后,进行动画处理的对象将保持其最终值。例如,如果对 Rectangle 的 Opacity 属性进行动画处理,使其在 2 秒内从 1 转换为 0,该矩形的默认行为是:在 2 秒后保持不透明度为 0 的状态。如果将 FillBehavior 设置为 Stop,该矩形的不透明度将在动画结束后还原为初始值 1。
缓动函数
通过缓动函数,您可以将自定义算术公式应用于动画。例如,您可能希望某一对象逼真地弹回或其行为像弹簧一样。您可以使用关键帧动画甚至 From/To/By 动画来大致模拟这些效果,但可能需要执行大量的工作,并且与使用算术公式相比动画的精确性将降低。
除了通过从 EasingFunctionBase 继承来创建您自己的自定义缓动函数外,您还可以使用运行时提供的若干缓动函数之一来创建常见效果。
-
BackEase:在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动。
-
BounceEase:创建弹回效果。
-
CircleEase:创建使用循环函数加速和/或减速的动画。
-
CubicEase:创建使用公式 f(t) = t3 加速和/或减速的动画。
-
ElasticEase:创建表示弹簧在停止前来回振荡的动画。
-
ExponentialEase:创建使用指数公式加速和/或减速的动画。
-
QuadraticEase:创建使用公式 f(t) = t2 加速和/或减速的动画。
-
QuarticEase:创建使用公式 f(t) = t4 加速和/或减速的动画。
-
QuinticEase:创建使用公式 f(t) = t5 加速和/或减速的动画。
-
SineEase:创建使用正弦公式加速和/或减速的动画。
可使用下面的示例查看这些缓动函数的行为。
若要将缓动函数应用于某一动画,请使用该动画的 EasingFunction 属性指定要应用于该动画的缓动函数。下面的示例将 BounceEase 缓动函数应用于 DoubleAnimation 以创建弹回效果。
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation From="30" To="200" Duration="00:00:3"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="Height">
<DoubleAnimation.EasingFunction>
<BounceEase Bounces="2" EasingMode="EaseOut"
Bounciness="2" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</StackPanel.Resources>
<Rectangle x:Name="myRectangle" MouseLeftButtonDown="Mouse_Clicked"
Fill="Blue" Width="200" Height="30" />
</StackPanel>
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="Height"
Storyboard.TargetName="myRectangle">
<!-- This keyframe animates the ellipse up to the crest
where it slows down and stops. -->
<EasingDoubleKeyFrame Value="30" KeyTime="00:00:02">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<!-- This keyframe animates the ellipse back down and makes
it bounce. -->
<EasingDoubleKeyFrame Value="200" KeyTime="00:00:06">
<EasingDoubleKeyFrame.EasingFunction>
<BounceEase Bounces="5" EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</StackPanel.Resources>
<Rectangle x:Name="myRectangle" MouseLeftButtonDown="Mouse_Clicked"
Fill="Blue" Width="200" Height="200" />
</StackPanel>
您可以使用 EasingMode 属性更改缓动函数的行为方式,也就是说,更改动画的内插方式。有三个可能的值可赋予 EasingMode:
下图演示了 EasingMode 的不同值,其中 f(x) 表示动画进度,t 表示时间。
说明:
您可以使用 PowerEase 创建与使用 Power 属性的 CubicEase、QuadraticEase、QuarticEase 和 QuinticEase 的相同的行为。例如,如果您要使用 PowerEase 来替换 CubicEase,则将 Power 的值指定为 3。
除了使用在运行时中包括的缓动函数外,您还可以通过从 EasingFunctionBase 继承来创建自己的自定义缓动函数。下面的示例演示如何创建简单的自定义缓动函数。您可以通过覆盖 EaseInCore 方法,针对缓动函数的行为方式添加您自己的数学逻辑。
xmlns:CustomEase="clr-namespace:CustomEasingFunction"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<StackPanel>
<TextBlock Margin="10" TextWrapping="Wrap">Click on the rectangle to start the animation</TextBlock>
<StackPanel x:Name="LayoutRoot" Background="White">
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation From="30" To="300" Duration="00:00:3"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="Height">
<DoubleAnimation.EasingFunction>
<!-- You get the EasingMode property for free on your custom
easing function.-->
<CustomEase:CustomSeventhPowerEasingFunction EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</StackPanel.Resources>
<Rectangle x:Name="myRectangle" MouseLeftButtonDown="Mouse_Clicked"
Fill="Blue" Width="200" Height="30" />
</StackPanel>
</StackPanel>