01 、Windows 应用商店动画
MSDN Silverlight 示例: http://samples.msdn.microsoft.com/Silverlight/SampleBrowser/index.htm
并非你创建的所有自定义动画都会默认运行(可能对你的应用有性能影响的动画称为从属动画)。如果你的动画导致布局更改或可能影响性能,则需要在代码中明确启用该动画。
在应用中添加一点动画效果,可能会对用户体验有显著的提升。在 win8 中的一些控件自动带有动画效果,比如 GridView、FlipView、ProgressRing、ToolTip 等等。
1、过渡动画
1) 在 win8 的 api 中提供了一些淡入淡出的动画过渡。
例如:按钮轻快地滑入视图,在此代码中,我们将 EntranceThemeTransition 对象添加到按钮的过渡集中。可以在动画对象上设置一些属性,以调节它滑动的距离以及从什么方向滑动。
<Button Content="过渡按钮"> <Button.Transitions> <TransitionCollection> <EntranceThemeTransition/> </TransitionCollection> </Button.Transitions> </Button>
或者把它定义成样式,供其它按钮使用:
<Style x:Key="DefaultButtonStyle" TargetType="Button"> <Setter Property="Transitions"> <Setter.Value> <TransitionCollection> <EntranceThemeTransition/> </TransitionCollection> </Setter.Value> </Setter> </Style>
在 ItemsControl 中使用 EntranceThemeTransition, 这样,容器的所有子对象都会参与过渡:
<!-- 子元素自动出现动画效果 --> <ItemsControl Grid.Row="1" x:Name="rectangleItems"> <ItemsControl.ItemContainerTransitions> <TransitionCollection> <!-- 应用 entrance 主题动画 --> <EntranceThemeTransition/> </TransitionCollection> </ItemsControl.ItemContainerTransitions> <!--设置容器的模板为 WrapGrid 控件,宽度 400 像素--> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapGrid Height="400"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.Items> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> </ItemsControl.Items> </ItemsControl>
2)使用 RepositionThemeTransition 主题动画,当容器的一个或多个子对象更改位置时,也可以重新流动。
<Button Content="Remove Rectangle" Click="RemoveButton_Click"/> <ItemsControl Grid.Row="1" x:Name="rectangleItems"> <ItemsControl.ItemContainerTransitions> <TransitionCollection> <!-- 添加 RepositionThemeTransition ,当删除项时,会有动画效果--> <RepositionThemeTransition/> </TransitionCollection> </ItemsControl.ItemContainerTransitions> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapGrid Height="400"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.Items> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> <Rectangle Fill="Red" Width="100" Height="100" Margin="10"/> </ItemsControl.Items> </ItemsControl>
相应的 C# 代码:
private void RemoveButton_Click(object sender, RoutedEventArgs e) { if (rectangleItems.Items.Count > 0) { rectangleItems.Items.RemoveAt(0); } }
3)将多个过渡动画运用到单个对象或对象容器,例如,同时运用 RepositionThemeTransition 和 EntranceThemeTransition:
<ItemsControl.ItemContainerTransitions> <TransitionCollection> <EntranceThemeTransition/> <RepositionThemeTransition/> </TransitionCollection> </ItemsControl.ItemContainerTransitions>
4)有多重过渡动画可以运用到 UI 元素上, 这些 API 的名称都包含“ThemeTransition” :
API | 描述 |
---|---|
AddDeleteThemeTransition | 为控件添加或删除子对象或内容的情形提供动画的过渡表现方式。通常,控件是项目容器。 |
ContentThemeTransition | 为控件的内容更改时的情形提供动画的过渡表现方式。可以在应用 AddDeleteThemeTransition 后再应用它。 |
EntranceThemeTransition | 为控件第一次显示的情形提供动画的过渡表现方式。 |
ReorderThemeTransition | 为列表-视图控件项目更改顺序的情形提供动画的过渡表现方式。通常它作为拖放操作的结果出现。不同的控件和主题可能具有不同的动画特征。 |
RepositionThemeTransition | 为控件更改位置的情形提供动画的过渡表现方式。 |
2、主题动画
你可能想要对动画效果的计时和顺序进行稍多的控制, 同时对动画的表现方式仍使用一致的 Windows 主题。
例如,使用 FadeOutThemeAnimation 将一个矩形淡出视图 :
<StackPanel> <StackPanel.Resources> <Storyboard x:Name="myStoryboard"> <FadeOutThemeAnimation Storyboard.TargetName="myRectangle" /> </Storyboard> </StackPanel.Resources> <Rectangle PointerPressed="Rectangle_Tapped" x:Name="myRectangle" Fill="Blue" Width="200" Height="300" /> </StackPanel>
//当用户点击该矩形时,动画开始执行 private void Rectangle_Tapped(object sender, PointerRoutedEventArgs e) { myStoryboard.Begin(); }
你必须使用 Storyboard 来包含动画,而且必须使用事件处理程序来启动 Storyboard。你可以使用 Begin、Stop、Pause 以及 Resume Storyboard 方法来分别执行开始、停止、暂停以及恢复 Storyboard 动画。还可以更改动画的默认表现方式。例如,你可以通过增加 FadeOutThemeAnimation 上的 Duration 来放缓淡出。
你可以为 UI 元素应用对个主题动画。API 中的 ThemeAnimation :
API | 描述 |
---|---|
DropTargetItemThemeAnimation | 应用到潜在的拖放目标元素的预配置动画。 |
FadeInThemeAnimation | 控件第一次出现时应用到控件的预配置不透明度动画。 |
FadeOutThemeAnimation | 控件从 UI 中删除或隐藏时应用到控件的预配置不透明度动画。 |
PopInThemeAnimation | 控件的弹入组件显示时应用到它们的预配置动画。此动画结合了不透明度和转换。 |
PopOutThemeAnimation | 控件的弹入组件关闭或删除时应用到它们的预配置动画。此动画结合了不透明度和转换。 |
RepositionThemeAnimation | 对象重新放置时应用的预配置动画。 |
SplitCloseThemeAnimation | 使用拆分动画显示目标 UI 的预配置动画。 |
PointerDownThemeAnimation | 用于用户点击或单击项目或元素操作的预配置动画。 |
PointerUpThemeAnimation | 在点击一个项目或元素后(指针不再悬停在上面)运行的用户操作预配置动画。 |
SplitOpenThemeAnimation | 使用拆分动画显示目标 UI 的预配置动画。 |
3、创建你自己的动画:
为了创建动画,要动画显示的属性必须是“依赖属性”。依赖属性是 Windows 运行时 XAML 实现的关键特征。大多数
常见 UI 元素的可写属性通常为依赖属性。依赖属性概述。
示例中,为 Opacity 属性创建了动画:
<StackPanel> <StackPanel.Resources> <!-- Animates the rectangle's opacity. --> <Storyboard x:Name="myStoryboard"> <DoubleAnimation Storyboard.TargetName="MyAnimatedRectangle" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:1" AutoReverse="True" /> </Storyboard> </StackPanel.Resources> <Rectangle PointerPressed="Rectangle_Tapped" x:Name="MyAnimatedRectangle" Width="300" Height="200" Fill="Blue" /> </StackPanel>
相应的 C# :
private void Rectangle_Tapped(object sender, PointerRoutedEventArgs e) { myStoryboard.Begin(); }
此动画与前面所示的使用 FadeOutThemeAnimation的淡出动画示例类似。你可以自己重复所有主题动画的动画表现方式。但最好在适当的位置使用主题动画,原因是:
-
预打包的主题和过渡动画使用较少的代码来实现。
-
它们比自定义的动画执行得更好。
-
它们的设计与 UI 设计指南保持一致。
有关如何使用属性的间接目标的属性路径来实现动画的详细信息,请参阅 属性路径语法或 Storyboard.TargetProperty。
4、启动动画
并非所有自定义动画都会默认运行。可能对你的应用有性能影响的动画(尤其是布局效果动画)称为关联动画,你必须在运行前启用。若要启用你的动画,请在动画对象上将 EnableDependentAnimation
设置为 True
。下个示例演示了如何使用此属性。此示例还演示了除了双精度类型值外,如何使其他属性值类型实现动画,如一个点如何开始、暂停、停止和恢复动画。
<Canvas> <Canvas.Resources> <Storyboard x:Name="myStoryboard"> <!-- 操作这个椭圆的中心坐标 --> <PointAnimation EnableDependentAnimation="True" Storyboard.TargetProperty="Center" Storyboard.TargetName="MyAnimatedEllipseGeometry" Duration="0:0:5" From="20,200" To="400,100" RepeatBehavior="Forever" /> </Storyboard> </Canvas.Resources> <Path Fill="Blue"> <Path.Data> <!-- 显示一个椭圆. --> <EllipseGeometry x:Name="MyAnimatedEllipseGeometry" Center="20,20" RadiusX="15" RadiusY="15" /> </Path.Data> </Path> <StackPanel Orientation="Horizontal" Canvas.Left="10" Canvas.Top="265"> <!-- 动画开始按钮. --> <Button Click="Animation_Begin" Width="65" Height="30" Margin="2" Content="Begin" /> <!-- 动画暂停按钮. --> <Button Click="Animation_Pause" Width="65" Height="30" Margin="2" Content="Pause" /> <!-- 动画恢复按钮. --> <Button Click="Animation_Resume" Width="65" Height="30" Margin="2" Content="Resume" /> <!--动画停止按钮,椭圆回到开始的位置 --> <Button Click="Animation_Stop" Width="65" Height="30" Margin="2" Content="Stop" /> </StackPanel> </Canvas>
相应的 C# :
private void Animation_Begin(object sender, RoutedEventArgs e) { myStoryboard.Begin(); } private void Animation_Pause(object sender, RoutedEventArgs e) { myStoryboard.Pause(); } private void Animation_Resume(object sender, RoutedEventArgs e) { myStoryboard.Resume(); } private void Animation_Stop(object sender, RoutedEventArgs e) { myStoryboard.Stop(); }
5、使用关键帧动画创建动画
上面我们演示了两个值之间创建的自定义动画 (from/to/by) 。关键帧动画使你可以使用两个以上的目标值并控制动画的
插入方法。通过指定多个值来创建动画,你可以作出更复杂的动画。通过指定动画的插入,特别是通过使用 KeySpline 属性,你可以控制动画的加速。
例: 使用关键帧动画来创建矩形高度的动画
<StackPanel> <StackPanel.Resources> <Storyboard x:Name="myStoryboard"> <DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetName="myRectangle" Storyboard.TargetProperty="Height"> <LinearDoubleKeyFrame Value="30" KeyTime="0:0:0" /> <!--样条动画 ( Spline animations )是用来创建加速度。这个 SplineDoubleKeyFrame 创建一个动画,一开始减缓 然后加速。 这个矩形像是掉下来--> <SplineDoubleKeyFrame KeySpline="0,0 1,0" Value="300" KeyTime="0:0:0.8" /> <!-- 这样条动画创建“反弹”效果,在结束时矩形缩短其长度,然后迅速减缓和停止。 --> <SplineDoubleKeyFrame KeySpline="0.10, 0.21 0.00, 1.0" Value="250" KeyTime="0:0:1.5" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </StackPanel.Resources> <Rectangle x:Name="myRectangle" PointerPressed="Rectangle_Tapped" Fill="Blue" Width="200" Height="30" /> </StackPanel>
相应的 C# :
private void Rectangle_Tapped(object sender, PointerRoutedEventArgs e) { myStoryboard.Begin(); }
XAML 包括 3 个关键帧。每个关键帧指定一个值在某个时间点实现动画。整个动画持续 1.5 秒。
- LinearDoubleKeyFrame。LinearTypeKeyFrame 对象(如 LinearDoubleKeyFrame)在值之间创建一个平滑线性的过渡。但在此示例中,我们只使用它来指定在值 30 时间 0 处实现动画。
- SplineDoubleKeyFrame 指定在动画开始后,矩形的高度在时间 0.8 秒处为 300。SplineTypeKeyFrame 对象,按照 KeySpline 属性的值,如 SplineDoubleKeyFrame 在值之间创建了可变的过渡。在此示例中,矩形开始移动很缓慢,然后加速朝时间段终点移动。
- SplineDoubleKeyFrame 指定在动画开始后,矩形的高度在时间 1.5 秒处为 250,它是在最后的 SplineDoubleKeyFrame 结束后的 0.7 秒。与最后的 SplineDoubleKeyFrame不同,此关键帧使动画快速开始,然后在快到达终点时逐渐慢下来。
KeySpline 使用的最奇妙的属性可能就是 SplineDoubleKeyFrame 属性。此属性指定贝塞尔曲线的第一个控制点和第二个控制点,描述动画的加速。
6、缓动函数
缓动动画支持你将自定义数学公式应用到动画。例如,你可能想对某个对象以理想的方式像弹簧一样弹跳。你可以
使用 关键帧 from/to/by 模拟这些效果但是工作量大,而且动画比起使用数学公式准确性要低。
缓动函数列表:
- BackEase:动画开始在指定路径上运动前稍微收缩动画的运行。
- BounceEase:创建回弹效果。
- CircleEase:使用圆函数创建加速或减速的动画。
- CubicEase:使用函数 f(t) = t3 创建加速或减速的动画。
- ElasticEase:创建一个动画,模拟弹簧的来回振荡运动,直到它达到停止状态。
- ExponentialEase:使用指数公式创建加速或减速的动画。
- PowerEase:使用公式 f(t) = tp 创建加速或减速的动画,其中 p 等于幂属性。
- QuadraticEase:使用函数 f(t) = t2 创建加速或减速的动画。
- QuarticEase:使用函数 f(t) = t4 创建加速或减速的动画。
- QuinticEase:使用函数 f(t) = t5 创建加速或减速的动画。
- SineEase:使用正弦公式创建加速或减速的动画。
你可以使用此 Silverilght 示例试验不同的缓动函数。
此示例为 DoubleAnimation 应用了一个 BounceEase 缓动函数以创建回弹效果:
<StackPanel x:Name="LayoutRoot" Background="White"> <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>
private void Mouse_Clicked(object sender, MouseEventArgs e) { myStoryboard.Begin(); }
在前面的示例中,我们对从/到/按照动画应用了缓动函数。你也可以使用 EasingDoubleKeyFrame、EasingPointKeyFrame 或 EasingColorKeyFrame 将这些缓动函数应用到关键帧动画 下一个示例展示了如何使用带有缓动函数的关键帧来创建矩形动画,此动画向上压缩,降速,然后向下延伸(好像降落一样),然后回弹,直到停止。若要尝试此示例,请单击矩形查看效果。
<StackPanel x:Name="LayoutRoot" Background="White"> <StackPanel.Resources> <Storyboard x:Name="myStoryboard"> <DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" 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" PointerPressed="Rectangle_Tapped" Fill="Blue" Width="200" Height="200" /> </StackPanel>
相应的 C# :
private void Rectangle_Tapped(object sender, PointerRoutedEventArgs e) { myStoryboard.Begin(); }
7、创建 XAML 附加属性的动画
这不是一个常见情形,但你可以将动画值应用到 XAML 附加属性。有关哪些附加属性及其工作原理的详细信息,请参阅附加属性概述。确定附加属性目标需要括号中包含属性名的属性路径语法。你可以通过使用应用不连续整数值的 ObjectAnimationUsingKeyFrames 创建内置附加属性的动画,如 Canvas.ZIndex。不过,Windows 运行时 XAML 实现的现有局限性是无法创建自定义附加属性的动画。