■ AnimatedVisualPlayer 엘리먼트를 사용해 로띠 애니메이션을 만드는 방법을 보여준다.
AnimatedVisualPlayer는 Adobe AfterEffects를 사용하여 생성되고 Lottie-Windows를 사용하여 Microsoft.UI.Composition 개체로 변환된 애니메이션을 사용한다.
여기에 사용된 CompositionShapes는 Windows 10 버전 17763+에서 지원되므로 AnimatedVisualPlayer는 소스를 사용할 수 없을 때 이미지로 대체된다.
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
<?xml version="1.0" encoding="utf-8"?> <Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:TestProject" Title="TestProject"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Border HorizontalAlignment="Center" Width="400" Height="400" BorderThickness="5" BorderBrush="{ThemeResource ToolTipBorderThemeBrush}" Background="LightGray"> <AnimatedVisualPlayer Name="player" AutoPlay="False"> <AnimatedVisualPlayer.Source> <local:LottieLogo1 /> </AnimatedVisualPlayer.Source> <AnimatedVisualPlayer.FallbackContent> <DataTemplate> <Image Source="/IMAGE/LottieLogo1.png"/> </DataTemplate> </AnimatedVisualPlayer.FallbackContent> </AnimatedVisualPlayer> </Border> <Grid HorizontalAlignment="Center" Margin="0 20 0 0" Width="400"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Button Name="playButton" Grid.Column="0" HorizontalAlignment="Stretch" Margin="10" ToolTipService.ToolTip="Play"> <SymbolIcon Symbol="Play" /> </Button> <ToggleButton Name="pauseButton" Grid.Column="1" HorizontalAlignment="Stretch" Margin="10" IsThreeState="False" ToolTipService.ToolTip="Pause"> <SymbolIcon Symbol="Pause" /> </ToggleButton> <Button x:Name="stopButton" Grid.Column="2" HorizontalAlignment="Stretch" Margin="10" ToolTipService.ToolTip="Stop"> <SymbolIcon Symbol="Stop" /> </Button> <Button x:Name="reverseButton" Grid.Column="3" HorizontalAlignment="Stretch" Margin="10" ToolTipService.ToolTip="Reverse"> <SymbolIcon Symbol="Previous" /> </Button> </Grid> </StackPanel> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
using Microsoft.UI.Xaml; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public sealed partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); this.playButton.Click += playButton_Click; this.pauseButton.Checked += pauseButton_Checked; this.pauseButton.Unchecked += pauseButton_Unchecked; this.stopButton.Click += stopButton_Click; this.reverseButton.Click += reverseButton_Click; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event #region Play 버튼 클릭시 처리하기 - playButton_Click(sender, e) /// <summary> /// Play 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void playButton_Click(object sender, RoutedEventArgs e) { this.player.PlaybackRate = 1; EnsurePlaying(); } #endregion #region Pause 버튼 체크시 처리하기 - pauseButton_Checked(sender, e) /// <summary> /// Pause 버튼 체크시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void pauseButton_Checked(object sender, RoutedEventArgs e) { this.player.Pause(); } #endregion #region Pause 버튼 체크 해제시 처리하기 - pauseButton_Unchecked(sender, e) /// <summary> /// Pause 버튼 체크 해제시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void pauseButton_Unchecked(object sender, RoutedEventArgs e) { this.player.Resume(); } #endregion #region Stop 버튼 클릭시 처리하기 - stopButton_Click(sender, e) /// <summary> /// Stop 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void stopButton_Click(object sender, RoutedEventArgs e) { this.player.Stop(); this.pauseButton.IsChecked = false; } #endregion #region Reverse 버튼 클릭시 처리하기 - reverseButton_Click(sender, e) /// <summary> /// Reverse 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void reverseButton_Click(object sender, RoutedEventArgs e) { this.player.PlaybackRate = -1; EnsurePlaying(); } #endregion //////////////////////////////////////////////////////////////////////////////// Function #region 재생 보장하기 - EnsurePlaying() /// <summary> /// 재생 보장하기 /// </summary> private void EnsurePlaying() { if(this.pauseButton.IsChecked.Value) { this.pauseButton.IsChecked = false; } else { if(!this.player.IsPlaying) { _ = this.player.PlayAsync(fromProgress : 0, toProgress : 1, looped : false); } } } #endregion } } |