SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Silverlight入門

Silverlight入門(4)-アニメーションの作成

Silverlightによるリッチなアニメーション処理


アニメーションの組み合わせ

 これまでのアニメーション処理は、常にStoryboardオブジェクトに単一のTimelineを含ませるだけでした。しかし、複雑なアニメーションの実現には、より単純なTimelineを組み合わせる必要があります。アニメーションの組み合わせは難しいものではありません。複数のTimelineオブジェクトをStoryboardに登録すればよいのです。

Sample09 test.xaml
<Rectangle
 xmlns="http://schemas.microsoft.com/client/2007"
 Width="0" Height="100" Fill="Black" Name="rect"
>
 <Rectangle.Triggers>
  <EventTrigger RoutedEvent="Rectangle.Loaded">
   <BeginStoryboard>
    <Storyboard>
     <DoubleAnimation
      Storyboard.TargetName="rect"
      Storyboard.TargetProperty="Width"
      To="400" Duration="0:0:1"
      AutoReverse="true" RepeatBehavior="Forever"
     />
     <DoubleAnimation
      Storyboard.TargetName="rect"
      Storyboard.TargetProperty="Opacity"
      To="0.1" Duration="0:0:4"
      AutoReverse="true" RepeatBehavior="Forever"
     />
    </Storyboard>
   </BeginStoryboard>
  </EventTrigger>
 </Rectangle.Triggers>
</Rectangle>

 Sample09のXAMLコードはStoryboard要素内に2つのDoubleAnimation子要素を指定しています。このStoryboardオブジェクトが実行されると、子要素に指定したすべてのTimelineが同時に起動します。Sample09の場合、RectangleのWidthプロパティとOpacityプロパティを対象に同時にアニメーションするため、長方形の幅が伸縮しながら、透明度も変化します。

 Storyboard内の個々のTimelineの起動のタイミングを調整することも可能です。デフォルトでは、すべての子Timelineが同時に実行されますが、TimelineオブジェクトのBeginTimeプロパティを変更することで、起動時間を設定できます。

<object BeginTime="TimeSpan" .../>

 BeginTimeに設定するTimespanオブジェクトは、時間間隔を表すための値でDurationに設定した時間間隔と同じようにh:m:s形式で指定できます。Durationオブジェクトとの違いはAutomaticやForeverといった文字列を持たない点です。

 例えば、Storyboard内のTimelineがBeginTimeプロパティに0:0:5を設定している場合、そのTimelineはStoryboardの起動から5秒経過した時点で開始します。複数のTimelineをStoryboard内に保有させている場合、一部のアニメーションの開始を遅らせることができます。

Sample10 test.xaml
<Rectangle
 xmlns="http://schemas.microsoft.com/client/2007"
 Width="100" Height="100" Fill="Black" Name="rect"
>
 <Rectangle.Triggers>
  <EventTrigger RoutedEvent="Rectangle.Loaded">
   <BeginStoryboard>
    <Storyboard>
     <DoubleAnimation
      Storyboard.TargetName="rect"
      Storyboard.TargetProperty="Width"
      To="400" Duration="0:0:1"
      AutoReverse="true"
     />
     <DoubleAnimation
      Storyboard.TargetName="rect"
      Storyboard.TargetProperty="Height"
      To="300" Duration="0:0:1" BeginTime="0:0:2"
      AutoReverse="true"
     />
    </Storyboard>
   </BeginStoryboard>
  </EventTrigger>
 </Rectangle.Triggers>
</Rectangle>

 Sample10は、最初に長方形の幅が伸縮し、その後、高さが伸縮するアニメーションを実行します。幅を伸縮させるDoubleAnimationオブジェクトと、高さを伸縮させるDoubleAnimationオブジェクトの2つのTimelineが用意されていますが、このうち高さを伸縮させるDoubleAnimationオブジェクトにはBeginTimeプロパティで2秒後に起動するように指示しています。そのため、最初に幅を伸縮させるDoubleAnimationのみが進行し、このアニメーションが終了する2秒後に高さを伸縮するDoubleAnimationが開始されます。

