キー フレーム アニメーションとイージング関数アニメーション

線形キー フレーム アニメーション、 KeySpline 値を持つキー フレーム アニメーション、イージング関数は、ほぼ同じシナリオで 3 つの異なる手法です。ストーリーボードに設定されたアニメーションを作成する方法は、もう少し複雑で、開始状態から終了状態までの非線形アニメーション動作を使用します。

[前提条件]

ストーリーボード化されたアニメーションのトピックを読んだことを確認してください。 このトピックは、ストーリーボード化されたアニメーションで説明されたアニメーションの概念に基づいており、それらについては再度説明しません。 たとえば、ストーリーボードに設定されたアニメーション では、アニメーション、ストーリーボードをリソースとしてターゲットにする方法、 タイムライン プロパティの値 (Duration、FillBehavior など) を対象にする方法について説明します。

キー フレーム アニメーションを使用してアニメーションを行う

キー フレーム アニメーションでは、アニメーション タイムラインに沿って 1 つのポイントに到達する複数のターゲット値を使用できます。 つまり、各キー フレームは異なる中間値を指定でき、最後に到達したキー フレームは最終的なアニメーション値になります。 アニメーション化する複数の値を指定することで、より複雑なアニメーションを作成できます。 キー フレーム アニメーションでは、アニメーションの種類ごとに異なる KeyFrame サブクラスとして実装される、異なる補間ロジックも有効になります。 具体的には、キー フレーム アニメーションの種類ごとに、キー フレームを指定するための KeyFrame クラスの個別、線形、スプライン、イージングのバリエーションがあります。 たとえば、Double をターゲットにしてキー フレームを使用するアニメーションを指定するには、DiscreteDoubleKeyFrame、LinearDoubleKeyFrame、SplineDoubleKeyFrame、EasingDoubleKeyFrame を使用してキー フレームを宣言できます。 1 つの KeyFrames コレクション内でこれらすべての型を使用して、新しいキー フレームに到達するたびに補間を変更できます。

補間動作の場合、各キー フレームは 、KeyTime 時間に達するまで補間を制御します。 その 値 は、その時点でも達しています。 それ以上のキー フレームがある場合、値はシーケンス内の次のキー フレームの開始値になります。

アニメーションの開始時に、 KeyTime が "0:0:0" のキー フレームが存在しない場合、開始値はプロパティのアニメーション化されていない値です。 これは、From/To/By アニメーションがFromを使わない場合の動作と似ています。

キー フレーム アニメーションの期間は、任意のキー フレームで設定された最大 の KeyTime 値と暗黙的に等しい期間です。 必要に応じて明示的な 期間 を設定できますが、独自のキー フレームの KeyTime よりも短くしないようにしてください。さもないと、アニメーションの一部が切り取られる可能性があります。

Duration(期間)に加えて、キー フレーム アニメーション クラスは タイムライン から派生しているので、From/To/By アニメーションと同様に、キー フレーム アニメーションでタイムラインに基づくすべてのプロパティを設定できます。 これらは:

  • AutoReverse: 最後のキー フレームに達すると、フレームは末尾から逆の順序で繰り返されます。 これにより、アニメーションの見かけ上の継続時間が 2 倍になります。
  • BeginTime: アニメーションの開始を遅らせます。 フレーム内の KeyTime 値のタイムラインは 、BeginTime に達するまでカウントを開始しないため、フレームを切断するリスクはありません
  • FillBehavior: 最後のキー フレームに達したときの動作を制御します。 FillBehavior は、中間キー フレームには影響しません。
  • RepeatBehavior:
    • [Forever] に設定すると、キー フレームとそのタイムラインが無限に繰り返されます。
    • 反復回数に設定すると、タイムラインは何度も繰り返されます。
    • 期間に設定すると、タイムラインはその時間に達するまで繰り返されます。 タイムラインの暗黙の期間が整数の因数でない場合、キー フレーム シーケンスの途中でアニメーションが切り捨てられる可能性があります。
  • SpeedRatio (一般的には使用されません)

線形キーフレーム

線形キー フレームでは、フレームの KeyTime に達するまで値の単純な線形補間が行われます。 この補間の動作は、「ストーリーボード化されたアニメーション」トピックで説明されているより単純な From/To/By アニメーションに最も似ています。

線形キー フレームを用いて四角形のレンダリングの高さを調整する方法を次に示します。 次の使用例は、最初の 4 秒間、四角形の高さがわずかに直線的に増加するアニメーションを実行し、四角形が開始高さの 2 倍になるまで、最後の 2 秒間は急速に拡大縮小します。

<StackPanel>
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimationUsingKeyFrames
              Storyboard.TargetName="myRectangle"
              Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1.2" KeyTime="0:0:4"/>
                <LinearDoubleKeyFrame Value="2" KeyTime="0:0:5"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </StackPanel.Resources>
</StackPanel>

個別のキーフレーム

個別のキー フレームでは、補間はまったく使用されません。 KeyTime に達すると、新しい値が単に適用されます。 アニメーション化されている UI プロパティに応じて、"ジャンプ" と表示されるアニメーションが生成されることがよくあります。 これがあなたが本当に望む審美的な行動であることを確認してください。 宣言するキー フレームの数を増やすことで、見かけ上のジャンプを最小限に抑えることができますが、スムーズ アニメーションが目標である場合は、代わりに線形キー フレームまたはスプライン キー フレームを使用することをお勧めします。

注

個別のキー フレームは、 Double、 Point、 Color 型以外の値を DiscreteObjectKeyFrame でアニメーション化する唯一の方法です。 これについては、このトピックの後半で詳しく説明します。

スプライン キー フレーム

スプライン キー フレームは、 KeySpline プロパティの値に従って値間の可変遷移を作成します。 このプロパティは、アニメーションの高速化を記述するベジエ曲線の 1 番目と 2 番目のコントロール ポイントを指定します。 基本的に、 KeySpline は、関数と時間の関係を定義します。ここで、関数と時間のグラフはそのベジエ曲線の形状です。 通常は、スペースまたはコンマで区切られた 4 つの Double 値を持つ XAML 短縮形属性文字列で KeySpline 値を指定します。 これらの値は、ベジエ曲線の 2 つの制御点の "X,Y" ペアです。 "X" は時間、"Y" は値の関数修飾子です。 各値は、常に 0 ~ 1 の範囲にする必要があります。 KeySpline に制御点を変更しない場合、0,0 から 1,1 までの直線は、線形補間の時間経過に伴う関数の表現です。 コントロール ポイントは、その曲線の形状を変更するため、スプライン アニメーションの時間の経過に伴う関数の動作を変更します。 これをグラフとして視覚的に確認することをお勧めします。

次の例では、アニメーションに適用される 3 つの異なるキー フレームを示します。最後の 1 つは Double 値 (SplineDoubleKeyFrame) のキー スプライン アニメーションです。 KeySpline に適用される文字列 "0.6,0.0 0.9,0.00" に注意してください。 これにより、アニメーションが最初はゆっくりと実行しているように見えるが、 KeyTime に達する直前に値に急速に達する曲線が生成されます。

<Storyboard x:Name="myStoryboard">
    <!-- Animate the TranslateTransform's X property
        from 0 to 350, then 50,
        then 200 over 10 seconds. -->
    <DoubleAnimationUsingKeyFrames
        Storyboard.TargetName="MyAnimatedTranslateTransform"
        Storyboard.TargetProperty="X"
        Duration="0:0:10" EnableDependentAnimation="True">

        <!-- Using a LinearDoubleKeyFrame, the rectangle moves 
            steadily from its starting position to 500 over 
            the first 3 seconds.  -->
        <LinearDoubleKeyFrame Value="500" KeyTime="0:0:3"/>

        <!-- Using a DiscreteDoubleKeyFrame, the rectangle suddenly 
            appears at 400 after the fourth second of the animation. -->
        <DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4"/>

        <!-- Using a SplineDoubleKeyFrame, the rectangle moves 
            back to its starting point. The
            animation starts out slowly at first and then speeds up. 
            This KeyFrame ends after the 6th second. -->
        <SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00" Value="0" KeyTime="0:0:6"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

イージング キー フレーム

イージング キー フレームは、補間が適用されるキー フレームであり、補間の時間の経過に伴う関数は、いくつかの定義済みの数式によって制御されます。 実際には、一部のイージング関数の種類と同じ結果をスプライン キー フレームで生成できますが、 BackEase など、スプラインで再現できないイージング関数もあります。

イージング キー フレームにイージング関数を適用するには、そのキー フレームの XAML のプロパティ要素として EasingFunction プロパティを設定します。 値には、イージング関数の種類の 1 つにオブジェクト要素を指定します。

次の使用例は、連続するキー フレームとして CubicEase と BounceEase を DoubleAnimation に適用し、バウンス効果を作成します。

<Storyboard x:Name="myStoryboard">
    <DoubleAnimationUsingKeyFrames Duration="0:0:10"
        Storyboard.TargetProperty="Height"
        Storyboard.TargetName="myEllipse">

        <!-- This keyframe animates the ellipse up to the crest 
            where it slows down and stops. -->
        <EasingDoubleKeyFrame Value="-300" KeyTime="00:00:02">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>

        <!-- This keyframe animates the ellipse back down and makes
            it bounce. -->
        <EasingDoubleKeyFrame Value="0" KeyTime="00:00:06">
            <EasingDoubleKeyFrame.EasingFunction>
                <BounceEase Bounces="5"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

これは単なるイージング関数の例です。 詳細については、次のセクションで説明します。

イージング関数

イージング関数を使用すると、アニメーションにカスタム数式を適用できます。 数学演算は、多くの場合、2-D 座標系で実際の物理演算をシミュレートするアニメーションを生成するのに役立ちます。 たとえば、オブジェクトを実際に跳ねさせたり、ばねのように動作させたりすることができます。 キー フレームや From/To/By アニメーションを 使用してこれらの効果を近似することもできますが、かなりの時間がかかり、数式を使用するよりもアニメーションの精度が低下します。

イージング関数は、次の 3 つの方法でアニメーションに適用できます。

イージング関数の一覧を次に示します。

  • BackEase: 指定されたパスでアニメーション化を開始する少し前に、アニメーションのモーションを取り消します。
  • BounceEase: バウンス効果を作成します。
  • CircleEase: 円関数を使用して加速または減速するアニメーションを作成します。
  • CubicEase: 数式 f(t) = t3 を使用して加速または減速するアニメーションを作成します。
  • ElasticEase: 静止するまで前後に振動するスプリングに似たアニメーションを作成します。
  • ExponentialEase: 指数数式を使用して加速または減速するアニメーションを作成します。
  • PowerEase: f(t) = tp という数式を使用して加速または減速するアニメーションを作成します。p は Power プロパティと等しくなります。
  • 二次イーズ: 数式 f(t) = t² を使用して加速または減速するアニメーションを作成します。
  • QuarticEase: 数式 f(t) = t4 を使用して加速または減速するアニメーションを作成します。
  • QuinticEase: 数式 f(t) = t5 を使用して加速または減速するアニメーションを作成します。
  • SineEase: 正弦数式を使用して加速または減速するアニメーションを作成します。

イージング関数の一部には、独自のプロパティがあります。 たとえば、BounceEase には、その特定の BounceEase の関数の時間経過動作を変更する 2 つのプロパティ Bounces と Bounceiness があります。 CubicEase などの他のイージング関数には、すべてのイージング関数が共有する EasingMode プロパティ以外のプロパティがなく、常に同じ関数の超過動作が生成されます。

これらのイージング関数の中には、プロパティを持つイージング関数にプロパティを設定する方法に応じて、少し重複しているものもあります。 たとえば、QuadraticEase は、指数 を 2 に設定した PowerEase とまったく同じです。 CircleEase は基本的に既定値の ExponentialEase です。

