オープニングに実行するアニメーションをStoryboardに設定。最初の画面はこれで初期化する
※1 最初にアニメーションさせたいStoryboardを配置するためにXAMLを直接編集します。
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
ここにストーリーボードを配置
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Canvas.Triggers>
このタグで囲むことにより、ロードが完了した時点でオープニングアニメーションが動き始めます。
どうしてもFlashをベースに考えてしまうため、XAMLのオーサリングの概念が、Blendを操作するうえで実は最初にとまどったところでした。Flashの場合、メインのタイムライン上に見たままにレイアウトしたり、ActionScriptを使用してライブラリのMovieClipを配置したりするわけですが、Blendではライブラリという概念がないので、いきなり画面上でCAMVASを作成して画面を構成していくことになります。そこで、ホントは後から配置したいアイテムはどうすればいいのだろう? といったようなことが最初にぶつかった壁でした。
これは結局“Flash的”に考えると、「XAML上に<CANVAS />として記述したモノすべてをMovieClipだと思えばいいのかもしれない」と判断し、そこで最初にオープニングアニメーションのStoryboardを作成しました。読み込みが完了した時点で最初にそれが再生されるようにして(※1)、そのStoryboard上で最初には表示させたくないアイテム(CANVAS)は、そのStoryboardの設定で透明度を設定したり(Opacity="0")、画面外に置いてしまうなどして初期画面を構成することにしました。
Storyboardでは、キーフレームで移動したり、色などを変更したCANVASの属性だけが画面上に反映されます。そのため、PLAYボタンにマウスカーソルがロールオーバーしたときに実行させたい、クリックしたときに実行させたい、といったさまざまな細かい動きは、Storyboardのタイムライン上で設定しておき、JavaScriptのイベントハンドラ上ではそのStoryboardを実行しろとだけ指定すればよいのです。
Storyboardの概念もFlash的に考えてしまうと最初にとまどうところで、これはFlashのMovieClipにplay()を実行するのに似ていますが、Blendの場合は動かしたいプロパティだけをアニメーションで変更すればよく、使い方によってはかなり便利になるでしょう(詳しくはコラム参照)。
ここでのポイントは、アニメーションして変化させたプロパティは、別のシーンに移動したときに戻しておく点。戻しておかないと、たとえばボタンの赤フチが残ったままになってしまうので考慮しておく必要があるのです。簡単な動きならStoryboardをDuplicate(複製)してReverse(反転)することで、状態を戻すためのStoryboardをある程度簡単に作ることができます。
![](img/ex1_sec02_bg_top.gif)
BlendのStoryboardがFlashのTimelineと大きく違うのは、最初の状態であるにもかかわらず、指定したキーフレームの属性が、実行した瞬間の状態からトゥイーンアニメーションで変化すること。文章ではわかりにくいので次のサンプルをみてほしい。
四隅にボタンを設置・クリックすると、その位置に2秒間で真ん中のボールがトゥイーンアニメーションして移動する。図はDの位置からBをクリックして、まだBに移動しきれないうちにCのボタンをクリックしたところ。するとその時点から実行されたStoryboardで指定したキーフレームの場所までが補間される。これと同じことをFlashで表現しようとすると、Tween Classを使ったスクリプトの記述が多少必要とされるが、Blendではボタンの左クリックで呼び出されるJavaScriptのfunctionに
sender.findName("ストーリーボード名").begin();
と1行だけ記述、実行しているだけだ。基本的にそのストーリーボードには2秒後のボールの位置だけが指定しているのみ。なんて簡単!
![](img/ex2_sec02_visual01.jpg)
![](img/ex1_sec02_bg_btm.gif)
話が前後しますが、Blendのインターフェイス上ではSilverlightのイベントトリガーを設定できないため、前述のCanvas.Lodedと同じようにXAMLに直接イベントを書き込みます。
たとえばボタンのデザインパーツをグループ化してひとつのCANVASにし、そのCANVASの属性に
<Canvas x:Name="PLAY" Width="100" Height="32" Canvas.Left="8" Canvas.Top="7"
Cursor="Hand"
MouseEnter="PLAY_MouseEnter"
MouseLeave="PLAY_MouseLeave"
MouseLeftButtonDown="PLAY_MouseLeftButtonDown">
と、「MouseEnter」「MouseLeave」「MouseLeftButtonDown」イベントで実行するJavaScriptのファンクション名を指定します(赤文字が追加した部分)。
JavaScriptではそれを受けてどのStoryboardを実行するか指定するだけ。JavaScriptからCANVASの属性を変更することも可能なので、Storyboardを使ってコントロールしたほうがいいのか、直接属性を変更したほうがよいのかどうかを臨機応変に見極める必要があるかもしれませんね。
このあたりもプログラマーとデザイナーの分業の度合いによって判断することになるでしょう。同じようなアニメーションのアクションをたくさん作る大変さを考えたら、JavaScript側で汎用のfunctionを作成してすべてのコントロールをしてしまうという技もなくはないと思います。ただし複雑な動きのアクションと演出はStoryboardにまかせたほうが圧倒的にいい動きになる場合も多いでしょう。
![Storyboardで制御するか、属性を直接変更するか、ケースによって使い分けよう](img/ex2_sec03_visual01.jpg)