示例性操作环境
图1示出了在其上可实现动画间平滑过渡的一合适的计算系统环境100的示例。计算系统环境100只是一合适的计算环境的一例,而不是要提出对本发明使用范围或功能性进行任何限制。计算环境100也不应解释成对于在示范操作环境100中所示出的任一组件或其组合有任何依赖或要求。
本发明是可用多个其它通用或专用计算系统环境或配置运行的。可以适用于该本发明的公知的计算系统、环境、和/或配置的示例包括,但不局限于,个人计算机、服务器计算机、手持设备或膝上型设备、写字板设备、多处理器系统、基于微处理器的系统、机顶盒、可编程消费者电子设备、网络PC、小型机、大型计算机、包括任何诸如以上系统或设备等的分布式计算环境等。
本发明可以在正由计算机执行的诸如程序模块的计算机可执行指令的一般上下文中被描述。一般地,程序模块包括完成特殊任务或执行特殊抽象数据类型的例行程序、程序、对象、组件、数据结构等。本发明也可以在分布的计算环境中实践,在此由通过通信网络而链接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以定位于包括记忆体储存设备的本地和远程计算机存储介质。
参见图1,对于实现本发明的示范的系统包括一以计算机110形式出现的通用计算设备。计算机110的组件包括,但不局限于,处理单元120、系统存储器130、以及将包括该系统存储器在内的各种系统组件耦合至处理单元120的系统总线121。上述系统总线121可以是几种总线结构类型中的任何一种,包括存储总线或存储控制器、外围总线和使用各种总线体系结构的任一种的局域总线。举例来说,而非限制,此类体系结构包括工业标准体系结构(ISA)总线、微通道体系结构(MCA)总线、增强型ISA(EISA)总线、视频电子标准技术协会(VESA)局域总线、加速图形端口(AGP)总线和也被称为Mezzanine总线的外围部件互连(PCI)总线。
计算机110通常包括各种计算机可读介质。计算机可读介质可以是任何计算机110能够访问的可用介质,包括易失性的和非易失性的介质、可移动的和不可移动的介质。举例来说,而非限制,计算机可读介质可以包含计算机存储介质和通信介质。计算机存储介质包括能以任何方法或技术实现的易失性的和非易失性的、可移动的和不可移动的介质,用于存储诸如计算机可读指令、数据结构、程序模块或其它数据等信息。计算机存储介质包括,但不局限于,RAM、ROM、EEPROM、闪存或其它存储技术,CD-ROM、数字化多功能光盘(DVD)或其它光盘存储、盒式磁带、磁带、磁盘存储器或其它磁存储设备,或任何其它可以被用来存储想要的信息并且可以被计算机110访问的介质。通信介质通常具体体现为诸如载波或其它传送机制的已调制数据信号中的计算机可读指令、数据结构、程序模块或其它数据,也包括任何信息传递介质。术语“已调制数据信号”是指在该信号中以编码信息的方式来设置或改变其一个或多个特征的信号。举例来说,而非限制,通信介质包括诸如有线网或直线连接的有线介质,和诸如声音、射频、红外线和其它无线介质的无线介质。任何以上所述的组合也应该包括在计算机可读介质的范围之内。
系统存储器130包括以诸如只读存储器(ROM)131和随机存取存储器(RAM)132的易失性和/或非易失性存储器的形式的计算机存储介质。包含如在启动期间帮助在计算机110内各元件之间传送信息的基本例行程序的基本输入/输出系统133(BIOS),通常存储在ROM 131中。RAM 132通常包含可以被处理单元120立即访问和/或当前操作的数据和/或程序模块。作为示例而非限制,图1示出了操作系统134、应用程序135、其它程序模块136和程序数据137。
计算机110还可以包括其它可移动/不可移动、易失性/非易失性的计算机存储介质。仅作为示例,图1示出了从不可移动、非易失性磁性介质读出或写入不可移动、非易失性磁性介质的硬盘驱动器141、从可移动、非易失性磁盘152读出或写入可移动、非易失性磁盘152的磁盘驱动器151、以及从诸如CD ROM或其它光学介质的可移动、非易失性光盘156读出或写入可移动、非易失性光盘156的光盘驱动器155。其它可以使用在示例的操作环境中的可移动/不可移动、易失性/非易失性计算机存储介质包括,但不局限于,盒式磁带、闪存卡、数字多功能光盘、数字录像带、固态RAM、固态ROM等。硬盘驱动器141通常通过诸如接口140的不可移动存储接口连接到系统总线121,磁盘驱动器151和光盘驱动器155通常通过诸如接口150的可移动存储接口连接到系统总线121。
以上讨论并且在图1中示出的驱动器及它们相关的计算机存储介质为计算机110提供了计算机可读指令、数据结构、程序模块和其它数据的存储。在图1中,例如,示出硬盘驱动器141存储操作系统144、应用程序145、其它程序模块146、和程序数据147。需要注意的是这些组件可以和操作系统134、应用程序135、其它程序模块136和程序数据137相同,也可以和它们不同。在此对操作系统144、应用程序145、其它程序模块146和程序数据147给出了不同的标号来说明至少它们是不同的副本。用户可以通过诸如写字板(电子数字转换器)164、麦克风163、键盘162和定位设备161的输入设备把指令和信息输入到计算机110中,定位设备161通常指如鼠标、跟踪球或触摸板。其它输入设备(图1中未示)可以包括操纵杆、游戏垫、圆盘式卫星天线、扫描仪等等。这些和其它输入设备通常由用户输入接口160连接到处理单元120,上述输入接口160和系统总线121相耦合。但是上述和其它输入设备也可以由其它接口和总线结构连接到处理单元120,诸如,并行端口、游戏端口或通用串行总线(USB)。监视器191或其它类型显示设备也可以通过诸如视频接口190的接口连接到系统总线121。监视器191也可以和触摸屏面板193等集成在一起。该触摸屏面板193等可以经由接口(例如触摸屏接口192)将诸如手写笔迹的数字化输入到计算机系统110。需要注意的是监视器和/或触摸屏画板可以物理地耦合到包含了计算机110,诸如写字板式个人计算机的一外壳,其中触摸屏面板193实质上用为写字板164。另外,计算机(例如,计算设备110)也包括其它外围输出设备,诸如可以是通过一输出外围设备接口194等连接的扬声器195和打印机196。
计算机110可以在网络化的环境中运行,该环境使用与诸如远程计算机180的一台或多台远程计算机的逻辑连接。远程计算机180可以是个人计算机、服务器、路由器、网络个人计算机、对等设备或其它公共网络节点,通常包括以上描述的和计算机110相关的多个或全部元件,尽管在图1中只示出了记忆存储设备181。在图1中描绘的逻辑连接包括局域网(LAN)171和广域网(WAN)173,但是也可以包括其它网络。这样的网络环境在办公室、企业范围的计算机网络、内联网和因特网中是普遍的。
当在LAN网络环境中使用时,计算机110通过网络接口或适配器170连接到LAN 171。当在WAN网络环境中使用时,计算机110通常包括调制解调器172或通过诸如因特网的WAN 173建立通信的其他装置。调制解调器172可以是内置的或外置的,可以通过用户输入接口160或其它适当的机制连接到系统总线121。在一网络化的环境中,所描述的和计算机110相关的程序模块或其中的各个部分可以存储在远程记忆体存储设备内。举例说明,但非限制,图1示出了驻留在存储设备181上的远程应用程序185。可以理解的是所示的网络连接是示例的,也可以使用在计算机间建立通信链路的其他装置。
示例性架构
一方面一般涉及在计算机系统上提供平滑、复杂的动画和/或媒体。为此,如图2中所一般表现的,提供媒体整合架构200。应用程序、控制或其它类似的较高级程序代码(例如,操作系统组件的用户接口)202通过一组应用编程接口(API)204等访问媒体整合层架构200以访问(读或写)图形信息。需要注意的是虽然在此描述的例子中的多个例子涉及与API连接的应用程序,但可以理解的是其它较高级程序代码和组件(例如,操作系统的用户接口)也可用以与在此描述的较低级组件相连接。如此,任何涉及对这样的较高级程序代码的引用,不管是否涉及应用程序、用户接口等,都应该被同等考虑。
在一实现中,媒体整合架构200包括高级合成和动画引擎206、定时和动画组件208、以及低级合成和动画引擎210。如在此使用的,术语“高级”和“低级”类似于那些在其它计算情况中使用的,其中一般地,相对于较高级组件而言越低级的软件组件是越靠近硬件的组件。如此,例如,发送自高级合成和动画引擎206的图形信息可在低级合成和动画引擎210处被接收,在210处信息被用以发送图形数据至包括硬件的图形子系统。
一般地,高级合成和动画引擎(在此也称为高级合成器和动画播放器或高级引擎或组件)206构建显示元素树以表现由应用程序202提供的图形场景,而定时和动画组件提供说明性的(或其它)动画和定时控制。低级合成和动画引擎(在此也称为低级合成器和动画播放器或低级引擎或组件)210组成用以多个应用场景的再现,并利用再现组件来实现对于屏幕真实的图形再现。注意,在较高层上依然可能做消耗时间的或特定应用的再现,并发送涉及位图等至较低层。
高级合成和动画引擎206构建元素树结构并遍历该结构,创建被发送至低级合成和动画引擎210的再现指令和简单动画时间间隔。由高级合成器生成的再现指令可包括定时和动画信息。低级合成和动画引擎210采用再现指令和动画时间间隔并管理以后提供给图形子系统(举例来说,图形软件和硬件)212的场景的动画播放、再现和合成。除了本地显示的输出以外,高级合成和动画引擎206(或此外一类似的)可以合适的格式提供再现和动画指令给较低级打印代码220以发送固定的图形数据至打印机222等,和/或可以合适的格式提供再现指令和简单动画时间间隔给较低级终端传送服务器226以传送至远程机器228。注意大量的信息也可通过网络发送,举例来说,在没有任何网络流通量的情况下,让远程机器本地处理鼠标滚动影响是理想的。
在该实现中,媒体整合架构200把图形处理分割成多级,并且这些级中的每级执行某些智能图形处理,这些处理一起允许应用程序的用户接口202等输出具有平滑动画的图形、用其它应用图形合成这些图形、以及与视频帧一起工作。动画和/或合成也可和音频输出同步。例如,通过同步音频与在低级组件上的帧速率,音频的定时实质上可与视频或图形的定时一致,并且不依赖于任务调度、复杂预处理的能力以保持刷新速率。
图3表示了在其中诸如基于XAML的代码的标记代码302可由语法分析器/翻译器304解释的一个实现。一般地,语法分析器/翻译器304添加元素至元素树/属性系统314;元素是实行自己布局的可视对象。此外,注意标记代码的某些或所有可被按需编译而不是解释,从而提高效率。
一般地,元素是在参与属性系统、触发和布局/表现系统的元素层内的对象。语法分析器304查找标记并且确定是否那些标记帮助定义元素或资源对象。在VisualBrush的特殊情况中,例如,相同的标记可被解释成元素或也被解释成资源对象,这取决于那些标记出现地方的上下文,例如,如在美国专利申请序号为10/401,717中描述的那样,取决于是否在复杂属性句法中出现。
除了在标记内的内联表现以外,资源实例也可定位在其它任何位置(例如,在标记内或文件内,该文件可以是在本地或在远程网络上并能适当地下载),并能由名称所引用,(例如,文本名称、引用或其它合适的标识符)。通过这种方式,场景设计者可在整个场景内重用元素树中的元素,包括由复杂属性句法描述的元素。正如以下将详述的那样,资源可以包括故事板,以允许各故事板的重新使用。
语法分析器304按需通过访问类型转换器308来处理在复杂属性句法内的标记,并且也通过把特定的参数与对象属性匹配来处理在复杂属性句法内的标记,从而为场景设计者处理复杂性。如此,语法分析器304不仅仅建立对象,也设置对象上的属性。由于相同的再现模型在元素级和API级之间共享,对象中的多个对象实质上是相同的。这使得语法分析/翻译具有高效率,并且也允许不同类型的编程语言(例如,类似C#等语言)可容易地从标记转换成自己的句法,并且反之亦然。注意的是如图3中所表现的,另一个这样的编程语言310(可包括编译过的标记)能添加元素至元素树314,或能直接与可视API层316连接。
还如图3中所表现的,相同的标记302可被用以在元素级和资源级编程。一般地,元素级给场景设计者全部的可编程性、提供继承的属性系统的使用(例如,如特征的式样表)、以及触发(例如,由此元素可具有附加的代码以响应用户输入事件或动作来更改它的外观、位置等)。然而,各实施例还提供资源层机制,场景设计者实质上可由此简化元素树以及直接对可视API层编程。对于不需要元素级特征的许多类型的静态形状、图形等,这提供一种更有效率和轻便的方式输出适当的对象。
为了控制动画和媒体输出,如以下参照图4和图5描述的那样,包括时钟的定时树也被维持。一般地,高级合成器和动画引擎206执行复杂处理(有时指编译),该复杂处理大大简化处理量并且大大减少较低级需要处理的数据量以再现正确的输出。然而,需要的注意的是,由较高级执行的处理的数量和类型在很大程度上可取决于较低级的装载、配置和能力。例如,如果高能力图形硬件存在,较高级可进行较少数量的处理,反之亦然。高级和低级层被自适应于这些因素。
一般地,动画通过高级合成器和动画引擎206以及低级合成器和动画引擎210完成。在一实现中,高级引擎206遍历场景并且用关于稍后的插补的时间间隔更新动画参数,以及把这些简化的数据结构封装至发送到较低级引擎210的指令中。这可以同步和/或异步的方式完成。时间间隔数据可被考虑成包括定时端点(开始和结束定时数据)和用于再现指令的参数化的值。注意的是高级引擎204可执行请求的插补中的某些插补或所有插补,例如,如果一插补或其它运动函数对于较低级引擎210而言太复杂而不能处理,或较低级不能跟上放置其中的处理需要,较高级引擎可执行计算中的某些计算或所有计算并提供给较低级简化的数据、指令、格局等以实现理想的结果。
在典型的情况下,当较低级执行插补时,对于动画的每个帧,低级引擎210插补参数时间间隔以获得即时值,并解码指令为由图形设备执行的再现命令。图形设备通过添加任何可在场景中出现的视频帧以合成最终的场景。其它数据也可被添加,诸如由数字化版权管理保护的内容。
高级引擎206于是遍历场景数据结构、计算描述一段时间内每个动画的参数的时间间隔、以及发送这些时间间隔和简化的参数化的画图指令至低级引擎210。参数数据包括开始时间、结束时间、插补算子和插补数据。作为示例,高级合成器和动画引擎206可指示低级合成器和动画引擎210关于图形应该随时间的推移如何改变,例如,开始坐标、结束坐标、图形应该在坐标之间移动的时间量(时间间隔)、以及诸如线性的运动函数(注意运动不是动画所要求的,如静态对象可通过更改例如它的颜色属性而被动画播放),而不是擦除和重画图像以使它看上去移动。低级合成器和动画引擎210将插补以确定帧之间新的位置,把这些转换成图形设备可理解的画图指令,并发送命令至图形设备。高级引擎206的每个发送较好地提供足够数据给低级引擎210以执行随着几个帧的推移的平滑的动画。
低级(例如,快速记号)引擎210是从高级引擎206中分离的任务。低级引擎210从高级引擎206接收简化的参数化的画图指令和描述场景的参数时间间隔。低级引擎维持和遍历这些数据结构直到新的数据结构由高级引擎206提供。低级引擎可服务多个高级引擎206,对于每个高级引擎维持独自的数据结构。在低级引擎210和高级引擎206之间一对多的关系允许系统同步地平滑地动画播放多个场景。
低级引擎210实质上基于高级引擎的提供的时间间隔来插补即时动画参数,更新画图指令和再现每一帧的场景。低级引擎210任务在系统上以高优先级运行以确保帧准备好诸如以图形硬件屏幕刷新速率显示。由低级引擎210执行的插补一般因此限制于简单、快速的函数,诸如线性、分段线性、三次样条以及类似速度的那些函数。
关于动画和媒体,一般如图4和图5中显示的,诸如应用程序202的程序结合定时信息(被称为时钟或时钟属性)对高级组件206指定动画属性值。如以下描述的,实质上任何独立动画或媒体(例如,诸如视频和音频的线性媒体)以及协调指定的动画的故事板将具有对于其在高级组件上维持的时钟。一般地,作者指定例示成时钟以合适地保持它们同步的时间线数据。在某些实施例中,故事板是由一组时间线或时间线树组成的时间线。故事板可以提供目标信息,以使其时间线树能够以有关多个元素的多种属性为目标。此外,动画在某些实施例中是各类时间线。
时钟属性包括定义给定的时钟和定时结构的其余部分之间初始同步关系的定时属性。如图5所示,高级组件206可调用高级动画函数520H(例如,以管理的代码书写,该代码以元数据的形式提供信息,该元数据允许通用语言运行时间,其上可运行元数据以控制它的操作)以确定动画属性的当前值。在快速帧速率计算期间,低级组件210调用类似(或相同)的具有由引擎414计算的进程的动画函数520L以确定动画的当前属性值。注意的是在可供选择的实现中,动画函数可构建进例如较低级组件中。
一般地,动画和线性媒体与一组时钟关联,该组时钟通过同步图元和规则相互相关。时钟可被分层次地安排,例如,应用程序具有父时钟,而应用程序的动画的对象是子层,其依次可具有其它子层。当时钟的属性被定义或修改时,该时钟的任何子时钟可被影响。例如,暂停父时钟可暂停其子时钟的任何一个,以及加倍父时钟的速度可加倍子时钟的任何一个的速度。
这些时钟属性可由包括由应用程序在运行时间启动的交互式的控制事件的资源事件所修改。如此,时钟是交互的,通过这种方式每个时钟可各自地由应用程序在任意时间,例如,响应于用户输入而启动、暂停、继续执行以及停止。此外,新的时钟可被添加至定时结构,并且现有的时钟可被移除。
如在上述美国专利申请10/693,822中描述的,高级定时组件可基于存储的事件列表(开始、暂停等)和关联的同步图元对于每个时钟生成时间间隔列表。激活时间间隔是描述在真实世界时间内的不同点上由给定的时钟表示的时间的直接的、非重叠片断。
如图4中所示的,时钟属性中的至少某些属性可在时钟的定时树402内被分层次地关联。三个这样的时钟与它们的属性在图4中示出,即时钟属性4041-4043,然而,可以理解的是在给定的情况下可存在许多更多的时钟和可供替代的定时树。对每个时钟,例如可对应于要显示的动画对象(或故事板协调的对象组),高级组件206包括状态机,称为事件列表生成器408,可从时钟属性产生事件列表(例如,4061)。一般地,事件列表生成器408把由特定的时钟属性初始安排的事件与任何诸如暂停和继续执行接收到的关于动画的请求的显式的交互事件一起分组成一个事件列表。时钟对于每个动画(或如以下描述的通过故事板的动画组)维持,并且这样就存在相应于每个独立的动画/动画组的事件列表以及存在一个对于每个独立线性媒体的事件列表。
高级组件包括对于每个动画或媒体使用事件列表(例如,4063)的时间间隔生成器410以计算发送至低级组件210的相应的时间间隔列表(例如,4123)。依次地,低级组件210包括基于关于时间间隔数据的当前时间来控制输出的低级计算引擎414,该引擎通过诸如基于对于该对象的时间间隔数据和当前时间提供进程值至确定动画对象的变化属性的当前值的低级动画功能子系统520L来控制输出。例如,对于任何给定的帧,低级计算引擎414基于时间间隔数据和当前时间(可以是系统时间或相对时间)来插补动画对象的位置。注意的是如图4和图5中所示,高级定时组件包括定时树402和事件列表4061-4063,而低级定时组件210包括时间间隔列表4121-4123,然而这些数据结构实质上可维持在存储器,一般在高速随机存取存储器内的任何位置。
总而言之,高级定时组件206查看同步规则和图元所相关(例如,分层次地)的时钟的树402。各实施例在高级定时组件206内使用时钟以编译由低级定时引擎消耗的活动时间间隔列表412。低级定时引擎查看表现独立(例如,每一动画对象或每一线性媒体)时钟的时间间隔列表412。如图5中所示,存在提供一致的时间给高级定时组件和低级定时组件的诸如系统时钟524的时钟以使多个级保持同步。
响应于从应用程序202(或某些其它源)接收到的交互更改,高级定时组件需要更新时钟的状态,该状态直接涉及该更改,和任何如同步图元所指定的那样间接涉及的更改。注意的是对于单时钟的更改可影响在定时结构内其它时钟是可能的。例如,幻灯片的陈述者可暂停整个显示,由此当前在显示的任何动画和线性媒体需要被暂停。如以下描述的,根据一个实施例,Storyboard(故事板)允许动画和/或媒体被一起分组并且以这种理想的方式协调。
一般地,任何时候发生关于对象的交互动作,事件列表按需重新生成并且时间间隔列表被重新计算并被发送至较低级定时组件。较高级组件执行这些操作(例如,以每秒大约6到10次数量级的频率)以使较低级组件(例如,每秒操作60次)只需要处理对于每个动画的对象当前的时间间隔列表。
除了一个对象的该时间间隔信息和开始以及结束值,额外的参数可被发送至较高级组件并导致对于时间间隔列表的更改。例如,应用程序可及时寻找对应于一事件的时间段。该应用程序指定寻找何时将要发生、以及到什么程度。象倒带或快进媒体,通过在动画上的寻找,应用程序可及时前跳或回跳至特定点。倒转事件是应用程序可指定的另一类型的计划的或交互的事件。当倒转事件在表中时,进程自动倒转,例如,从百分之百至百分之零。速度更改也被支持,例如,低于某个时钟的每个事物可被设置成运行速度高于或低于实际时间。其它属性也可被指定,诸如对于特定时钟表明是否允许重新开始,和/或如果当前不运行是否再开始,例如,在一秒处启动,在10秒处再开始,在100秒处再开始等,但是如果当前运行,重启或不重启是可任选的。
用于协调动画和媒体的故事板
各实施例尤其涉及故事板,该故事板包括允许对于元素(例如,诸如窗体、面板的FrameworkElement(框架元素),诸如按钮等的控件)特定时间线树的对象。时间线设置元素的属性值,并且控制元素和它子树的动画。Storyboard基本上对应于可被启动、结束或暂停、或用以寻找的特定类型的时间线对象,从而控制与该Storyboard关联的动画元素和/或媒体行为的外观。Storyboard可从标记和代码中获得。
在某些实施例中,对于动画和故事板使用总被触发模型。此外,该模型将动画和故事板放入与触发的直接关系中(与先前实现中的Storyboard属性相反)从而允许传递行为(将在如下结合图6至图9描述)。传递行为是根本的触发概念。正如下文将描述的,未指定的“来自”值基于在新动画被触发以及新动画的传递行为时刻在属性上存在的当前值而被定义。这意味着动画的“来自”值(在未指定时)仅在触发动画时被定义。
因为该属性仅在触发动画时被定义,所以该模型将动画与触发相关联。在此模型中,动画可以内联于触发,或者在Resource(资源)中定义并且直到触发才被使用。
在某些实施例中,Storyboard包括可与元素相关联并且能独立开始的顶级时间线集合。Storyboard也在定时树和元素树之间提供连接点,其中该元素树允许在Storyboard内的动画相对该元素解析它们的目标,且该Storyboard依附于该元素。从标记中,Storyboard也可在Trigger(触发)的集合中声明,该Trigger可由状态更改、事件、或其它动作激活并包含在Trigger被激活时将要被执行的一组可扩展动作(例如,时间线的开始或停止)。Storyboard也可在元素的Resource属性、Style(式样)或Template(模板)中声明。
一般地,在Storyboard内的时间线表示可被应用于各种子树、元素和其它对象(例如,文本字母、单词、线、段落等)的动画模板。根据本发明,故事板(例如,通过API访问的对象)允许程序作者通过对时间线内的动画分组(成为元素属性)来安排协调的动画组。换句话说,故事板把定时树和元素树整合,通过相同的时间线以协调的方式提供能力以操作对于不同动画的不同属性的定时。如此,故事板提供一种方法以将影响各种对象和属性的独立的时间线以其他方式组成一单个时间线树,使程序作者以直接的方式组织和控制复杂定时事件组。例如,作为Storyboard一部分的时间线下的动画分组允许通过简单重启Storyboard来一次性重启所有动画,而不是必须寻找和重启单独的动画。
Storyboard可在动画/视频/音频的特定实例上使用,或被用以特定式样的动画。在某些场景中,被声明为Resource的单个Storyboard可经由多个Element(元素)上各自的触发而被应用于这些元素。BeginStoryboard(开始故事板)在来自标记或代码的属性上启动动画(或其他媒体)。从标记中,开始故事板利用FrameworkElement.BeginStoryboard(框架元素.开始故事板)来走过分配给其故事板属性的各时间线的树。FrameworkElement.BeginStoryboard随后调用居于Timeline(时间线)的Storyboard的树的叶子上的任何动画上的FrameworkElement.BeginAnimation(框架元素.开始动画)。在标记中,BeginStoryboard可用于事件和属性触发。
从标记中,作者可以使用BeginStoryboard来启动Storyboard。BeginStoryboard.Storyboard(开始故事板.故事板)包含其附加属性提供了让多种属性以多个元素为目标的能力的Storyboard。该Storyboard可以含有所有类型的Timeline,包括动画和MediaTimeline(媒体时间线)。
以下的示例示出了内联Storyboard。容器对象(Button(按钮))被动画播放。在此示例中供应Storyboard.TargetName(故事板.目标名),但是在某些实施例中则并不要求供应,这是由于为该动画以该容器为目标。因为BeginStoryboard.Storyboard标签被自动供应,所以它们不是必须的。
在此实施例中,所有的动画在Storyboard.TargetName未被指定时都以容器对象为目标。此外,它们在源未被指定时将容器用作触发事件的Source(源)。这两个假设允许在以容器为目标和触发容器的场景中标记的简化(无需具有TargetName或Source)。
<Window>
<Button Width=”2”Name=”myButton”>
<Button.Triggers>
<EventTrigger Event=”Loaded”>
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To=”4”
Duration=”0:0:1”Storyboard.TargetProperty=”Width”
Storyboard.TargetName=”myButton”/>
//TargetName is not required in this case
because the default target is the container.
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
</Winndow>
以下的示例示出了被定义为Resource的Storyboard。因为动画被定义在Resource部分,所以它可以在其他Framework Element的动画中被重新使用。
<Window>
<Button Width=”2”>
<Button.Resources>
<DoubleAnimation To=”4”Duration=”0:0:1”x:Key=”myAnimation”/>
</Button.Resources>
<Button.Triggers>
<EventTrigger Event=”Loaded”>
<EventTrigger.Actions>
<BeginStoryboard Storyboard=”{StaticResource my Animation}”
TargetProperty=”Width”/>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
</Window>
如上各示例所示,除了整合定时树和元素树之外,故事板允许使用事件触发来控制它们的操作(例如,启动、暂停、寻找和停止动作)。此外,故事板可用属性触发来使用。一般说来,属性触发与诸如真或假的某种状态/值相对应,而事件则激发(fire)(于是就不具有假值)。例如,属性触发可以在鼠标在一元素上盘旋时具有真值,并在不再盘旋时具有假值。每个真或假的状态都可分别用来开始、停止、暂停和/或在故事板(或多个故事板)内寻找。诸如鼠标点击一元素的事件激发,且因而不具有可变状态,但仍能控制故事板的操作。以此方式,动画可经由与显示的元素树表示的用户交互动作而受到控制。
事件触发将在事件在主控元素上激发时引发动作出现的该事件作为它的源。注意,与属性触发不同,事件触发并不界定范围(scoped);它执行操作,随后该操作确定其自身的生命周期。例如,一个事件可以启动一时间线,并且该时间线可以运行直到其持续时间完成,或直到另一事件触发或类似的事件停止该时间线。
图6根据一个实施例示出了一种在富媒体间提供平滑过渡的系统600。在此实施例中,系统600除了先前描述的应用程序202、定时系统208、图形子系统212和属性系统314之外,还包括具有传递系统604的动画系统602。如下将描述根据各实施例在这些过渡中使用的这些组件的某些功能。
如前所述,属性系统314可以存储有关由应用程序202示例的各可视对象(未示出)的属性的值。例如,属性系统314除了对象属性之外,可以存储有关表示UI中显示的按钮的一对象的长度和宽度属性的基值。
如前所述,定时系统208可以协调由应用程序202创建的各动画的定时。例如,定时系统208可以提供在计算正被动画播放的各属性当前值中使用的时间线信息。在一个实施例中,定时系统208可以接收来自交互元素(未示出)的事件和属性变更信息以生成在动画生成中使用的触发(例如,事件触发、属性触发等)。例如,交互元素可以监视鼠标和/或键盘活动,并且将信息提供给定时系统208以引发该定时系统208开始时间线并将触发提供给动画系统602。
如前所述,图形子系统212可以生成需要用来在显示设备上再现动画的数据。
动画系统602在此实施例中执行改变用于创建可视动画性效果的属性值的操作。在一个实施例中,动画系统包括诸如高和低级合成和动画引擎206和208的组件,以及传递系统604。同样地,动画系统602可以从应用程序202接收为动画性属性指定的“来自”和“至(to)”值,以及为执行这些动画指定的时间段。在某些实施例中,有关动画性属性的默认“至”和/或“来自”值可在应用程序未指定时使用。
传递系统604在此实施例中可在动画要在一属性上执行同时其他动画仍然在该属性上执行时使用。在某些实施例中,传递系统604可以执行若干种不同的传递,诸如下表1中所列。术语“旧”动画指的是当应用程序为一特定属性启动另一动画时正在对该相同属性运行的动画。在某些场景中,旧动画可以是两个或更多其他动画的“合成”(即,如表1定义的合成)。在某些实施例中,动画系统602可以被实现以为一个或多个预先确定的场景提供默认的传递行为。在此实施例中,表1描述了能够在动画中设置的传递活动属性的各个值。传递行为属性基本上描述了使用什么作为该动画的“来自”值的值以及要对旧动画做出的动作。
表1
传递 |
行为 |
合成 |
旧动画继续,并且对每个再现循环而言,新动画使用旧动画的输出值作为其“来自”值。新动画的输出值被用作再现该属性的值。 |
替换 |
旧动画被释放,并且当各值未被指定时新动画使用基“至”和“来自”值。 |
快照和替换 |
旧动画的当前值被获取(即,快照)并且旧动画被释放。新动画随后使用快照作为“来自”值并且在未被指定时作为有关“至”值的基值。 |
快照和保留 |
旧动画的快照被获取并且旧动画被允许继续运行而不影响动画性属性的值。新动画使用快照作为“来自”值并且在未被指定时作为有关“至”值的基值。当新动画结束时,旧动画随后被允许恢复该属性的动画。 |
快照和保留/暂停 |
旧动画的快照被获取并且旧动画被暂停。新动画使用快照作为“来自”值并且在未被指定时作为有关“至”值的基值。当新动画结束时,旧动画随后被允许从暂停时的动画状态中动画播放该属性。 |
混合 |
使用动画的加权平均值 |
队列 |
排队未决动画直到现有动画完成。 |
再次使用按钮示例,应用程序可被写入以引发按钮在鼠标光标移动到按钮上时经一特定时间段增大至一特定大小,并在鼠标光标离开该按钮时经一特定时间段缩小回原始大小。在此场景下,用户然后在该特定时间段完全经过之前将光标快速移至并移开该按钮。于是,一当“MouseOver(鼠标在其上)”,“增大”动画会开始,,随后在增大动画完成之前一当“MouseExit(鼠标退出)”,“缩小”动画开始。
如果有关“增大”动画的传递行为是如上表1所述的“快照和替换”行为(可以是指定或默认的),那么在光标离开按钮之时,由“增大”动画产生的按钮的长度和宽度的当前将被快照。在此实施例中,快照的值存储在动画存储对象606内。动画系统602在此实施例中为每个动画播放属性创建动画存储对象606。在某些实施例中,动画存储对象602被配置用以为使按钮在被图形子系统212再现时出现增大和缩小的属性长度和宽度的改变执行计算。
在有关动画性属性的值被快照之后,“增大”动画被释放(即,“增大”动画实际上被终止),并且“缩小”动画将利用作为快照值的长度和宽度的有关属性的“来自”值启动。如果没有影响按钮宽度和长度属性的其他动画被启动,“缩小”动画就完成并在动画结束处,按钮的长度和宽度属性将处于基值。
“快照和替换”行为使得在“增大”和“缩小”动画之间的过渡在用户看来是平滑的。也就是说,按钮看上去是平滑地增大至某一大小并在随后从同一大小平滑地缩小。在不具有前述快照能力的其他系统中,应用程序202或动画系统602很可能不得不提供有关“缩小”动画的“来自”值(例如,基“来自”值或者“增大”动画的目标值),从而很可能导致按钮看上去意外“失灵”。也就是说,按钮看上去增大到某一大小,随后看上去突然改变至一个不同的大小,并由此按钮大小开始缩小。快照的前述优点也应用于如上表1所述的“快照和保留”和“快照和保留/暂停”行为。
如下是使用“快照和替换”传递行为的代码的示例。该代码在MouseEnter(鼠标进入)上增大并在MouseLeave(鼠标离开)上缩小,其中快照和替换行为是默认的传递行为。
<Grid xmlns=″http://schemas.microsoft.com/winfx/avalon/2005″
xmlns:x=″http://schemas.microsoft.com/winfx/xaml/2005″>
<Grid.Resources>
<Style x:Key=″GelButton″TargetType=″{x:Type Button}″>
<Setter Property=″Button.RenderTransform″>
<Setter.Value>
<ScaleTransform Center=″0,0″ScaleX=″1″ScaleY=″1″/>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent=″Mouse.MouseEnter″>
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration=″0:0:0.2″
Storyboard.TargetProperty=″RenderTransform.ScaleX″To=″1.5″
AccelerationRatio=″.9″/>
<DoubleAnimation Duration=″0:0:0.2″
Storyboard.TargetProperty=″RenderTransform.ScaleY″To=″1.5″
AccelerationRatio=″.9″/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent=″Mouse.MouseLeave″>
<EVentTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration=″0:0:0.2″
Storyboard.TargetProperty=″RenderTransform.ScaleX″AccelerationRatio=″.9″/>
<DoubleAnimation Duration=″0:0:0.2″
Storyboard.TargetProperty=″RenderTransform.ScaleY″AccelerationRatio=″.9″/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Button Style=″{StaticResource GelButton}″Width=″100″Height=″100″/>
</Grid>
示例性“快照和替换”操作流程
图7根据一个实施例示出了用于执行“快照和替换”行为的操作流程700。操作流程700可以在任何合适的计算环境内执行。例如,操作流程700可由诸如系统600(图6)的系统执行。因此,操作流程700的描述可能涉及图6的至少一个组件。然而,对图6组件的任何这类参考仅出于描述的目的,并且应该理解图6的实现是操作流程700的一个非限制性环境。
在框702,检测到有关一动画的触发。在一个实施例中,诸如动画系统602(图6)的动画系统检测到该触发(例如,一事件触发或属性触发)。在某些实施例中,动画系统可以从交互元素(以上结合图6所述)接收触发的通知。在此示例性操作流程中,没有其他动画当前正为与该动画相关联的属性运行(即,该属性在可视对象被“动画播放”时改变)。
在框704,分配动画存储对象。在一个实施例中,动画系统创建诸如动画存储对象606(图6)的动画对象来处理与该动画相关联的属性的各动画。在某些实施例中,可为每个要动画播放的属性创建动画存储对象。当有关一属性的所有动画都已被完成时,在某些实施例中就可以删除该动画存储对象。在某些实施例中,当动画到达其充满值时,该充满值会保留在该动画存储对象内,但存储信息的其余信息则被删除。
在框706,将与被触发动画相关联的属性的基值存储在动画存储对象内。在一个实施例中,动画系统将该基值存储在动画存储对象内。基值从诸如属性系统314(图6)的属性系统中获取。
在框708,启动动画并由动画存储对象保持该动画。在一个实施例中,动画存储对象实际上将以屏幕刷新率重新计算有关该属性的值直到该动画完成(或被替换或被暂停),以使得可视对象看上去被动画播放。动画存储对象还可以在该动画正运行的同时保持该动画(即,维持定义该动画当前状态的信息以使得该动画在被保留或保留/暂停的情况下可以被定位并继续)。
在框710,在第一动画完成之前检测到涉及同一属性的第二动画的触发。如框702,动画系统在一个实施例中检测这另外的触发。在此示例性操作流程中,第二动画被配置为具有传递行为,诸如表1中定义的“快照和替换”行为。
在框712,保存由第一动画产生的属性的当前值(即,快照)。在一个实施例中,快照被存储在动画存储对象内。例如,动画系统能够根据第一动画计算有关下一屏幕刷新率的属性的值并将该算出的值(即,快照)存储在动画存储对象内。
在框714,释放第一动画。在一个实施例中,动画系统删除存储在动画存储对象内的第一动画的状态信息。
在框716,启动第二动画并由动画存储对象保持该第二动画。根据该实施例,快照被用作运行第二动画时该属性的“来自”值。与框708的操作类似,动画系统实际上将以屏幕刷新率重新计算有关该属性的值直到该动画完成(或被替换或被暂停),以使得可视对象看上去被动画播放。动画存储对象还可以在该第二动画正运行的同时保持该第二动画(即,维持定义该第二动画当前状态的信息以使得该第二动画在被保留或保留/暂停的情况下可以被定位并继续)。
虽然以特定的次序顺序地示出并描述了操作流程700,但是在其它实施例中,在各框内描述的操作也可以按不同次序,多次和/或并行执行。此外,在某些实施例中,在各框中描述的一个或多个操作可以被分成另一框,或者被省略或合并。
图8根据一个实施例示出了如何根据“快照和替换”传递行为(表1)获取与一动画相关联的有关属性的值。在此实施例中,未被动画播放的属性802具有基值804。在一个实施例中,该基值被存储在诸如先前描述的属性系统314(图3、图6)的属性系统内。
当启动影响属性802的动画808(在图8中被指示为动画A)时,基值804通常被用作动画808的“来自”值810。动画808的“至”值812可由创建该动画808的应用程序(诸如,图6中的应用程序202)指定。在某些场景中,该应用程序可能未指定“至”值和“来自”值,从而导致使用基值作为默认。在一个实施例中,“至”值和“来自”值被存储在诸如动画存储对象606(图6)的动画存储对象内,该动画存储对象在动画808被启动时可由诸如动画系统602(图6)的动画系统分配。当动画808正运行时,在每次屏幕被刷新时计算属性的值(随着动画808改变)并输出作为再现值814。
在此示例中,动画816(在图8中被指示为动画B)在动画808完成之前被启动。在此示例中,动画816已被配置为具有“快照和替换”行为。当被启动时,动画816快照该属性并使用该快照作为动画816的“来自”值818。动画816的“至”值820可由创建该动画816的应用程序指定。在其他场景中,“至”值820可能未被指定,从而导致对基“至”值的使用。在某些实施例中,这些“至”值和“来自”值被存储在前述动画存储对象内。此外,释放动画808以使得只有动画816影响属性的值。当动画816运行时,在每次屏幕被刷新时计算属性的值(随着动画816改变)并将其作为再现值822输出。
如果传递行为是“快照和保留”,动画808就不会被释放。相反地,动画808可被允许继续运行,但是会仅使用动画816(即,忽略动画808)来计算属性的值。随后当动画816完成时,可以使用由动画816生成的属性的最新值来恢复动画808。类似地,如果传递行为是“快照和保留/暂停”,动画808不会被释放。相反地,动画808可被允许在动画816启动时它所具有的状态下暂停,并且仅使用动画816来计算属性的值。随后当动画816完成时,可以使用动画808暂停时的属性来恢复动画808。
图9是根据一个实施例在分层动画之间关系的表示。在此实施例中,可视对象900由应用程序(诸如,图6的应用程序202)定义,该应用程序具有逻辑排列在各层内的各式动画。在此示例中,可视对象包括层902-1至902-N。层902-1包括动画904-1A和动画904-1B;层902-2包括动画904-2A和动画904-2B;并且如此类推直至层902-N包括动画904-NA和动画904-NB。虽然在此示例中存在N层并且每层包括两个动画,但是层数和每层的动画数可以取决于应用程序开发人员的设计选择而改变。
在一个实施例中,第一层902-1被定义以包含由事件触发(与属性触发相对)启动的所有动画。于是,层2至N的动画可由属性触发启动。在某些实施例中,每层与单个属性触发相关联并且包括由该属性触发启动的动画。此外,在此实施例中,正运行的动画可以按从第一层902-1到第N层902-N的属性被执行。另外,在此实施例中,一层内的动画可用包括快照(例如,表1中描述的“快照和替换”、“快照和保留”、“快照和保留/暂停”)和/或合成的传递行为定义,而各层间的过渡则具有合成传递行为。如下将结合图10描述合成传递行为的示例。
在某些实施例中,可以预定义一层内的合成优先级。由较高优先级动画输出的值将被用作下一较低优先级动画的“来自”值。
在一个实施例中,优先级如下定义:(1)来自式样的触发的动画,带有在其中它们出现在定义该层内多个“式样”触发的动画的优先级的标记或代码中的次序;(2)来自本地元素触发的触发的动画,带有在其中它们出现在定义该层内多个“本地元素”触发的动画的优先级的标记或代码中的次序;以及(3)从故事板或方法调用所应用的动画,带有在其中它们被应用以定义有关该“被应用的故事板/方法调用”的优先级的次序。
在某些实施例中,当一层的所有动画都退出时,就移除该层。可以从层“堆栈”中的任何位置移除一层。
图10根据一个实施例示出了两个动画的合成。在此实施例中,未被动画播放的属性1002具有基值1004。在一个实施例中,该基值被存储在诸如先前描述的属性系统314(图3、图6)的属性系统内。
当启动影响属性的动画1008(在图10中被指示为动画A)时,基值1004通常被用作动画1008的“来自”值1010。动画1008的“至”值1012可由创建该动画1008的应用程序(诸如,图6中的应用程序202)指定。在一个实施例中,“至”值和“来自”值被存储在诸如动画存储对象606(图6)的动画存储对象内。虽然未在图10中示出,但是当动画1008自行运行时,在每次屏幕被刷新时计算该属性的值(随着动画1008改变)并将其作为“再现”值提供给诸如图形子系统212(图3、图6)的图形子系统。
在此示例中,动画1016(在图10中被指示为动画B)在动画1008完成之前被启动。在此示例中,动画1016已被配置为具有“合成”行为。与“快照和替换”行为相反,动画1008继续运行以使得该属性的瞬时值持续更新。然而,由动画100产生的该属性的瞬时值不用作“再现”值。相反地,作为动画1008结果而计算的瞬时值作为一种中间值而被用作动画106的“来自”值1018。动画1016的“至”值1020可由创建动画1016的应用程序指定。在某些实施例中,这些“至”值和“来自”值被存储在前述动画存储对象内。由动画1016产生的属性的值随后可用作再现值1022。当动画1008和1016运行时,在每次屏幕被刷新时计算属性的值(随着动画1008和1016的合成改变)并将其作为再现值1022输出。
本说明书通篇引述了“一个实施例”、“一实施例”或“一示例性实施例”,这意指特定的说明特征、结构或特性是涵盖在本发明至少一个实施例中的。于是,这种短语的使用可引用到不止一个实施例中。进一步,在一个或多个实施例中,所述特征、结构或特性能以任何合适的方式组合。
然而,本领域熟练的技术人员会认识到本发明也可不用一个或多个特定细节,或者采用其它方法、资源、材料等来实践。仅仅为了避免模糊本发明的方面,这里未示出和详述其它情况下我们熟知的结构、资源或操作。
虽然已经示出并描述了本发明的示例性实施例和应用形式,但是应当认识到本发明不局限于上述的精确配置和资源。本领域普通技术人员也对这里所述本发明方法和系统的排列、操作和细节做出显而易见的各种修改、变更或变化而不背离本发明所声明的范围。