이번 글에서는 WPF에서 애니메이션에 대해서 알아보겠습니다. WPF에서는 모든 컨트롤을 애니메이션 지원을 해줍니다. 움직이거나, 회전하거나, 크기가 변경되는 등등 애니메이션처럼 표현해줍니다. 애니메이션을 만들 땐 몇 가지 핵심적인 설정 값이 있습니다.
- From : 어디서
- To : 어디까지
- Duration : 애니메이션 시간(속도)
- AutoReverse : 처음으로 다시 돌아 갈 건지
- RepeatBehavior : 반복 여부
Behavior를 사용해서 컨트롤에 마우스 Enter 이벤트가 발생하면 UI 요소들의 크기를 커졌다 작아졌다 하는, 심장 박동 같은 애니메이션을 만들어 보도록 하겠습니다.
코드
우선 MainWindow.xaml에 컨트롤들을 몇 개 만들어 줍니다.
<Window x:Class="WpfAnimation.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:WpfAnimation"
xmlns:b="clr-namespace:WpfAnimation.Behavior"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800">
<StackPanel Orientation="Vertical">
<Button Content="hi"
Margin="5"
HorizontalAlignment="Center"
Width="100">
<i:Interaction.Behaviors>
<b:AnimationBehavior/>
</i:Interaction.Behaviors>
</Button>
<CheckBox Content="shake"
HorizontalAlignment="Center">
<i:Interaction.Behaviors>
<b:AnimationBehavior/>
</i:Interaction.Behaviors>
</CheckBox>
</StackPanel>
</Window>
그 다음 Behavior 폴더를 만든 뒤 그 안에 AnimationBehavior.cs를 만들어줍니다.
public class AnimationBehavior : Behavior<FrameworkElement>
{
public AnimationBehavior() { }
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.MouseEnter += OnMouseEnter;
AssociatedObject.MouseLeave += OnMouseLeave;
}
protected override void OnDetaching()
{
AssociatedObject.MouseEnter -= OnMouseEnter;
AssociatedObject.MouseLeave -= OnMouseLeave;
base.OnDetaching();
}
#region mouse enter, leave
private void OnMouseEnter(object sender, MouseEventArgs e)
{
StartScale();
}
private void OnMouseLeave(object sender, MouseEventArgs e)
{
StopScale();
}
#endregion
#region animation
private void StartScale()
{
if (AssociatedObject == null)
return;
if (!(AssociatedObject.RenderTransform is ScaleTransform))
{
AssociatedObject.RenderTransform = new ScaleTransform();
AssociatedObject.RenderTransformOrigin = new Point(0.5, 0.5); // 컨트롤 변형이 일어날 때 기준점.
}
DoubleAnimation anim = new DoubleAnimation
{
From = 0.9, // 시작
To = 1.1, // 끝
Duration = TimeSpan.FromMilliseconds(300), // 기간
AutoReverse = true, // 처음으로 돌아감
RepeatBehavior = RepeatBehavior.Forever, // 계속 반복
EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseInOut }, // 효과
};
AssociatedObject.RenderTransform.BeginAnimation(ScaleTransform.ScaleXProperty, anim); // x축 으로 수행
AssociatedObject.RenderTransform.BeginAnimation(ScaleTransform.ScaleYProperty, anim); // y축 으로 수행
}
private void StopScale()
{
if (AssociatedObject?.RenderTransform is ScaleTransform)
{
AssociatedObject.RenderTransform.BeginAnimation(ScaleTransform.ScaleXProperty, null);
AssociatedObject.RenderTransform.BeginAnimation(ScaleTransform.ScaleYProperty, null);
}
}
#endregion
}
MouseEnter와 MouseLeave를 사용하여 Mouse가 컨트롤에 Enter, Leave되는 이벤트를 받았습니다.
AssociatedObject의 RenderTransform 속성에 크기 조절을 하는 ScaleTransform을 생성해준 다음, 애니메이션의 설정 값이 담긴 DoubleAnimation 객체를 만들어 준 다음 ScaleTransform.BeginAnimation에 인자로 입력해줍니다.
실행
실행 시켜서 확인해봅니다.
애니메이션 효과를 여러 개 동시에 적용하고 싶으면 TransformGroup을 사용하면 된다고 합니다. 생각보다 간단하니 이 글에서는 다루진 않겠습니다.
github : https://github.com/3001ssw/c_sharp/tree/main/WPF/WPF_Basic/WpfAnimation

