속성 애니메이션 기술 개요
이 항목에서는 storyboard, 로컬 애니메이션, 클록 및 프레임당 애니메이션 등, 속성에 애니메이션 효과를 주는 다양한 접근 방법을 설명합니다.
필수 구성 요소
이 항목을 이해하려면 애니메이션 개요에 설명된 기본 애니메이션 기능에 대해 잘 알고 있어야 합니다.
애니메이션 효과를 주는 다양한 방법
속성에 애니메이션 효과를 주는 다양한 시나리오가 있으므로 WPF에서는 속성에 애니메이션 효과를 주는 몇 가지 접근 방법을 제공합니다.
각 접근 방법에 대해 다음 표에는 인스턴스별로, 스타일, 컨트롤 템플릿 또는 데이터 템플릿에서 사용할 수 있는지, XAML에서 사용할 수 있는지 여부 및 해당 접근 방식을 사용하여 애니메이션을 대화형으로 제어할 수 있는지가 나와 있습니다. "인스턴스별"은 스타일, 컨트롤 템플릿 또는 데이터 템플릿이 아닌 개체의 인스턴스에 직접 애니메이션 또는 storyboard를 적용하는 기술을 나타냅니다.
애니메이션 기술 | 시나리오 | XAML 지원 | 대화형으로 제어 가능 |
---|---|---|---|
Storyboard 애니메이션 | 인스턴스별, Style, ControlTemplate, DataTemplate | 예 | 예 |
로컬 애니메이션 | 인스턴스별 | 예 | 예 |
클록 애니메이션 | 인스턴스별 | 예 | 예 |
프레임당 애니메이션 | 인스턴스별 | 예 | 해당 없음 |
Storyboard 애니메이션
XAML에서 애니메이션을 정의하고 적용하거나, 애니메이션이 시작된 후 대화형으로 제어하거나, 복잡한 애니메이션 트리를 만들거나, Style, ControlTemplate 또는 DataTemplate에서 애니메이션 효과를 주려는 경우 Storyboard을 사용합니다. Storyboard를 통해 개체에 애니메이션 효과를 주려면 FrameworkElement 또는 FrameworkContentElement이거나 FrameworkElement 또는 FrameworkContentElement를 설정하는 데 사용해야 합니다. 자세한 내용은 Storyboard 개요를 참조하세요.
Storyboard는 포함된 애니메이션에 대한 대상 지정 정보를 제공하는 특수한 유형의 컨테이너 Timeline입니다. Storyboard로 애니메이션 효과를 주려면 다음 세 단계를 완료합니다.
Storyboard 및 하나 이상의 애니메이션을 선언합니다.
TargetName 및 TargetProperty 연결된 속성을 사용하여 각 애니메이션의 대상 개체 및 속성을 지정합니다.
(코드만 해당) FrameworkElement 또는 FrameworkContentElement에 대해 NameScope을 정의합니다. FrameworkElement 또는 FrameworkContentElement로 애니메이션 효과를 적용할 개체의 이름을 등록합니다.
Storyboard를 시작합니다.
Storyboard를 시작하면 애니메이션을 지정하는 대상 속성에 애니메이션이 적용된 후 시작됩니다. Storyboard는 두 가지 방법으로 시작할 수 있습니다. Storyboard 클래스에서 제공하는 Begin 메서드를 사용하거나 BeginStoryboard 작업을 사용할 수 있습니다. XAML에서 애니메이션을 적용하는 유일한 방법은 BeginStoryboard 작업을 사용하는 것입니다. BeginStoryboard 동작은 EventTrigger, 속성 Trigger 또는 DataTrigger에서 사용할 수 있습니다.
다음 표에서는 각 Storyboard 시작 기술이 지원되는 다양한 위치, 즉 인스턴스별, 스타일, 컨트롤 템플릿 및 데이터 템플릿에 대해 설명합니다.
storyboard 시작 방법... | 인스턴스별 | 스타일 | 컨트롤 템플릿 | 데이터 템플릿 | 예제 |
---|---|---|---|---|---|
BeginStoryboard 및 EventTrigger | 예 | 예 | 예 | 예 | 스토리보드를 사용하여 속성에 애니메이션 효과 주기 |
BeginStoryboard 및 Trigger 속성 | 예 | 예 | 예 | 예 | 속성 값 변경 시 애니메이션 트리거 |
BeginStoryboard 및 DataTrigger | 예 | 예 | 예 | 예 | 방법: 데이터가 변경될 때 애니메이션 트리거Changes |
Begin 메서드 | 예 | 예 | 예 | 예 | 스토리보드를 사용하여 속성에 애니메이션 효과 주기 |
Storyboard 개체에 대한 자세한 내용은 스토리보드 개요를 참조하세요.
로컬 애니메이션
로컬 애니메이션은 Animatable 개체의 종속성 속성에 애니메이션 효과를 주는 편리한 방법을 제공합니다. 속성에 단일 애니메이션을 적용하며 애니메이션이 시작된 후에 대화형으로 제어할 필요가 없으면 로컬 애니메이션을 사용합니다. 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.
*/
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;
};
};
}
}
}
}
/*
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.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
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
클록 애니메이션
Storyboard를 사용하지 않고 애니메이션 효과를 주려고 하며 애니메이션이 시작된 후에 복잡한 타이밍 트리를 만들거나 애니메이션을 대화형으로 제어하려는 경우 Clock 개체를 사용합니다. Clock 개체를 사용하여 Animatable 개체의 종속성 속성에 애니메이션 효과를 줄 수 있습니다.
Clock 개체를 사용하여 스타일, 컨트롤 템플릿 또는 데이터 템플릿에 직접 애니메이션 효과를 줄 수는 없습니다. (애니메이션 및 타이밍 시스템은 실제로 Clock 개체를 사용하여 스타일, 컨트롤 템플릿 및 데이터 템플릿에 애니메이션 효과를 주지만 Storyboard에서 해당 Clock 개체를 만들어야 합니다. 개체 Storyboard과(와) 개체 Clock 간의 관계에 대한 자세한 내용은 애니메이션 및 타이밍 시스템 개요를 참조하세요.)
단일 Clock을 속성에 적용하려면 다음 단계를 완료합니다.
AnimationTimeline 개체 만들기
AnimationTimeline의 CreateClock 메서드를 사용하여 AnimationClock을 만듭니다.
애니메이션 효과를 주려는 개체의 ApplyAnimationClock 메서드를 사용하여 지정한 속성에 AnimationClock을 적용합니다.
다음 예제에서는 AnimationClock을 만들고 두 개의 유사한 속성에 적용하는 방법을 보여 줍니다.
/*
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);
}
}
}
'
' This example shows how to create and apply
' an AnimationClock.
'
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 ReadOnly myScaleTransform As ScaleTransform
Public Sub New()
WindowTitle = "Opacity Animation Example"
Background = Brushes.White
Dim myStackPanel As New StackPanel With {
.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 With {
.Margin = New Thickness(50),
.HorizontalAlignment = HorizontalAlignment.Left,
.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)
Content = myStackPanel
End Sub
' Create and apply and animation when the button is clicked.
Private Sub myButton_Clicked(sender As Object, e As RoutedEventArgs)
' Create a DoubleAnimation to animate the
' ScaleTransform.
Dim myAnimation As New DoubleAnimation(1, 5, New Duration(TimeSpan.FromSeconds(5))) With {
.AutoReverse = True
} ' "To" value - "From" value
' 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
타이밍 트리를 만들고 속성에 애니메이션 효과를 주는 데 사용하려면 다음 단계를 완료합니다.
ParallelTimeline 및 AnimationTimeline 개체를 사용하여 타이밍 트리를 만듭니다.
루트 ParallelTimeline의 CreateClock을 사용하여 ClockGroup을 만듭니다.
ClockGroup의 Children을 반복하고 자식 Clock 개체를 적용합니다. 각 AnimationClock 자식 요소에 대해 애니메이션 효과를 주려는 개체의 ApplyAnimationClock 메서드를 사용하여 지정한 속성에 AnimationClock을 적용합니다.
클록 개체에 대한 자세한 내용은 애니메이션 및 타이밍 시스템 개요를 참조하세요.
프레임당 애니메이션: 애니메이션 및 타이밍 시스템 무시
이 접근 방법은 WPF 애니메이션 시스템을 완전히 무시해야 할 때 사용합니다. 이 방법에 대한 한 가지 시나리오는 애니메이션의 각 단계에서 개체 상호 작용의 마지막 집합에 따라 개체가 다시 계산되어야 하는 물리학 애니메이션입니다.
스타일, 컨트롤 템플릿 또는 데이터 템플릿 내부에서는 프레임당 애니메이션을 정의할 수 없습니다.
프레임별로 애니메이션 효과를 주려면 애니메이션 효과를 적용할 개체가 포함된 개체의 Rendering 이벤트에 등록합니다. 이 이벤트 처리기 메서드는 프레임마다 한 번씩 호출됩니다. WPF가 시각적 트리의 지속되는 렌더링 데이터를 컴퍼지션 트리로 마샬링할 때마다 이벤트 처리기 메서드가 호출됩니다.
이벤트 처리기에서 애니메이션 효과에 필요한 계산을 수행하고 이러한 값을 사용하여 애니메이션 효과를 적용하려는 개체의 속성을 설정합니다.
현재 프레임의 프레젠테이션 시간을 가져오려면 이 이벤트와 연결된 EventArgs를 현재 프레임의 렌더링 시간을 가져오는 데 사용할 수 있는 RenderingTime 속성을 제공하는 RenderingEventArgs로 캐스팅할 수 있습니다.
자세한 내용은 Rendering 페이지를 참조하세요.
참고 항목
.NET Desktop feedback