728x90
반응형
728x170
■ 이미지 롤 애니메이션(Roll Animation)을 사용하는 방법을 보여준다.
▶ ImageRollControl.xaml
<UserControl Name="userControl" x:Class="TestProject.ImageRollControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ClipToBounds="True">
<Canvas
Width="{Binding ElementName=userControl, Path=ActualWidth}"
Height="{Binding ElementName=userControl, Path=ActualHeight}">
<Image Name="image"
Width="{Binding ElementName=userControl, Path=ActualWidth}"
Height="{Binding ElementName=userControl, Path=ActualHeight}"
Source="{Binding ElementName=userControl, Path=ImageSource}"
Stretch="Fill" />
<Canvas Name="wrapCanvas"
Background="White"
Width="{Binding ElementName=userControl, Path=ActualWidth}"
Height="{Binding ElementName=userControl, Path=RollSize}">
<Canvas Name="rollCanvas"
Width="{Binding ElementName=userControl, Path=ActualWidth}"
Height="{Binding ElementName=userControl, Path=RollSize}">
<Line Name="line1"
X1="0"
Y1="0"
X2="{Binding ElementName=userControl, Path=ActualWidth}"
Y2="0"
StrokeThickness="1"
Stroke="Black"
Visibility="Collapsed">
<Line.BitmapEffect>
<BlurBitmapEffect
Radius="1"
KernelType="Box" />
</Line.BitmapEffect>
</Line>
<Line Name="line2"
X1="0"
Y1="50"
X2="{Binding ElementName=userControl, Path=ActualWidth}"
Y2="50"
StrokeThickness="1"
Stroke="Black"
Visibility="Collapsed">
<Line.BitmapEffect>
<BlurBitmapEffect
Radius="1"
KernelType="Box" />
</Line.BitmapEffect>
</Line>
</Canvas>
</Canvas>
</Canvas>
</UserControl>
▶ ImageRollControl.xaml
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace TestProject
{
/// <summary>
/// 이미지 롤 컨트롤
/// </summary>
public partial class ImageRollControl : UserControl
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 이미지 속성 - ImageSourceProperty
/// <summary>
/// 이미지 소스 속성
/// </summary>
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register
(
"ImageSource",
typeof(ImageSource),
typeof(ImageRollControl),
new UIPropertyMetadata
(
null,
null,
null,
false
)
);
#endregion
#region 롤링 속도 속성 - RollSpeedProperty
/// <summary>
/// 롤링 속도 속성
/// </summary>
public static readonly DependencyProperty RollSpeedProperty = DependencyProperty.Register
(
"RollSpeed",
typeof(double),
typeof(ImageRollControl),
new UIPropertyMetadata
(
15d,
null,
null,
false
)
);
#endregion
#region 롤 크기 속성 - RollSizeProperty
/// <summary>
/// 롤 크기 속성
/// </summary>
public static readonly DependencyProperty RollSizeProperty = DependencyProperty.Register
(
"RollSize",
typeof(double),
typeof(ImageRollControl),
new UIPropertyMetadata
(
50d,
null,
null,
false
)
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 타이머
/// </summary>
private DispatcherTimer timer = null;
/// <summary>
/// 롤 위쪽
/// </summary>
private double rollTop = 0;
/// <summary>
/// 임시 이미지
/// </summary>
private Image temporaryImage = null;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 이미지 소스 - ImageSource
/// <summary>
/// 이미지 소스
/// </summary>
public ImageSource ImageSource
{
get
{
return (ImageSource)GetValue(ImageSourceProperty);
}
set
{
SetValue(ImageSourceProperty, value);
}
}
#endregion
#region 롤링 속도 - RollSpeed
/// <summary>
/// 롤링 속도
/// </summary>
public double RollSpeed
{
get
{
return (double)GetValue(RollSpeedProperty);
}
set
{
SetValue(RollSpeedProperty, value);
}
}
#endregion
#region 롤 크기 - RollSize
/// <summary>
/// 롤 크기
/// </summary>
public double RollSize
{
get
{
return (double)GetValue(RollSizeProperty);
}
set
{
SetValue(RollSizeProperty, value);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - ImageRollControl()
/// <summary>
/// 생성자
/// </summary>
public ImageRollControl()
{
InitializeComponent();
Loaded += UserControl_Loaded;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
//////////////////////////////////////////////////////////////////////////////// Function
#region 시작하기 - Start()
/// <summary>
/// 시작하기
/// </summary>
public void Start()
{
if(ImageSource == null)
{
return;
}
if(this.timer.IsEnabled)
{
return;
}
this.rollTop = 0;
this.timer.Start();
}
#endregion
#region 중단하기 - Stop()
/// <summary>
/// 중단하기
/// </summary>
public void Stop()
{
if(ImageSource == null)
{
return;
}
if(!this.timer.IsEnabled)
{
return;
}
this.timer.Stop();
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 사용자 컨트롤 로드시 처리하기 - UserControl_Loaded(sender, e)
/// <summary>
/// 사용자 컨트롤 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
ScaleTransform scaleTransform = new ScaleTransform(1, -1, 0, 0);
this.temporaryImage = new Image();
this.temporaryImage.Source = ImageSource;
this.temporaryImage.Width = ActualWidth;
this.temporaryImage.Height = ActualHeight;
this.temporaryImage.RenderTransform = scaleTransform;
this.image.Clip = new RectangleGeometry(new Rect(0, 0, ActualWidth, this.rollTop));
LinearGradientBrush maskBrush = new LinearGradientBrush();
maskBrush.StartPoint = new Point(0, 0);
maskBrush.EndPoint = new Point(0, 1);
GradientStop blackStop1 = new GradientStop(Color.FromArgb(30 , 255, 255, 255), 0.0);
GradientStop transparentStop = new GradientStop(Color.FromArgb(175, 255, 255, 255), 0.5);
GradientStop blackStop2 = new GradientStop(Color.FromArgb(100, 255, 255, 255), 1.0);
GradientStop blackStop3 = new GradientStop(Colors.Black , 0.0);
GradientStop blackStop4 = new GradientStop(Colors.Black , 0.9);
maskBrush.GradientStops.Add(blackStop1);
maskBrush.GradientStops.Add(transparentStop);
maskBrush.GradientStops.Add(blackStop2);
maskBrush.GradientStops.Add(blackStop3);
maskBrush.GradientStops.Add(blackStop4);
this.rollCanvas.OpacityMask = maskBrush;
this.timer = new DispatcherTimer();
this.timer.Interval = TimeSpan.FromSeconds(.1);
this.timer.Tick += timer_Tick;
}
#endregion
#region 타이머 틱 처리하기 - timer_Tick(sender, e)
/// <summary>
/// 타이머 틱 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void timer_Tick(object sender, EventArgs e)
{
if(this.rollTop + RollSpeed > ActualHeight)
{
this.timer.Stop();
this.line1.Visibility = Visibility.Collapsed;
this.line2.Visibility = Visibility.Collapsed;
this.wrapCanvas.Visibility = Visibility.Collapsed;
return;
}
double height;
if(this.rollTop + RollSize > ActualHeight)
{
height = ActualHeight - this.rollTop;
}
else
{
height = RollSize;
}
this.rollCanvas.Height = height;
this.wrapCanvas.Height = height;
this.line2.Y1 = height;
this.line2.Y2 = height;
this.image.Clip = new RectangleGeometry(new Rect(0, 0, ActualWidth, this.rollTop + height));
this.line1.Visibility = Visibility.Visible;
this.line2.Visibility = Visibility.Visible;
this.wrapCanvas.Visibility = Visibility.Visible;
Rect clippingRect = new Rect(0, this.rollTop, ActualWidth, height);
this.temporaryImage.Clip = new RectangleGeometry(clippingRect);
VisualBrush brush = new VisualBrush(this.temporaryImage as Visual);
this.rollCanvas.Background = brush;
Canvas.SetTop(this.wrapCanvas, this.rollTop);
this.rollTop += RollSpeed;
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 리소스 URI 구하기 - GetResourceURI(assemblyName, resourcePath)
/// <summary>
/// 리소스 URI 구하기
/// </summary>
/// <param name="assemblyName">어셈블리명</param>
/// <param name="resourcePath">리소스 경로</param>
/// <returns>리소스 URI</returns>
private Uri GetResourceURI(string assemblyName, string resourcePath)
{
if(string.IsNullOrEmpty(assemblyName))
{
return new Uri(string.Format("pack://application:,,,/{0}", resourcePath));
}
else
{
return new Uri(string.Format("pack://application:,,,/{0};component/{1}", assemblyName, resourcePath));
}
}
#endregion
#region 비트맵 이미지 구하기 - GetBitmapImage(sourceURI)
/// <summary>
/// 비트맵 이미지 구하기
/// </summary>
/// <param name="sourceURI">소스 URI</param>
/// <returns>비트맵 이미지</returns>
private BitmapImage GetBitmapImage(Uri sourceURI)
{
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = sourceURI;
bitmap.CacheOption = BitmapCacheOption.OnDemand;
bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bitmap.EndInit();
return bitmap;
}
#endregion
}
}
▶ MainWindow.xaml
<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="clr-namespace:TestProject"
Width="800"
Height="600"
Title="이미지 롤 애니메이션(Roll Animation) 사용하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Grid>
<Border
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderThickness="1"
BorderBrush="DarkGray">
<local:ImageRollControl x:Name="imageRollControl"
ImageSource="IMAGE\sample.png"
Width="600"
Height="400" />
</Border>
<StackPanel
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="10"
Orientation="Horizontal">
<Button Name="startButton"
Width="100"
Height="30"
Content="Start" />
<Button Name="stopButton"
Margin="10 0 0 0"
Width="100"
Height="30"
Content="Stop" />
</StackPanel>
</Grid>
</Window>
▶ MainWindow.xaml.cs
using System.Windows;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
this.startButton.Click += startButton_Click;
this.stopButton.Click += stopButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 시작 버튼 클릭시 처리하기 - startButton_Click(sender, e)
/// <summary>
/// 시작 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void startButton_Click(object sender, RoutedEventArgs e)
{
this.startButton.IsEnabled = false;
this.stopButton.IsEnabled = true;
this.imageRollControl.Start();
}
#endregion
#region 중단 버튼 클릭시 처리하기 - stopButton_Click(sender, e)
/// <summary>
/// 중단 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void stopButton_Click(object sender, RoutedEventArgs e)
{
this.startButton.IsEnabled = true;
this.stopButton.IsEnabled = false;
this.imageRollControl.Stop();
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] 리소스 병합하기 (0) | 2021.02.12 |
---|---|
[C#/WPF] 애니메이션 메시지 컨트롤 사용하기 (0) | 2021.02.11 |
[C#/WPF] 3D 애니메이션 시계 사용하기 (0) | 2021.02.11 |
[C#/WPF] SVG 파일을 XAML로 변환하기 (0) | 2021.02.10 |
[C#/WPF] 이미지 물방울 애니메이션(Drip Animation) 사용하기 (0) | 2021.02.09 |
[C#/WPF] UI 자동화 사용하기 (0) | 2021.02.08 |
[C#/WPF] 모니터 추가/제거시 이벤트 처리하기 (0) | 2021.02.08 |
[C#/WPF] Shape 클래스 : 커스텀 호(Arc) 만들기 (0) | 2021.02.07 |
[C#/WPF] DrawingContext 클래스 : DrawGlyphRun 메소드를 사용해 텍스트 그리기 (0) | 2021.02.07 |
[C#/WPF] Shape 클래스 : DefiningGeometry 속성을 사용해 커스텀 도형 만들기 (0) | 2021.02.07 |
댓글을 달아 주세요