WPFで画像を使用したアニメーション(画像の切り替え)

XAMLコード

ひとまずコードです。Viewに関することは基本的にxamlに記述するというMVVMの教えに従っていこうと思います。

<Window x:Class="Animation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Animation"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <Storyboard x:Key="Storyboard">
            <ObjectAnimationUsingKeyFrames
                        Storyboard.TargetName="main"
                        Storyboard.TargetProperty="(Image.Source)"
                        AutoReverse="False"
                        Duration="0:0:1.5"
                        RepeatBehavior="Forever">
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime1.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime2.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime3.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime4.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime5.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime6.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime7.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime8.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime9.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame.Value>
                        <BitmapImage UriSource="Resource\anime10.png" />
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard Storyboard="{StaticResource Storyboard}"/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <Image 
            Name="main"
            Source="Resource\anime10.png"
            Margin="10" />
    </Grid>
</Window>

説明

Window.Resources内の記述について

<Window.Resources>
    <Storyboard x:Key="Storyboard">
        <ObjectAnimationUsingKeyFrames
                    Storyboard.TargetName="main"
                    Storyboard.TargetProperty="(Image.Source)"
                    AutoReverse="False"
                    Duration="0:0:1.5"
                    RepeatBehavior="Forever">
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime1.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime2.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime3.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime4.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime5.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime6.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime7.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime8.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime9.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame>
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="Resource\anime10.png" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>

Window.Resources

今回の例でいくと、Window.Resourcesに記述する意味はないかもしれませんが、Resources内に記述するとオブジェクトを複数のUIと共有できます。

Storyboard

アニメーションを使用する際、通常Storyboardを使うみたいです。Storyboardを使う場合はResources内に定義するとのことなのでこの書き方で良いかもしれませんね。

ObjectAnimationUsingKeyFrames

オブジェクト(画像)などをアニメーションにするにはObjectAnimationUsingKeyFramesを使用する。
他にも図形とか文字とかのアニメーションをする場合に使う型があるみたいだが、それはおいおいやっていきます。

参考

https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.media.animation?view=netframework-4.7.2

Storyboard.TargetNameStoryboard.TargetPropertyでアニメーションを再生したいオブジェクト(ここではImageオブジェクト)とプロパティを指定します。

AutoReverseはアニメーションを逆再生するかどうか、Durationは再生時間、 RepeatBehaviorはアニメーションを繰り返すかどうかを設定しています。他にもプロパティはありますがそれもおいおい。。。

DiscreteObjectKeyFrame

Valueにアニメーションで使用する画像をセットします。

Window.Triggers内の記述について

<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <BeginStoryboard Storyboard="{StaticResource Storyboard}"/>
    </EventTrigger>
</Window.Triggers>

Triggers

Window.ResourcesでStoryboard(アニメーション)を定義しましたが、定義するだけではアニメーションが開始されません。開始のトリガーをここで定義します。

<EventTrigger RoutedEvent="Window.Loaded">

上記の記述がウィンドウが表示し終わってからトリガー内の動作をすることになります。

<BeginStoryboard Storyboard="{StaticResource Storyboard}"/>

BeginStoryboardによりStoryboardで定義した内容のアニメーションが再生されます。

Grid内の記述について

<Grid>
    <Image 
        Name="main"
        Source="Resource\anime10.png"
        Margin="10" />
</Grid>

Storyboard.TargetNameに定義したプロパティをNameプロパティに定義することでImageオブジェクトにアニメーションが再生されます。

Sourceプロパティに画像をセットしていますが、これがないとアニメーションを繰り返し再生したときに一瞬アニメーションが消えてしまうためこうしています。他にいい方法があるかもしれないので知っている方がいれば教えてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA