プロパティ アニメーションの手法の概要
ここでは、ストーリーボード、ローカル アニメーション、クロック、フレーム単位のアニメーションなど、プロパティをアニメーション化するためのさまざまな方法を示します。
必要条件
このトピックを理解するには、「アニメーションの概要」で説明されている基本的なアニメーション機能に精通している必要があります。
アニメーション化のための各種方法
プロパティのアニメーション化には多数の異なるシナリオがあるため、WPF では、プロパティをアニメーション化するために複数の方法を利用できます。
それぞれの方法について、インスタンス単位、スタイル内、コントロール テンプレート内、またはデータ テンプレート内で使用できるかどうか、XAML で使用できるかどうか、およびアニメーションを対話的に制御できるかどうかを次の表に示します。 "インスタンス単位" とは、スタイル、コントロール テンプレート、またはデータ テンプレート内のインスタンスではなく、オブジェクトのインスタンスに直接アニメーションまたはストーリーボードを適用する方法のことです。
アニメーションの手法 |
シナリオ |
XAML のサポート |
対話的に制御可能 |
---|---|---|---|
ストーリーボード アニメーション |
インスタンス単位、Style、ControlTemplate、DataTemplate |
○ |
○ |
ローカル アニメーション |
インスタンス単位 |
X |
X |
クロック アニメーション |
インスタンス単位 |
X |
○ |
フレーム単位のアニメーション |
インスタンス単位 |
X |
N/A |
ストーリーボード アニメーション
XAML でアニメーションを定義して適用する場合、アニメーションを開始後に対話的に制御する場合、アニメーションの複雑なツリーを作成する場合、または Style、ControlTemplate、DataTemplate でアニメーション化する場合は、Storyboard を使用します。 Storyboard によってアニメーション化するオブジェクトについては、FrameworkElement または FrameworkContentElement である必要があります。あるいは、FrameworkElement または FrameworkContentElement を設定するために使用されている必要があります。 詳細については、「ストーリーボードの概要」を参照してください。
Storyboard はコンテナー Timeline の特殊な型であり、含まれる複数のアニメーションの対象情報を持っています。 Storyboard を使用してアニメーション化するには、次の 3 つの手順を実行します。
Storyboard および 1 つ以上のアニメーションを宣言します。
TargetName 添付プロパティおよび TargetProperty 添付プロパティを使用して、各アニメーションのターゲット オブジェクトおよびプロパティを指定します。
(コードのみ) FrameworkElement または FrameworkContentElement の NameScope を定義します。 アニメーション化するオブジェクトの名前を、その FrameworkElement または FrameworkContentElement に登録します。
Storyboard を開始します。
Storyboard を開始すると、アニメーションがアニメーション化するプロパティに適用され、開始されます。 Storyboard を開始するには、2 とおりの方法があります。Storyboard クラスによって提供される Begin メソッドを使用するか、BeginStoryboard アクションを使用します。 XAML でアニメーション化するには、BeginStoryboard アクションを使用する以外に方法はありません。A BeginStoryboard アクションは、EventTrigger、Trigger プロパティ、または DataTrigger で使用できます。
各 Storyboard の開始方法がサポートされているさまざまな場所、インスタンス単位、スタイル、コントロール テンプレート、およびデータ テンプレートを次の表に示します。
ストーリーボードが開始される場所 |
インスタンス単位 |
スタイル |
コントロール テンプレート |
データ テンプレート |
例 |
---|---|---|---|---|---|
○ |
○ |
○ |
○ |
||
BeginStoryboard および Trigger プロパティ |
X |
○ |
○ |
○ |
|
X |
○ |
○ |
○ |
||
Begin メソッド |
○ |
X |
X |
X |
Storyboard オブジェクトの詳細については、「ストーリーボードの概要」を参照してください。
ローカル アニメーション
ローカル アニメーションは、任意の Animatable オブジェクトの依存関係プロパティをアニメーション化するための便利な方法を提供します。 プロパティに適用するアニメーションが 1 つだけであり、アニメーションを開始後に対話的に制御する必要がない場合は、ローカル アニメーションを使用します。 Storyboard アニメーションとは異なり、ローカル アニメーションは、FrameworkElement または FrameworkContentElement に関連付けられていないオブジェクトをアニメーション化できます。 この種類のアニメーションには NameScope を定義する必要はありません。
ローカル アニメーションはコードだけで使用できます。スタイル、コントロール テンプレート、またはデータ テンプレート内では定義できません。 ローカル アニメーションは、開始後に対話的に制御できません。
ローカル アニメーションを使用してアニメーション化するには、次の手順を実行します。
AnimationTimeline オブジェクトを作成します。
アニメーション化するオブジェクトの BeginAnimation メソッドを使用して、指定するプロパティに AnimationTimeline を適用します。
Button の幅および背景色をアニメーション化する方法を次の例に示します。
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''This sample demonstrates how to apply non-storyboard animations to a property.
'''To animate in markup, you must use storyboards.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Imports System
Imports System.Windows
Imports System.Windows.Navigation
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports System.Windows.Controls
Namespace Microsoft.Samples.Animation.LocalAnimations
' Create the demonstration.
Public Class LocalAnimationExample
Inherits Page
Public Sub New()
WindowTitle = "Animate Property Example"
Dim myStackPanel As New StackPanel()
myStackPanel.Margin = New Thickness(20)
' Create and set the Button.
Dim aButton As New Button()
aButton.Content = "A Button"
' Animate the Button's Width.
Dim myDoubleAnimation As New DoubleAnimation()
myDoubleAnimation.From = 75
myDoubleAnimation.To = 300
myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(5))
myDoubleAnimation.AutoReverse = True
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever
' Apply the animation to the button's Width property.
aButton.BeginAnimation(Button.WidthProperty, myDoubleAnimation)
' Create and animate a Brush to set the button's Background.
Dim myBrush As New SolidColorBrush()
myBrush.Color = Colors.Blue
Dim myColorAnimation As New ColorAnimation()
myColorAnimation.From = Colors.Blue
myColorAnimation.To = Colors.Red
myColorAnimation.Duration = New Duration(TimeSpan.FromMilliseconds(7000))
myColorAnimation.AutoReverse = True
myColorAnimation.RepeatBehavior = RepeatBehavior.Forever
' Apply the animation to the brush's Color property.
myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation)
aButton.Background = myBrush
' Add the Button to the panel.
myStackPanel.Children.Add(aButton)
Me.Content = myStackPanel
End Sub
End Class
End Namespace
/*
This sample demonstrates how to apply non-storyboard animations to a property.
To animate in markup, you must use storyboards.
*/
using System;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls;
namespace Microsoft.Samples.Animation.LocalAnimations
{
// Create the demonstration.
public class LocalAnimationExample : Page
{
public LocalAnimationExample()
{
WindowTitle = "Local Animation Example";
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(20);
// Create and set the Button.
Button aButton = new Button();
aButton.Content = "A Button";
// Animate the Button's Width.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 75;
myDoubleAnimation.To = 300;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
myDoubleAnimation.AutoReverse = true;
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
// Apply the animation to the button's Width property.
aButton.BeginAnimation(Button.WidthProperty, myDoubleAnimation);
// Create and animate a Brush to set the button's Background.
SolidColorBrush myBrush = new SolidColorBrush();
myBrush.Color = Colors.Blue;
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Blue;
myColorAnimation.To = Colors.Red;
myColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(7000));
myColorAnimation.AutoReverse = true;
myColorAnimation.RepeatBehavior = RepeatBehavior.Forever;
// Apply the animation to the brush's Color property.
myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation);
aButton.Background = myBrush;
// Add the Button to the panel.
myStackPanel.Children.Add(aButton);
this.Content = myStackPanel;
}
}
}
/*
This sample demonstrates how to apply non-storyboard animations to a property.
To animate in markup, you must use storyboards.
*/
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Navigation;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Animation;
using namespace System::Windows::Shapes;
using namespace System::Windows::Controls;
namespace Microsoft {
namespace Samples {
namespace Animation {
namespace LocalAnimations {
// Create the demonstration.
public ref class LocalAnimationExample : Page {
public:
LocalAnimationExample ()
{
WindowTitle = "Local Animation Example";
StackPanel^ myStackPanel = gcnew StackPanel();
myStackPanel->Margin = Thickness(20);
// Create and set the Button.
Button^ aButton = gcnew Button();
aButton->Content = "A Button";
// Animate the Button's Width.
DoubleAnimation^ myDoubleAnimation = gcnew DoubleAnimation();
myDoubleAnimation->From = 75;
myDoubleAnimation->To = 300;
myDoubleAnimation->Duration = Duration(TimeSpan::FromSeconds(5));
myDoubleAnimation->AutoReverse = true;
myDoubleAnimation->RepeatBehavior = RepeatBehavior::Forever;
// Apply the animation to the button's Width property.
aButton->BeginAnimation(Button::WidthProperty, myDoubleAnimation);
// Create and animate a Brush to set the button's Background.
SolidColorBrush^ myBrush = gcnew SolidColorBrush();
myBrush->Color = Colors::Blue;
ColorAnimation^ myColorAnimation = gcnew ColorAnimation();
myColorAnimation->From = Colors::Blue;
myColorAnimation->To = Colors::Red;
myColorAnimation->Duration = Duration(TimeSpan::FromMilliseconds(7000));
myColorAnimation->AutoReverse = true;
myColorAnimation->RepeatBehavior = RepeatBehavior::Forever;
// Apply the animation to the brush's Color property.
myBrush->BeginAnimation(SolidColorBrush::ColorProperty, myColorAnimation);
aButton->Background = myBrush;
// Add the Button to the panel.
myStackPanel->Children->Add(aButton);
this->Content = myStackPanel;
};
};
}
}
}
}
クロック アニメーション
Storyboard を使用せずにアニメーション化する際に、複雑なタイミング ツリーを作成する場合、またはアニメーションを開始後に対話的に制御する場合は、Clock オブジェクトを使用します。 Clock オブジェクトを使用すると、任意の Animatable オブジェクトの依存関係プロパティをアニメーション化できます。
Clock オブジェクトは、スタイル、コントロール テンプレート、またはデータ テンプレート内で直接アニメーション化するために使用することはできません (アニメーションとタイミング システムは、実際に Clock オブジェクトを使用して、スタイル、コントロール テンプレート、およびデータ テンプレート内でアニメーション化しますが、そのためには、これらの Clock オブジェクトを Storyboard から作成する必要があります。 Storyboard オブジェクトと Clock オブジェクトの関係の詳細については、「アニメーションとタイミング システムの概要」を参照してください。
プロパティに 1 つの Clock を適用するには、次の手順を実行します。
AnimationTimeline オブジェクトを作成します。
AnimationTimeline の CreateClock メソッドを使用して AnimationClock を作成します。
アニメーション化するオブジェクトの ApplyAnimationClock メソッドを使用して、指定するプロパティに AnimationClock を適用します。
AnimationClock を作成し、2 つの類似するプロパティにこれを適用する方法を次の例に示します。
'
' This example shows how to create and apply
' an AnimationClock.
'
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Shapes
Imports System.Windows.Media.Animation
Namespace Microsoft.Samples.Animation.TimingBehaviors
Public Class AnimationClockExample
Inherits Page
Private myScaleTransform As ScaleTransform
Public Sub New()
Me.WindowTitle = "Opacity Animation Example"
Me.Background = Brushes.White
Dim myStackPanel As New StackPanel()
myStackPanel.Margin = New Thickness(20)
' Create a button that with a ScaleTransform.
' The ScaleTransform will animate when the
' button is clicked.
Dim myButton As New Button()
myButton.Margin = New Thickness(50)
myButton.HorizontalAlignment = HorizontalAlignment.Left
myButton.Content = "Click Me"
myScaleTransform = New ScaleTransform(1,1)
myButton.RenderTransform = myScaleTransform
' Associate an event handler with the
' button's Click event.
AddHandler myButton.Click, AddressOf myButton_Clicked
myStackPanel.Children.Add(myButton)
Me.Content = myStackPanel
End Sub
' Create and apply and animation when the button is clicked.
Private Sub myButton_Clicked(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Create a DoubleAnimation to animate the
' ScaleTransform.
Dim myAnimation As New DoubleAnimation(1, 5, New Duration(TimeSpan.FromSeconds(5))) ' "To" value - "From" value
myAnimation.AutoReverse = True
' Create a clock the for the animation.
Dim myClock As AnimationClock = myAnimation.CreateClock()
' Associate the clock the ScaleX and
' ScaleY properties of the button's
' ScaleTransform.
myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleXProperty, myClock)
myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleYProperty, myClock)
End Sub
End Class
End Namespace
/*
This example shows how to create and apply
an AnimationClock.
*/
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
namespace Microsoft.Samples.Animation.TimingBehaviors
{
public class AnimationClockExample : Page
{
ScaleTransform myScaleTransform;
public AnimationClockExample()
{
this.WindowTitle = "Opacity Animation Example";
this.Background = Brushes.White;
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(20);
// Create a button that with a ScaleTransform.
// The ScaleTransform will animate when the
// button is clicked.
Button myButton = new Button();
myButton.Margin = new Thickness(50);
myButton.HorizontalAlignment = HorizontalAlignment.Left;
myButton.Content = "Click Me";
myScaleTransform = new ScaleTransform(1,1);
myButton.RenderTransform = myScaleTransform;
// Associate an event handler with the
// button's Click event.
myButton.Click += new RoutedEventHandler(myButton_Clicked);
myStackPanel.Children.Add(myButton);
this.Content = myStackPanel;
}
// Create and apply and animation when the button is clicked.
private void myButton_Clicked(object sender, RoutedEventArgs e)
{
// Create a DoubleAnimation to animate the
// ScaleTransform.
DoubleAnimation myAnimation =
new DoubleAnimation(
1, // "From" value
5, // "To" value
new Duration(TimeSpan.FromSeconds(5))
);
myAnimation.AutoReverse = true;
// Create a clock the for the animation.
AnimationClock myClock = myAnimation.CreateClock();
// Associate the clock the ScaleX and
// ScaleY properties of the button's
// ScaleTransform.
myScaleTransform.ApplyAnimationClock(
ScaleTransform.ScaleXProperty, myClock);
myScaleTransform.ApplyAnimationClock(
ScaleTransform.ScaleYProperty, myClock);
}
}
}
タイミング ツリーを作成し、これを使用してプロパティをアニメーション化するには、次の手順を実行します。
ParallelTimeline オブジェクトと AnimationTimeline オブジェクトを使用して、タイミング ツリーを作成します。
ルート ParallelTimeline の CreateClock を使用して ClockGroup を作成します。
ClockGroup の Children を反復処理し、その子 Clock オブジェクトを適用します。 子 AnimationClock ごとに、アニメーション化するオブジェクトの ApplyAnimationClock メソッドを使用して、指定するプロパティに AnimationClock を適用します。
Clock オブジェクトの詳細については、「アニメーションとタイミング システムの概要」を参照してください。
フレーム単位アニメーション : アニメーションとタイミング システムのバイパス
この方法は、WPF アニメーション システムを完全にバイパスする必要がある場合に使用します。 この方法の 1 つのシナリオは、アニメーションの各ステップで、オブジェクトの最後の一連のやり取りに基づいてオブジェクトの再計算が必要になる物理アニメーションです。
フレーム単位アニメーションは、スタイル、コントロール テンプレート、またはデータ テンプレート内で定義できません。
フレームごとにアニメーション化するには、アニメーション化するオブジェクトを格納しているオブジェクトの Rendering イベントで登録します。 このイベント ハンドラー メソッドは、フレームごとに 1 回呼び出されます。 WPF がビジュアル ツリーの永続化されたレンダリング データを構成ツリーにマーシャリングするたびに、イベント ハンドラー メソッドが呼び出されます。
イベント ハンドラーでは、アニメーション効果に必要なあらゆる計算を実行し、これらの値を使用してアニメーション化するオブジェクトのプロパティを設定します。
現在のフレームの表現時間を取得するには、このイベントに関連付けられている EventArgs を、RenderingEventArgs としてキャストできます。これにより、現在のフレームのレンダリング時間を取得するために使用できる RenderingTime プロパティが提供されます。
詳細については、Rendering のページを参照してください。