Metro 风格应用程序中快速而流畅的动画效果

快速而流畅的动画将为应用程序注入活力。在 Windows 8 Consumer Preview 中,您将发现动画已与用户体验完美融合,成为用户体验中不可或缺的一部分。当您登录 PC 时,“开始”菜单中的项目将呈现动画效果。当您启动沉浸式应用程序或缩放“开始”菜单时,流畅的动画将为使用体验增色不少。用户可从动画效果中了解某一特定操作的结果。这种视觉反馈将让用户对应用程序的响应程度充满信心。借助一个微妙的动画效果,即使用户只是添加或删除列表中的一个项目,其也将获得流畅、现代的用户体验,而且将在整个过程中获得丰富信息(您可观看Jensen Harris 在 //build/ 大会上的发言,直观了解动画效果,视频时长约为 25:00 分钟)。

该短片将展示流畅的动画效果可如何丰富 UI。

您的浏览器不支持 HTML5 视频。
请下载本视频,以在您常用的媒体播放器中观看:
高质量 MP4 |低质量 MP4

在 Windows 8 中,动画效果是 Metro 风格应用程序的一个重要特征,您也可在自己的应用程序中充分彰显这一特征!

以下是本篇博文的主要内容:

  1. 动画引擎之概述
  2. 动画库使用入门知识
  3. 自定义动画与如何利用动画引擎的改进
  4. 在 Metro 风格应用程序中融入动画的技巧与提示。

独立动画

Windows 8 用户体验中的一个重要内容便是流畅、无暇的动画效果,这一切都是通过名为“独立动画”的功能而得以实现。“独立动画”是指不依赖于运行核心 UI 逻辑的线程,而独立运行的动画。(而“从属动画”则在 UI 线程中运行。)在 Windows 8 中,许多动画元素是由运行于单独线程的组合引擎编制而成。引擎的工作将从 CPU 卸载至 GPU。将组合移至一个非 UI 线程意味着无法出现动画效果,或者说在 UI 线程中运行的应用程序(如 JavaScript 代码执行或同步操作)将阻止动画效果。GPU 现已得到优化,因而用户可查看视觉效果更为丰富的图形,并使用视频内存资源。使用 GPU 将大幅改善性能,并让动画效果在流畅而一致的帧率运行。

您不需要借助额外的标记即可让您的动画效果利用独立动画功能。系统将确定何时可独立编制动画效果。为了向您的应用程序添加出色、流畅的动画效果,您需要遵循开发中心中的独立动画指导原则。这些指导原则将在创建自定义动画时发挥最大功效,我们将在博文的稍后部分深入探讨这一话题。

现在,让我们来了解如何使用动画库中所提供的 Metro 风格动画来充实、加强您的应用程序。

动画库

动画库是专为利用平台的独立动画功能而构建的一整套 Metro 风格动画效果。这些动画效果将用于整个 Windows UI 之中,同时也可应用于您的 Metro 应用程序。您可将这个动画库理解成为您提供恰当服务的动画调色板,而且其设计效果已十分快速、流畅。

作为应用程序开发人员,我们非常喜爱这一功能,因为我们不需要花费时间创建拥有 Windows 8 外观的动画效果。我们只需要使用动画库,即可让应用程序为用户提供 Windows 使用体验。

这个库将为 Windows UI 自身提供动画效果。这些动画给人以洁净的视觉效果,而且意义重大。我们投入了大量精力来确保时间与动画曲线精准匹配,因此用户在与 Windows UI 交互时可获得快速而流畅的反馈。当您在应用程序中设计动画时,我们建议您首先从动画库中查找最符合您需求的动画效果。

无论您是使用 HTML 或是 XAML,动画库都将让您选用适当的动画效果,并确保您的 UI 将快速而流畅。接下来让我们一起来看几个示例。

JavaScript 示例

JavaScript/HTML 特征库是使用 CSS3 动画和切换构建而成。这些动画效果广泛应用于应用程序导航、内容切换和 Windows 8 控件之中。

EnterPage animation 是一个简单而引人入胜的动画效果。您可在首次显示内容或在运行的应用程序不同页面中切换时使用该动画效果。

该示例将向您展示如何在应用程序中使用这一简单 API。

HTML
<html>
   <body>
      <div id="input">
         Some content here
      div>
      <button onclick="runAnimation()", Run animation&lt;/button>
   body>
html>
CSS
<style>
   #input
   {
      background-color:blue;
   }
style>
JavaScript
XAML 示例

在 XAML 中,内置的动画库需要两个概念:主题切换与主题动画。

主题切换通常在加载、卸载或更改屏幕中内容位置时为屏幕中的视觉对象提供动画效果。XAML 布局系统将触发这些内置的动画效果,以响应页面布局的变更。

这些布局触发包括:

  1. 为页面或可视化树添加 UIElement。
  2. 从页面或可视化树中删除 UIElement。
  3. 对造成位置或尺寸需要更新的页面或可视化树中的现有 UIElement 的布局属性进行更新。

一个特定的主题切换可能将响应这些布局触发中的任意一项或全部。EntranceThemeTransition 将响应 1 号触发,并在 UIElements 添加至页面或可视化树时为其添加动画效果。在下一示例中,系统将使用EntranceThemeTransition 为所有网格的子段提供动画效果。

<Grid>
    <Grid.ChildrenTransitions>
        <TransitionCollection>
            <EntranceThemeTransition/>
        TransitionCollection>
    Grid.ChildrenTransitions>

    
Grid>

主题动画是通常在用户交互时所运行的内置动画,而且您必须触发运行它们。运行主题动画最简单的方式是在 Storyboard 类别中调用Begin 方法。如果您熟悉 VisualStateManager (VSM),那么您可将一个主题动画置于某一控件可视状态内。这一示例显示了如何使用 Begin 方法来触发主题动画:

XAML
<Grid Background="{StaticResource ApplicationPageBackgroundBrush}"> <Grid.Resources> <Storyboard x:Name="downAnimation"> <TapDownThemeAnimation TargetName="rectangle"/> Storyboard> <Storyboard x:Name="upAnimation"> <TapUpThemeAnimation TargetName="rectangle"/> Storyboard>
    Grid.Resources>
        
    <Rectangle x:Name="rectangle" 
                PointerPressed="Rectangle_PointerPressed" 
                PointerReleased="rectangle_PointerReleased"/>
Grid>
代码
private void Rectangle_PointerPressed(object sender, PointerEventArgs e)
{
    downAnimation.Begin();
}

private void rectangle_PointerReleased(object sender, PointerEventArgs e)
{
    upAnimation.Begin();
}

自定义动画

尽管自定义动画与动画库一样功能强大,但是它并不能涵盖您的所有应用场景。在这些情形中,您可构建您的自定义动画,其中系统将独立运行(参阅动画内容,查看构建您自己的动画的设计准则)。此处需要您特别的注意,方可确保构建出的动画最终不会在 UI 线程上运行。

您仍可在应用程序中使用从属动画。我们建议您在自定义动画设计过程中遵循独立动画的指导原则,但是如果您的应用场景需要无法以独立模式启动的动画效果,那么该动画效果仍可以从属模式运行。

此处列举的示例展现了动画库之外的 3D 非仿射独立动画的使用情况。

JavaScript

对于 JavaScript 应用程序,您可通过 CSS3 动画和切换句法而为自定义动画访问独立动画功能。这些句法均为新引入 IE10 中 Microsoft Web 平台的句法。独立动画仅可支持无需重新布局或重新渲染的属性。也就是说,面向 JavaScript 应用程序的独立动画仅适用于、且仅可支持以 CSS3 2D 和 3D变形或非透明性为目标的 CSS 动画/切换。其他 CSS 属性的动画将在 UI 线程中以从属模式运行。

HTML 自定义动画的示例

此处所展示的示例将显示一个简单的 CSS 3D 翻转。

HTML
<html> <head> <title>Html animations CSS3title>
   head>
   <body>
      <div id="parent">
         <div id="box" onclick="className='move'" >Click me for CSS Change!div>
      div>
   body>
html>
CSS
<style>
   body
   { 
      background-color:gray; 
   }
   #box
   {
      position: relative;        
      background-color:green;
      width:300px;
      height:300px
   }
   
   #box.move
   {
      -ms-transition-property: -ms-transform;
      -ms-transition-duration: 1s;
      -ms-transition-timing-function: ease-in;    
      -ms-transform: rotateY(-180deg);
      -ms-transform-origin: 50% 50%;    
   }

   #parent{-ms-perspective: 600px;}
style>
XAML

对于 XAML 应用程序而言,一个特定属性子集将独立受到支持(详情请访问 Windows 8 开发中心)。这些属性包括 Canvas 定位、非透明性、渲染变换、投影、剪辑和颜色。

为任意属性(包括我们刚刚查看过的列表)提供动画效果都将产生从属动画。这意味着动画将在 UI 线程上运行,因此有可能发生故障。为了鼓励开发人员开发快速而流畅的 UI,XAML 应仅运行独立动画,除非您可明确启用从属动画。如果您希望运行从属动画,那么您可在时间线中使用EnableDependentAnimation 属性。此外,您可将一个全局静态 AllowDependentAnimations 属性设为 false,以禁用应用程序中所有从属动画。

XAML 自定义动画的示例

下一示例将展示如何为系统独立运行的 PlaneProjection 属性提供动画效果。其动画概念和句法与其他 XAML 技术如出一辙,但是它们在 Windows 8 中得到了强化,因而可独立运行,且改善了应用程序的性能特征。

<Grid> <Grid.Resources> <Storyboard x:Name="customAnimation"> <DoubleAnimation Storyboard.TargetProperty="RotationY" Storyboard.TargetName="projection" Duration="0:0:1" To="-180" /> Storyboard>
    Grid.Resources>
        
    <Grid Background="Red" Height="400" Width="600" PointerPressed="Grid_PointerPressed">
        <Grid.Projection>
            <PlaneProjection x:Name="projection"/>
        Grid.Projection>

        

    Grid>
Grid>
 
private void Grid_PointerPressed(object sender, PointerEventArgs e)
{
    customAnimation.Begin();
}

独立动画的最佳做法

和所有系统一样,独立动画也面临着许多限制条件。这些限制条件与 HTML 和 XAML 平台有所不同。总的来说,除了以下情形,您在其他所有情形中都可以使用独立动画:

  1. 将影响布局的动画属性:这些属性(如 CSS 宽度)将触发重新布局,而且无法独立获得支持。
  2. 动画元素状态无法遵循独立动画的指导原则:系统将不支持未遵循指导原则的独立动画(请参阅动画发布)。
  3. 系统资源不足:如果系统资源(如视频内存)不足,那么动画将回滚至从属组合。

以下列出了独立动画的一些指导原则。

JavaScript
  1. 避免使用无限动画:当使用独立动画时,GPU 将分配视频内存。而在 CSS 中,GPU 将无法指定–ms-iteration-count: infinite。当您设置属性值时,指定的动画将继续运行。也就是说您的应用程序保留动画元素的视频内存,直至您停止动画。要停止无限动画,您可删除–ms-animation-name值或将动画元素的显示属性更改成 display: none
  2. 请勿切换 CSS 可见性属性:当您将独立动画原色设置为 visibility: hidden ,然后又重新设置为 visibility: visible 时,该元素将不再是独立元素。而该动画效果将继续,但是其将在 UI 线程中编制。
  3. 在顶部放置独立动画元素:由于独立组合将使用您的 GPU,因此您的系统可独立编制内容的数量将受到限制。如果您的独立动画在其他 UI 元素后方,那么这些位于顶部的 UI 元素将被独立编制。这样一来,您将消耗许多不必要的视频内存。为了避免这一问题,请确保将所有独立动画放置于其他所有 UI 元素的顶部。如果您的独立动画处于堆栈中较低位置,那么其将面临回滚至从属动画的风险。

    您可通过以下方式将您的独立动画放置于顶部:

    • 为独立动画元素提供较高的 Z-索引。
    • 为独立动画元素使用非负 Z-索引。
    • 避免独立动画与其他元素重叠。
  4. 请勿使用过大图面和过多独立动画:与将您的独立动画放置于顶部类似,请注意您动画元素的尺寸,以及一次动画效果的数量。独立动画将受到系统 GPU 的限制。如果您突破了这一限制,那么您的动画将回滚至从属 UI 线程。如果您��觉动画效果不够流畅,那么您可使用IsIndependentlyComposed API 来查询元素。
  5. 使用 IsIndependentlyComposed API:您可使用该 API 来确定 HTML 元素是否独立于 UI 线程编制而成。该属性将为独立动画元素、子滚动条、覆盖的元素、以及独立动画元素返回 true 值。
XAML
  1. 为 Height 和 Width 动画缩放元素:为 UIElement Height 和/或 Width 属性添加动画效果将形成从属动画,这是因为这些属性需要布局变更,而布局变更仅可在 UI 线程上完成。为了获得动画HeightWidth 的类似效果,您可为控件的缩放设置动画效果。ScaleTransform 将独立获得动画效果,该方法将提供更加的帧率。
  2. 请勿为缓存内容添加动画效果:如果您将某一元素的 CacheMode 属性 (UIElement.CacheMode) 设置为BitmapCache,那么可视化子树中的所有动画效果将以从属模式运行。这是因为我们需要在每一帧中重新创建整个缓存。该解决方案将完全不会为缓存内容添加动画效果。
  3. 请勿使用 Progress 控件的无限动画:ProgressRingProgressBar 拥有无限动画,这些动画将继续运行,即使页面中并未显示控件,这有可能阻止 CPU 进入低功耗或空闲模式。我们建议您在不显示ProgressRing.IsActiveProgressBar.IsIndeterminate 控件的时候,将其各自属性设置为 false。

总结

在 Windows 8 应用程序中,独立动画为用户提供了快速而流畅的使用体验,对此我们感到兴奋不已。我们希望您在为 Windows 8 的 Metro 风格应用程序创建引人入胜的用户体验时,动画库以及我们对独立于 UI 线程运行的自定义动画所提供的支持对你有所帮助。

-- Angelina Gambo 和 Hamid Mahmood
Windows 项目经理

你可能感兴趣的:(Metro 风格应用程序中快速而流畅的动画效果)