XAMLは画像を定義するだけでなく、簡単なアニメーションも登録することができます。
XAMLアニメーションの解説の多くは、単純に図形の位置や向きが変化したり色や透明度が変化するだけのものが多いですが、ちょっと工夫するとXAMLだけでも、パラパラ漫画のように画像を順番に切り替えていくパラパラアニメーションも作ることができます。
私が試して成功した方法は以下の4つです。
- ObjectAnimationUsingKeyFramesを使ってImageのSourceプロパティを変更して画像を切り替え
- アニメーションを1枚に連結した画像をImageBrushに登録し、Transformでブラシの位置をずらしながら、1コマ分の大きさのRectangleを表示
- Canvas.clipに1コマ分の大きさのRectangleGeometryを登録し、その中でImageを移動させて連結画像の1コマ分をクリップ表示
- Canvas上の同じ位置に全ての画像を重ねて配置し、1枚ずつ順番に表示されるようにObjectAnimationUsingKeyFramesでVisibilityプロパティを切り替え
1は一番素直だと思いますが、Sourceプロパティを変更するたびにPNG画像の読み込みが発生するので、たぶん一番重いと思います。Image専用の手法で、ベクトル画像には使えない欠点もあります。また、VisualStudioでXAMLを編集しようとすると落ちたりして、扱いづらかったです。
2と3は考え方はほとんど一緒で、連結画像から1コマ分だけをどうやって抜き出すのかの実現方法が違います。2はラスター画像専用ですが、3はベクトル画像にも適用できます。
4はStoryboardの記述が複雑になりますが、もしかすると一番軽いかもしれません。ベクトル画像をアニメーションさせる場合は、これがベストではないかと思います。
3の方法で作ったパラパラアニメは以下のようになります。
<UserControl x:Class="SilverlightAnimationTest.Walk" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" IsHitTestVisible="False"> <Canvas x:Name="LayoutRoot"> <Canvas Canvas.Left="-45" Canvas.Top="-73"> <Canvas.Clip> <RectangleGeometry Rect="0,0,75,75"/> </Canvas.Clip> <Image Name="walking" Source="walking.png" Stretch="None"/> </Canvas> <Canvas.Triggers> <EventTrigger RoutedEvent="Canvas.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="walking" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:1.2" RepeatBehavior="Forever"> <DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0.0"/> <DiscreteDoubleKeyFrame Value="-75" KeyTime="0:0:0.2"/> <DiscreteDoubleKeyFrame Value="-150" KeyTime="0:0:0.4"/> <DiscreteDoubleKeyFrame Value="-225" KeyTime="0:0:0.6"/> <DiscreteDoubleKeyFrame Value="-300" KeyTime="0:0:0.8"/> <DiscreteDoubleKeyFrame Value="-375" KeyTime="0:0:1.0"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger> </Canvas.Triggers> </Canvas> </UserControl>
ここで使用しているwalking.pngは以下のようにアニメーションを横に連結した画像で、1コマは75*75のサイズとなっています。

入れ子になっている内側のCanvasは、原点を人物の足元にするためにマイナスの座標を設定しています。また1コマ分を抜き出すためのクリップGeometryもここに設定してあります。
アニメーションの対象が添付プロパティの場合は、このようにTargetPropertyの引数に括弧を付ける必要があります。
これを組み込んだ実物のサンプルは続きで。
C#のコード上では、スプライトの位置と左右反転を操作しているだけで、アニメーションに関しては全く関与していません。アニメーションの開始もXAML内で処理しているので、静止画なのかアニメーションなのか、コード上からは全く意識する必要がありません。
このようにXAMLだけでアニメーションを定義できると、最初に静止画で作っておいたパーツも後からXAMLの編集だけで動きを加えることができるので便利です。

