[Windows 8 | XAML] 使用Blend製作動畫故事版(StoryBoard)

前言


有時候會希望可以透過程式的方式產生、製作較複雜動畫,但是複雜的動畫在撰寫時會花費大量時間與來來回回的執行調整參數以達到符合期望的動畫效果,但是其實可以用更快的方式,以程式產生動畫-使用Blend軟體!

Blend


Blend是一個提供給開發.Net的人員,透過更精確的設計介面與工具,達到可以用視覺化的介面來編輯應用程式。而Blend在Visual Studio 2012中整合進去了,所以安裝Visual Studio 2012也會一併提供。

而Blend裡面也提供了製作動畫的時間格 與 修改元件或圖像的屬性,方便可以直接修改並觀看成效。

使用Blend製作Storybard動畫


這邊我們來讓一個Rectangle從在時間1秒內白色變成藍色,感受一下如何使用Blend完成一個簡單的動畫

1.加入白色Rectangle

其中,你左邊的工具列中可以找到與多可以拖拉的元件,或是你可以切換到資產,並從資產中的控制項或其他元件拉入到應用程式的畫面,這邊Rectangle是圖形,所以我們把它拉入。

2.點選狀態,加入動畫狀態

在資產旁邊中,有一個狀態的頁面切換紐,點開後點選這邊框起來紅色的框,就會加入狀態:

而在這邊狀態的預設名稱會是VisualStateGroup,然後我們稍微看一下他的程式碼:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    	<VisualStateManager.VisualStateGroups>
    		<VisualStateGroup x:Name="VisualStateGroup"/>
    	</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="rectangle" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="185" Margin="525,370,0,0" Stroke="Black" VerticalAlignment="Top" Width="220"/>
    </Grid>

你會看到產生了一個VisualStateGroup元件 ,這個VisualStateGroup包含了VisualState與VisualTransition物件,用來使元件從某一狀態到另一狀態時使用;而這些狀態的外觀變化都是透過Storyboard的方式完成外觀的設定。

VisualState:

表示控制項處於特定狀態的外觀,當如Button可能會有Pressed、Normal等狀態時我們可以設定按鈕文字的顏色之類

不過每個元件的都有不同的VisualState狀態,詳細的部分可以看一下海角點部落的這篇文章,整理得很詳細。

VisualTransition:

表示控制項從一個狀態變換至另一個狀態時,中間的視覺外觀,如MouseOver ->Pressed的過程;另外如果元件本身不是控制項或是元件是控制項但沒有要使用到本身提供的VisualState狀態,要製作隨著時間變化的動畫效果時,也會使用到VisualTransition來包覆住Stoyrboard完成。

例如這個例子中,我們所做的範例是Rectangle,他是被定義在圖形中,所以沒有提供相關VisualSate的狀態,而在製作變化顏色的動畫時,便會被包覆在VisualTransition物件的標籤中。

3.修改屬性,拉動時間軸

當我們點擊狀態中的VisualStateGroup時,便會看到畫面中跑出錄製的紅色框,透過這個錄製動作,像是巨集錄製一般,把所設定的外觀變化都記錄起來;改變外觀的部分,可以透過右邊屬性中的選項來設定;其中,下方有一個轉換的區塊,可以用來對元件做旋轉、縮放、位移等功能。

再來我們可以拉動時間軸,把這個變化效果的時間做調整。

讓我們看一下加入變色後的程式碼:

這裡你會看到,時間的軸的變化與效果的改變,是透過Storyboard完成。

<VisualStateManager.VisualStateGroups>
    		<VisualStateGroup x:Name="VisualStateGroup">
    			<VisualStateGroup.Transitions>
    				<VisualTransition GeneratedDuration="0">
    					<Storyboard>
    						<ColorAnimation Duration="0" To="#FF0404FF" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
    					</Storyboard>
    				</VisualTransition>
    			</VisualStateGroup.Transitions>
    		</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

這邊我們也可以讓他再複雜一點,變色後再來是旋轉。

先把時間軸往後拉:

然後再對屬性中的轉換->調整旋轉:

但是這樣還不算完成喔,最後一步就是在我們的程式中啟動Storyboard:

4.在程式中啟動編輯好的動畫Storyboard

MainPage.xaml

在Storyboard標籤中加入Name

<VisualStateManager.VisualStateGroups>
    		<VisualStateGroup x:Name="VisualStateGroup">
    			<VisualStateGroup.Transitions>
    				<VisualTransition GeneratedDuration="0">
    					<Storyboard x:Name="myStoryboard">
    						<ColorAnimation Duration="0:0:1" To="Blue" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
    						<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="rectangle">
    							<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
    							<EasingDoubleKeyFrame KeyTime="0:0:2" Value="180"/>
    						</DoubleAnimationUsingKeyFrames>
    					</Storyboard>
    				</VisualTransition>
    			</VisualStateGroup.Transitions>
    		</VisualStateGroup>
    	</VisualStateManager.VisualStateGroups>

MainPage.cs

public MainPage()
{
     this.InitializeComponent();
     myStoryboard.Begin();
}

前面看到了VisualTransition的一個簡單範例,但是對VisualState的使用方式還不是很有感覺,以下在介紹一個範例來呈現。

VisualState範例


這裡我們以一個Button按鈕來做為範例,看看控制項Button所提供的VisualState狀態。

1.加入Button

從資產中拉入按鈕

2.把Button變成控制項

對著Button按右鍵後,選擇變成控制項(因為預設的Button並由有提供VisualState的狀態,透過轉變成控制項的方式把Button的樣式產生,在樣式中會提供預設的狀態)。

下圖是轉變成控制項的選單,點選Button並按下確定。

然後左邊的狀態便會產生屬於Button的一些狀態

3.對點擊(Pressed)做出動畫效果

點選Pressed後會開始錄製,這邊要製作一個效果是點選Button後,Button的背景會變成紅色的效果

最後我們看一下程式碼部分:

<VisualStateManager.VisualStateGroups>
	<VisualStateGroup x:Name="CommonStates">
		<VisualState x:Name="Normal"/>
			<VisualState x:Name="Pressed">
				<Storyboard>
					<ColorAnimation Duration="0" To="#FFF72B2B" Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" Storyboard.TargetName="button" d:IsOptimized="True"/>
				</Storyboard>
			</VisualState>
			<VisualState x:Name="Disabled"/>
			<VisualState x:Name="PointerOver"/>
		</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

控制項會提供特定的狀態,而已Button為例子,這邊的範例,因為我是點選CommonState所提供的狀態,而Button包含了Normal、Pressed、Disabled、PointerOver等效果,當我對Pressed狀態做編輯了,Blend便自動對包含在CommonState的狀態一併產生在程式中。

最後這部分的效果,一樣是透過Storyboard來達成,在VisualStateGroup中所呈現外觀、動畫是透過Storyboard完成。

結論


透過Blend有時候可以更快的完成複雜的動畫效果或特定狀態時的動畫,如果與美術設計師合作開發時,也可以透過Blend來快速把介面的Prototype建立起來,達到共識。

參考資料:

VisualState 類別

VisualTransition 類別

VisualStateGroup 類別

如需更全面地了解编译器优化,请参阅优化注意事项