かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その48 「WPFのアニメーション その1」

WPFは、アニメーションを組み込みでサポートしています。WPFのアニメーションは、指定した依存関係プロパティを指定した時間内で、指定した変化量で、指定した範囲の値を変化させ続ける仕組みになります。単純なWPFのアニメーションの定義例を以下に示します。

<Storyboard x:Key="rectAnimation">
    <DoubleAnimation
        Storyboard.TargetName="rect"
        Storyboard.TargetProperty="(Canvas.Left)"
        To="300"
        Duration="0:0:5" />
</Storyboard>

アニメーションは通常Storyboardというものに纏められます。Storyboardは通常Resourcesで定義されます。Storyboardの中にAnimation(は型名)という値のアニメーションをさせるタグを定義します。上記ではDouble型のアニメーションを行うDoubleAnimationを使用しています。Animationには、Storyboard.TargetName添付プロパティと、Storyboard.TargetProperty添付プロパティでターゲットとなるオブジェクトとプロパティを指定します。上記の例では、rectという名前で定義されたオブジェクトのCanvas.Left依存関係プロパティを指定しています。プロパティの指定がカッコで括られているのは、プロパティが添付プロパティであるためです。通常の依存関係プロパティの場合はカッコは必要ありません。

続けてToプロパティで、アニメーションが最終的にいくつく値を設定します。今回の例では省略していますがFromを指定することで、どこの値を開始とするか指定することもできます。省略した場合は、現在の値が使われます。最後にDurationで、アニメーションにかかる時間を指定します。書式は時:分:秒です。上記の例では、5秒を指定しています。今回のアニメーションの定義は、rectという名前のオブジェクトのCanvas.Leftプロパティを5秒間かけて300という値に変更するという意味になります。

アニメーションは定義しただけでは起動しません。アニメーションを開始する方法はいくつかありますが、ここでは、単純なEventTriggerを使う方法を紹介します。EventTriggerは名前の通り、コントロールのTriggersプロパティに指定できるルーティングイベントをきっかけにアニメーションを開始するためのクラスです。以下のように定義して使います。

<Button Canvas.Top="10" Canvas.Left="10" Content="Animation start">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard Storyboard="{StaticResource rectAnimation}" />
        </EventTrigger>
    </Button.Triggers>
</Button>

上記の例ではButtonのClickイベントをきっかけにrectAnimationを開始するように定義しています。

このサンプルの全体のXAMLを以下に示します。

<Window x:Class="AnimationSample01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Storyboard x:Key="rectAnimation">
            <DoubleAnimation
                Storyboard.TargetName="rect"
                Storyboard.TargetProperty="(Canvas.Left)"
                To="300"
                Duration="0:0:5" />
        </Storyboard>
    </Window.Resources>
    <Canvas>
        <Button Canvas.Top="10" Canvas.Left="10" Content="Animation start">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard Storyboard="{StaticResource rectAnimation}" />
                </EventTrigger>
            </Button.Triggers>
        </Button>
        <!-- アニメーションのターゲット -->
        <Rectangle
            x:Name="rect"
            Canvas.Top="50" Canvas.Left="10"
            Width="50" Height="50" Fill="Red"/>
    </Canvas>
</Window>

実行結果を以下に示します。起動直後は以下のような配置になっています。

f:id:okazuki:20140827213702p:plain

ボタンをクリックすると矩形が右に移動を始めます。

f:id:okazuki:20140827213732p:plain

5秒たつと矩形の移動が終わります。

f:id:okazuki:20140827213756p:plain

Byによる値の指定方法

アニメーションの値の指定方法で一番単純なのは、FromとToを指定する方法です。アニメーションの指定方法にはFromとTo以外に、FromとByを使う方法があります。この方法はFrom(省略可能)を基準として、Byだけ変化させるということになります。初期値が10でByに20を指定した場合、アニメーションが終わった時の値は30になります。以下にByを使ったアニメーションの定義例を示します。

<Storyboard x:Key="rectAnimationBy">
    <DoubleAnimation
        Storyboard.TargetName="rect"
        Storyboard.TargetProperty="(Canvas.Left)"
        By="100" 
        Duration="0:0:5" />
</Storyboard>

上記の例は、5秒かけて100だけCanvas.Leftがアニメーションします。

アニメーションの繰り返しの指定

デフォルトでは、アニメーションは1度終了すると再度手動で実行するまで停止しています。アニメーションに繰り返しを指定すると、指定した回数、指定した方法でアニメーションを繰り返させることが出来ます。

AutoReverseプロパティを指定すると、アニメーションが終了したあと、逆方向のアニメーションを再生するか指定できます。サンプルで示した矩形が右に移動するアニメーションに指定すると、右に移動が完了したあと元の位置に向かって左方向にアニメーションするようになります。

また、RepeatBehaviorにアニメーションを繰り返す時間を指定できます。ここで指定した時間だけ、アニメーションを再生し続けることが出来ます。AutoReverseと組み合わせることで、行ったり来たりというアニメーションを実行させることも出来ます。色に対して指定すると点滅させるという効果も持たせることが出来ます。TimeSpan型なのでDurationプロパティと同様に時:分:秒の書式で指定しますが、Foreverを指定することで無限にアニメーションを再生し続けることが出来ます。 以下にアニメーションの繰り返しの指定例を示します。

<Storyboard x:Key="rectAnimationRepeat">
    <DoubleAnimation
        Storyboard.TargetName="rect"
        Storyboard.TargetProperty="(Canvas.Left)"
        To="300" 
        Duration="0:0:5"
        RepeatBehavior="0:0:13"
        AutoReverse="True"/>
</Storyboard>

この例ではアニメーションが13秒間繰り返しを続けます。

その他の型のアニメーション

ここまではDoubleAnimationを例にアニメーションを説明してきました。WPFのアニメーションにはDouble型以外の型もサポートしています。以下に主なものを示します。

  • ColorAnimation:SolidColorBrushなどの色をアニメーションします。
  • PointAnimation:Point型をアニメーションします。

コードからのアニメーション

WPFのアニメーションはコードで組み立てたり、実行することが出来ます。最初に示した矩形のアニメーションを行う例をC#で書いたものを以下に示します。

var storyboard = new Storyboard();

var a = new DoubleAnimation();
// TargetName添付プロパティではなく、Target添付プロパティで
// 直接アニメーションのターゲットを指定しています。
Storyboard.SetTarget(a, rect);
Storyboard.SetTargetProperty(a, new PropertyPath("(Canvas.Left)"));
a.To = 300;
a.Duration = TimeSpan.FromSeconds(5);
storyboard.Children.Add(a);

// アニメーションを開始します
storyboard.Begin();

コードでアニメーションを組むことで、計算に基づいた複雑なアニメーションを組み立てることが出来ます。

過去記事