Storyboardの中のStoryboard

 Timelineの抽象的な概念で最も重要なのはStoryboardもまたTimelineオブジェクトであるという点です。よって、StoryboardのChildrenプロパティが管理している子TimelineオブジェクトとしてStoryboardを追加することが可能です。いくつかの異なるTimelineオブジェクトのグループを組み合わせることができるのです。

 また、Storyboard内の子Timelineオブジェクトが対象とするオブジェクトやプロパティを、親StoryboardのStoryboard.TargetNameプロパティやStoryboard.TargetPropertyプロパティで共有することも可能です。子TimelineオブジェクトのStoryboard.TargetNameが同じである場合、Storyboardに設定することで共有させることができます。

 AutoReverseプロパティやRepeatBehaviorプロパティも、Timelineオブジェクトで宣言されているプロパティなので、Storyboard単位で設定することが可能です。

Sample11 test.xaml
<Canvas
 xmlns="http://schemas.microsoft.com/client/2007"
>
 <Ellipse Width="100" Height="100" Fill="Black" Name="ellipse">
  <Ellipse.Triggers>
   <EventTrigger RoutedEvent="Ellipse.Loaded">
    <BeginStoryboard>
     <Storyboard Storyboard.TargetName="ellipse">

      <Storyboard AutoReverse="true" >
       <DoubleAnimation To="280" Duration="0:0:4" 
        Storyboard.TargetProperty="(Canvas.Left)"
       />
       <DoubleAnimation To="180" Duration="0:0:4" 
        Storyboard.TargetProperty="(Canvas.Top)"
       />
      </Storyboard>

      <Storyboard AutoReverse="true" RepeatBehavior="Forever">
       <DoubleAnimation By="20" Duration="0:0:0.2" 
        Storyboard.TargetProperty="Width"
       />
       <DoubleAnimation By="20" BeginTime="0:0:0.1" Duration="0:0:0.2" 
        Storyboard.TargetProperty="Height"
       />
      </Storyboard>

     </Storyboard>
    </BeginStoryboard>
   </EventTrigger>
  </Ellipse.Triggers>
 </Ellipse>
</Canvas>

 Sample11のXAMLコードでStoryboard要素の子要素としてStoryboardを設定しているところに注目してください。StoryboardオブジェクトもまたTimelineを継承するオブジェクトなので、StoryboardオブジェクトのChildrenプロパティが管理している子Timelineとして登録できるのです。

 Timelineが対象とするオブジェクトは、トップレベルのStoryboardのStoryboard.TargetNameに設定しています。子TimelineオブジェクトのStoryboard.TargetNameプロパティに適切なオブジェクト名が設定されていない場合、親StoryboardのStoryboard.TargetNameプロパティがデフォルトの値として用いられます。

 さらに、AutoReverseプロパティやRepeatBehaviorプロパティの設定もStoryboard単位で行うことができます。いくつかのTimelineを組み合わせたStoryboard単位でアニメーション全体の動きを管理できます。Sample11では、オブジェクトを移動させるStoryboardと、オブジェクトを伸縮させるStoryboardに役割を分離してアニメーションを行います。

最後に

 本稿で解説させていただいたSilverlightのアニメーション機能は、XAMLコードをテキストエディタで記述することを想定した学習用のサンプルです。より曲線的な動きをするより複雑なアニメーションを作成することもできますが、複合的な動きをするアニメーションをテキストエディタで書く場合はコード量が膨大になることを覚悟しなければなりません。

 プロフェッショナルのデザイナが求めるような実用的なレベルのアニメーション処理となれば、ExpressionBlendのようなデザインツールを使って作成した方が合理的です。しかし、アニメーションを実現する具体的な処理の流れを理解することは、スクリプトを書く場合に重要になります。

 また、Webアプリケーションによってデータベースの情報から動的にXAMLを生成し、棒グラフなどをアニメーションさせるといった演出も可能です。いろいろなアイデアを試してみてください。

参考

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Silverlight入門連載記事一覧

もっと読む

この記事の著者

赤坂 玲音(アカサカ レオン)

平成13年度「全国高校生・専門学校生プログラミングコンテスト 高校生プログラミングの部」にて最優秀賞を受賞。2005 年度~ Microsoft Most Variable Professional Visual Developer - Visual C++。プログラミング入門サイト WisdomSoft の管理人。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2072 2008/08/26 13:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー