連載
» 2008年05月07日 00時00分 公開

.NETを知らない人でも分かるSilverlight入門(4):シンプルで機能的なSilverlightのアニメーションとは? (2/3)

[松原晋啓,@IT]

速度を変化させる「キーフレームアニメーション」

 いままでの解説で使用していたベーシックアニメーションは、ある範囲の間を一定の動作で変化するアニメーションでしたが、キーフレームアニメーションはその動作を変化できます。そうすることで、より現実に即したアニメーションを定義できるようになります。

 使用方法に関しては、ほとんどベーシックアニメーションと変わりませんが、1つだけ追加しなければならないオブジェクトがあります。それは、キーフレームアニメーションの「タイプ」と呼ばれるもので、表5のようなものがあります。

表5 キーフレームアニメーションの「タイプ」
タイプ 詳細
Discrete アニメーションではなく指定の位置にジャンプ
Linear スムースな直線のアニメーションを行う
Splined スプライン曲線(コラム参照)に従って可変のアニメーションを行う。このタイプは、より現実的なアニメーションを行うのに適している

コラム 「“スプライン曲線”って何?」

スプライン曲線とは、与えられた複数の点を通る滑らかな曲線で、ベジェ曲線とは異なり、与えられたすべての制御点を通過します。そのため、ベジェ曲線に比べて点の数を増やしても数式の次数は変わらないため、計算量が少なくて済むので、微妙な曲線表現に向いています。


編集部注:ベジェ曲線について詳しく知りたい読者は、連載第3回「Silverlightのリッチなグラフィックス描画サンプル集」のコラム「“ベジェ曲線”って何だべぇ?」をご参照ください。

 実際にキーフレームアニメーションを使用すると、以下のようになります。

ソース2 キーフレームアニメーションのサンプル
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Width="640" Height="480" Background="White" x:Name="Page">
  <Rectangle Fill="Blue" Width="50" Height="50">
    <Rectangle.RenderTransform>
      <TranslateTransform x:Name="MyAnimatedTranslateTransform"
        X="0" Y="0" />
    </Rectangle.RenderTransform>
    <Rectangle.Triggers>
      <EventTrigger RoutedEvent="Rectangle.Loaded">
        <BeginStoryboard>
          <Storyboard>

            <DoubleAnimationUsingKeyFrames
              Storyboard.TargetName="MyAnimatedTranslateTransform"
              Storyboard.TargetProperty="X" Duration="0:0:10">
<!-- LinearDoubleKeyFrame使用。四角形は最初の3秒をかけて500の位置へ移動します。 -->
              <LinearDoubleKeyFrame Value="500" KeyTime="0:0:3" />

<!-- DiscreteDoubleKeyFrame使用。四角形は4秒後に突然400の位置に現れます。 -->
              <DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4" />

<!-- SplineDoubleKeyFrame使用。四角形は2秒かけて最初はゆっくりスタートし、徐々に速くなってスタート地点に戻ります。 -->
              <SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00"
                Value="0" KeyTime="0:0:6" />

            </DoubleAnimationUsingKeyFrames>
          </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
    </Rectangle.Triggers>
  </Rectangle>
</Canvas>

図2 Lineオブジェクトサンプル実行例の画像 図2 キーフレームアニメーションサンプルサンプル実行例の画像(実際にSilverlightで見たい場合は画像をクリック!)※サンプルを動かすには、事前に実行環境のインストールが必要です。→ダウンロードページ

 ここでは、RectangleオブジェクトのX座標の位置を変化させるキーフレームアニメーションをサンプルとしています。そして、ストーリーボードに指定されている10秒の間に、その間にLinear、Discrete、Splinedのそれぞれの動作を行うサンプルになっています。

 最初のLinearキーフレームで、500の位置までRectangleオブジェクトが一定のスピードで動作します。次はDiscreteキーフレームで、500の位置にあったRectangleオブジェクトが突然400の位置に移動します。最後のSplinedキーフレームで、400の位置のRectangleオブジェクトが最初はゆっくりとスタートし、徐々に加速してスタート位置に戻ります。

 以上のようにキーフレームアニメーションでは、3つのタイプのキーフレームを組み合わせて使用することで、ベーシックアニメーションでは表現できなかったアニメーションを実現できます。特に、スプライン曲線が定義できるSplinedキーフレームはいろいろな動作を自由に定義できるので、筆者のお気に入りのキーフレームです。

ついに完成? グローアップアプリケーション

 今回の解説でSilverlight 1.0における機能は一通り網羅したことになりますので、グローアップアプリケーションもひとまずは完成ということになります。前回までで追加した機能は、メディア、イベントハンドラ、エラーハンドラになりますが、今回は2回にわたって解説したグラフィックスとアニメーションを追加しました。

図3 今回のグローアップ・アプリケーション(「Play」で再生、「Pause」で一時停止、「Stop」で停止、FullScreenでアプリケーションが画面いっぱいに広がる) 図3 グローアップアプリケーション実行例

グローアップアプリケーションにグラフィックス機能を追加

 最初はグラフィックスに関してですが、見てお分かりかと思いますが、連載第2回の「SilverlightならWeb上で高精細な動画再生も簡単?」で提示したときのように、「再生」「一時停止」「停止」ボタンが文字列ではなく、グラフィックスを使用したボタンに変わっています。

