いままでの解説で使用していたベーシックアニメーションは、ある範囲の間を一定の動作で変化するアニメーションでしたが、キーフレームアニメーションはその動作を変化できます。そうすることで、より現実に即したアニメーションを定義できるようになります。
使用方法に関しては、ほとんどベーシックアニメーションと変わりませんが、1つだけ追加しなければならないオブジェクトがあります。それは、キーフレームアニメーションの「タイプ」と呼ばれるもので、表5のようなものがあります。
表5 キーフレームアニメーションの「タイプ」
|
タイプ |
詳細 |
|
Discrete |
アニメーションではなく指定の位置にジャンプ |
Linear |
スムースな直線のアニメーションを行う |
Splined |
スプライン曲線(※コラム参照)に従って可変のアニメーションを行う。このタイプは、より現実的なアニメーションを行うのに適している |
|
スプライン曲線とは、与えられた複数の点を通る滑らかな曲線で、ベジェ曲線とは異なり、与えられたすべての制御点を通過します。そのため、ベジェ曲線に比べて点の数を増やしても数式の次数は変わらないため、計算量が少なくて済むので、微妙な曲線表現に向いています。
実際にキーフレームアニメーションを使用すると、以下のようになります。
ソース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 キーフレームアニメーションサンプルサンプル実行例の画像(実際にSilverlightで見たい場合は画像をクリック!)※サンプルを動かすには、事前に実行環境のインストールが必要です。→ダウンロードページ
ここでは、RectangleオブジェクトのX座標の位置を変化させるキーフレームアニメーションをサンプルとしています。そして、ストーリーボードに指定されている10秒の間に、その間にLinear、Discrete、Splinedのそれぞれの動作を行うサンプルになっています。
最初のLinearキーフレームで、500の位置までRectangleオブジェクトが一定のスピードで動作します。次はDiscreteキーフレームで、500の位置にあったRectangleオブジェクトが突然400の位置に移動します。最後のSplinedキーフレームで、400の位置のRectangleオブジェクトが最初はゆっくりとスタートし、徐々に加速してスタート位置に戻ります。
以上のようにキーフレームアニメーションでは、3つのタイプのキーフレームを組み合わせて使用することで、ベーシックアニメーションでは表現できなかったアニメーションを実現できます。特に、スプライン曲線が定義できるSplinedキーフレームはいろいろな動作を自由に定義できるので、筆者のお気に入りのキーフレームです。
今回の解説でSilverlight 1.0における機能は一通り網羅したことになりますので、グローアップアプリケーションもひとまずは完成ということになります。前回までで追加した機能は、メディア、イベントハンドラ、エラーハンドラになりますが、今回は2回にわたって解説したグラフィックスとアニメーションを追加しました。
図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オブジェクトで囲っているのは領域を指定するためで、ほかの設定に関しても整形や色の調整などを行っているだけなので、特に難しいことはここでは行っていません。
引き続き次のページでは、グローアップアプリケーションに今回学んだアニメーション機能を追加します。