BackEase イージング関数は、From/To またはキー フレームの値によって設定された通常の範囲外の値を変更できるため、一意です。 通常の From/To の動作から期待どおりに反対方向に値を変更してアニメーションを開始し、[開始 ] または [ 開始] の値に戻り、通常どおりにアニメーションを実行します。

前の例では、キー フレーム アニメーションのイージング関数を宣言する方法を示しました。 次のサンプルでは、 From/To/By アニメーションにイージング関数を適用します。

<StackPanel x:Name="LayoutRoot" Background="White">
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                Storyboard.TargetName="myRectangle" 
                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <DoubleAnimation.EasingFunction>
                    <BounceEase Bounces="2" EasingMode="EaseOut" 
                                Bounciness="2"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </StackPanel.Resources>
    <Rectangle x:Name="myRectangle" Fill="Blue" Width="200" Height="30"/>
</StackPanel>

FromToBy アニメーションにイージング関数を適用すると、アニメーションの継続時間にわたって、From 値と To 値の間で値が補間される際の関数の時間経過における特性が変化します。 イージング関数がないと、線形補間になります。

不連続オブジェクト値アニメーション

特定のアニメーションは、Double、Point、Color 型以外のプロパティにアニメーション値を適用できる唯一の方法であるため、特別な言及に値します。 これは、キー フレーム アニメーション ObjectAnimationUsingKeyFrames です。 オブジェクト値を使用したアニメーション化は、フレーム間で値を補間する可能性がないため、異なります。 フレームの KeyTime に達すると、アニメーション化された値はキー フレームの Value で指定された値にすぐに設定されます。 補間がないため、 ObjectAnimationUsingKeyFrames キー フレーム コレクションで使用するキー フレームは 1 つだけです: DiscreteObjectKeyFrame。

DiscreteObjectKeyFrame の値は、多くの場合、プロパティ要素の構文を使用して設定されます。多くの場合、設定しようとしているオブジェクト値は、属性構文の Value を埋める文字列として表現できないためです。 StaticResource などの参照を使用する場合でも、属性構文を使用できます。

既定のテンプレートで使用される ObjectAnimationUsingKeyFrames が表示される 1 つの場所は、テンプレート プロパティが Brush リソースを参照する場合です。 これらのリソースは、Color 値だけでなく SolidColorBrush オブジェクトであり、システム テーマ (ThemeDictionaries) として定義されているリソースを使用します。 これらは TextBlock.Foreground などの Brush 型の値に直接割り当てることができ、間接的なターゲット設定を使用する必要はありません。 ただし、SolidColorBrush は Double、Point、Color ではないため、リソースを使用するには ObjectAnimationUsingKeyFrames を使用する必要があります。

<Style x:Key="TextButtonStyle" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent">
                    <TextBlock x:Name="Text"
                        Text="{TemplateBinding Content}"/>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
...
                       </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ObjectAnimationUsingKeyFrames を使用して、列挙値を使用するプロパティをアニメーション化することもできます。 Windows ランタイムの既定のテンプレートに由来する名前付きスタイルの別の例を次に示します。 Visibility 列挙定数を受け取る Visibility プロパティを設定する方法に注意してください。 この場合は、属性構文を使用して値を設定できます。 列挙値を持つプロパティを設定するには、列挙型の非修飾定数名 ("Collapsed" など) のみが必要です。

<Style x:Key="BackButtonStyle" TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid x:Name="RootGrid">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal"/>
...           <VisualState x:Name="Disabled">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame Value="Collapsed" KeyTime="0"/>
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
...
          </VisualStateManager.VisualStateGroups>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

ObjectAnimationUsingKeyFrames フレーム セットには、複数の DiscreteObjectKeyFrame を使用できます。 これは、複数のオブジェクト値が役に立つ可能性があるシナリオの例として 、Image.Source の値をアニメーション化して "スライド ショー" アニメーションを作成する興味深い方法です。