ソース3 グローアップアプリケーションに追加するグラフィックス機能
<!-- 再生 -->
<Canvas x:Name="PlayButton" Width="25.004" Height="24"
  Canvas.Top="480" Canvas.Left="8">
  <Canvas.RenderTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="2" ScaleY="2"/>
      <SkewTransform AngleX="0" AngleY="0"/>
      <RotateTransform Angle="0"/>
      <TranslateTransform X="0" Y="0"/>
      </TransformGroup>
  </Canvas.RenderTransform>
  <Rectangle Opacity="0" Fill="#FF000000" Stroke="#FF000000"
    Width="24" Height="24"/>
  <Path Width="10.8881" Height="14.4597" Stretch="Fill"
    Data="F1 M 19.5637,625.888L 29.9518,618.862L 19.5807,611.928L 19.5637,625.888 Z "
    Fill="#FF505050" StrokeThickness="0.5"
    StrokeStartLineCap="Round" StrokeEndLineCap="Round"
    StrokeLineJoin="Round" Canvas.Left="9.332" Canvas.Top="5.206"
    MouseLeftButtonDown="mediaPlay">
    <Path.Stroke>
      <LinearGradientBrush StartPoint="0.493145,0.776347"
        EndPoint="0.506856,0.223657">
        <GradientStop Color="#C7636363" Offset="0"/>
        <GradientStop Color="#C7383838" Offset="0.844749"/>
      </LinearGradientBrush>
    </Path.Stroke>
  </Path>
</Canvas>

<!-- 一時停止 -->
<Canvas x:Name="PauseButton" Width="25.004" Height="24"
   Canvas.Top="480" Canvas.Left="72">
  <Canvas.RenderTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="2" ScaleY="2"/>
      <SkewTransform AngleX="0" AngleY="0"/>
      <RotateTransform Angle="0"/>
      <TranslateTransform X="0" Y="0"/>
    </TransformGroup>
  </Canvas.RenderTransform>
  <Rectangle Opacity="0" Fill="#FF000000" Stroke="#FF000000"
     Width="24" Height="24"/>
  <Canvas Opacity="1" Width="14.012" Height="13.608"
    Canvas.Left="5.209" Canvas.Top="5.539"
    MouseLeftButtonDown="mediaPause">
    <Rectangle Width="5.00575" Height="13.6077" Stretch="Fill"
       Fill="#FF505050" StrokeThickness="0.5"
       StrokeStartLineCap="Round" StrokeEndLineCap="Round"
       StrokeLineJoin="Round" Canvas.Left="9.006">
      <Rectangle.RenderTransform>
        <TransformGroup>
          <ScaleTransform ScaleX="1" ScaleY="1"/>
          <SkewTransform AngleX="0" AngleY="0"/>
          <RotateTransform Angle="0"/>
          <TranslateTransform X="0" Y="0"/>
        </TransformGroup>
      </Rectangle.RenderTransform>
      <Rectangle.Stroke>
        <LinearGradientBrush StartPoint="-0.0421154,0.499998"
          EndPoint="1.04212,0.499998">
          <GradientStop Color="#C7636363" Offset="0"/>
          <GradientStop Color="#C7383838" Offset="0.844749"/>
        </LinearGradientBrush>
      </Rectangle.Stroke>
    </Rectangle>
    <Rectangle Width="5.00575" Height="13.6077" Stretch="Fill"
      Fill="#FF505050" StrokeThickness="0.5"
      StrokeStartLineCap="Round" StrokeEndLineCap="Round"
      StrokeLineJoin="Round">
      <Rectangle.Stroke>
        <LinearGradientBrush StartPoint="-0.0421154,0.499998"
          EndPoint="1.04212,0.499998">
          <GradientStop Color="#C7636363" Offset="0"/>
          <GradientStop Color="#C7383838" Offset="0.844749"/>
        </LinearGradientBrush>
      </Rectangle.Stroke>
    </Rectangle>
  </Canvas>
</Canvas>

<!-- 停止 -->
<Canvas x:Name="StopButton" Width="24" Height="24" Canvas.Left="136"
  Canvas.Top="480">
  <Canvas.RenderTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="2" ScaleY="2"/>
      <SkewTransform AngleX="0" AngleY="0"/>
      <RotateTransform Angle="0"/>
      <TranslateTransform X="0" Y="0"/>
    </TransformGroup>
  </Canvas.RenderTransform>
  <Rectangle Opacity="0" Fill="#FF000000" Stroke="#FF000000"
    Width="24" Height="24"/>
  <Rectangle Width="13.006" Height="13.6077" Stretch="Fill"
    Fill="#FF505050" StrokeThickness="0.5"
    StrokeStartLineCap="Round"StrokeEndLineCap="Round"
    StrokeLineJoin="Round" Canvas.Left="5.325" Canvas.Top="5.389"
    MouseLeftButtonDown="mediaStop">
    <Rectangle.RenderTransform>
      <TransformGroup>
        <ScaleTransform ScaleX="1" ScaleY="1"/>
        <SkewTransform AngleX="0" AngleY="0"/>
        <RotateTransform Angle="0"/>
        <TranslateTransform X="0" Y="0"/>
      </TransformGroup>
    </Rectangle.RenderTransform>
    <Rectangle.Stroke>
      <LinearGradientBrush StartPoint="-0.0421154,0.499998"
        EndPoint="1.04212,0.499998">
        <GradientStop Color="#C7636363" Offset="0"/>
        <GradientStop Color="#C7383838" Offset="0.844749"/>
      </LinearGradientBrush>
    </Rectangle.Stroke>
  </Rectangle>
</Canvas>

 ここでは、「再生」ボタンにはPathオブジェクトを使用して三角形の図形を作成して使用していて、「一時停止」ボタンと停止ボタンにはそれぞれRectangleオブジェクトを使用してボタンを作成しています。

 それぞれのオブジェクトをCanvasオブジェクトで囲っているのは領域を指定するためで、ほかの設定に関しても整形や色の調整などを行っているだけなので、特に難しいことはここでは行っていません。

 引き続き次のページでは、グローアップアプリケーションに今回学んだアニメーション機能を追加します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。