GacUI 動畫系統 (3:漸變動畫)

慣例先上效果圖:

這次寫的基本上就是代碼生成器。你用XML定義這個漸變動畫,然後會生成Workflow腳本,最後Workflow腳本會由你執行腳本來生成C++代碼。然後這些動畫最終就使用C++來運行。後台那個轉圈圈的菊花動畫還在跑,就算是虛擬執行Workflow腳本CPU佔用率也<0.5%,使用C++的話就更低更快了。

首先,定義你需要的顏色和一些其他數據的數據結構。這個結構必須是一個帶有默認構造函數的class,而它的屬性都得是struct:

class ColorDef{ prop Top : Color = cast Color "#000000" {} prop Bottom : Color = cast Color "#000000" {} prop Shadow : Color = cast Color "#000000A0" {} prop Thickness : int = 0 {} static func Dark() : ColorDef^ { var def = new ColorDef^(); def.Top = cast Color "#9999FF"; def.Bottom = cast Color "#5555FF"; def.Thickness = 0; return def; } static func Light() : ColorDef^ { var def = new ColorDef^(); def.Top = cast Color "#DDDDFF"; def.Bottom = cast Color "#9999FF"; def.Thickness = 0; return def; } static func Sink() : ColorDef^ { var def = new ColorDef^(); def.Top = cast Color "#5555FF"; def.Bottom = cast Color "#0000FF"; def.Thickness = 10; return def; }}

然後用XML定義一個動畫類demo::ColorAnimation

<Animation name="ColorAnimation"> <Gradient ref.Class="demo::ColorAnimation" Type="demo::ColorDef"> <Interpolation> <![CDATA[G]]> </Interpolation> <Targets> <Target Name="Top"/> <Target Name="Bottom"/> <Target Name="Shadow"/> <Target Name="Thickness"> <Interpolation> <![CDATA[ [$1] ]]> </Interpolation> </Target> </Targets> </Gradient></Animation>

生成的demo::ColorAnimation會包含有Current屬性和CreateAnimation函數。其中Current屬性的類型就是你指定的demo::ColorDef。

那麼接下來,我們要做一個UI,然後把外觀的屬性綁定到這個類的Current屬性裡面的其他屬性上去。在此之前我們要在窗口裡面new一個ColorAnimation^放進成員變數里,這樣才有東西可綁:

<Instance name="MainWindowResource"> <Instance ref.Class="demo::MainWindow" xmlns:demo="demo::*"> <ref.Members> <![CDATA[ @cpp:Private prop GradientColorDef : ColorAnimation^ = new ColorAnimation^(ColorDef::Dark()) {const, not observe} func PerformGradientAnimation(target: ColorDef^): void { AddAnimation(GradientColorDef.CreateAnimation(target, (cast UInt64 500))); } var counter : int = 0; ]]> </ref.Members> <Window ref.Name="self" Text="GacUI XML資源臨時測試" ClientSize="x:640 y:480"> <att.BoundsComposition-set PreferredMinSize="x:640 y:480"/> <Tab> <att.BoundsComposition-set AlignmentToParent="left:5 top:5 right:5 bottom:5"/> <att.Pages> <TabPage Text="Gradient Animation"> <Table AlignmentToParent="left:0 top:0 right:0 bottom:0" CellPadding="5"> ... <Cell Site="row:0 column:0 rowSpan:4"> <Bounds PreferredMinSize="x:200 y:200"> <GradientBackground Direction="Slash" Color1-bind="self.GradientColorDef.Current.Top" Color2-bind="self.GradientColorDef.Current.Bottom"/> <Bounds AlignmentToParent="left:0 top:0 right:0 bottom:0"> <InnerShadow Color-bind="self.GradientColorDef.Current.Shadow" Thickness-bind="self.GradientColorDef.Current.Thickness"/> </Bounds> </Bounds> </Cell> ... </Table> </TabPage> ... </att.Pages> </Tab> </Window> </Instance> </Instance>

剩下的,我們只要放上三個按鈕,然後使用ColorDef裡面預先定義好的配色(寫在了靜態成員函數里),調用GacUI提供的API,加上ColorAnimation的CreateAnimation函數就可以了。這個函數的內容就在PerformGradientAnimation裡面。按鈕怎麼調用它我就不說了,用過GacUI的人都知道。

好了,現在動畫已經做完了,只要把剩下的可以把正在運行的動畫取消這一個給做了,GacUI對動畫的支持就差不多到這裡了。幾乎所有動畫都可以用這三篇文章的內容,加上熟練掌握的中學幾何知識來實現。

GacUI的XML基本上還是用來定義和實現GUI的,至於一些花俏的設計功能,還是得做進未來的GacStudio里。


推薦閱讀:

TAG:編程 | 圖形用戶界面 | 動畫製作 |