C#/WPF

C# WPF Ripple Effect (원형으로 퍼져 나가는 효과)

sheepone 2021. 11. 25. 16:32
반응형

효과

버튼이나 클릭 하는 부분에 사용하면 효과적입니다.

 

디자이너 사용

    <Grid>
        <l:RippleEffectDecorator Background="Green" HighlightBackground="LightGreen" Margin="30,30,397,139">
        </l:RippleEffectDecorator>
    </Grid>

 

디자이너 스타일 등록

   <Style TargetType="{x:Type l:RippleEffectDecorator}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type l:RippleEffectDecorator}">
                        <Grid x:Name="PART_grid" ClipToBounds="True" Background="{TemplateBinding Background}" Width="{Binding ElementName=PART_contentpresenter, Path=ActualWidth}" 
                              Height="{Binding ElementName=PART_contentpresenter, Path=ActualHeight}">
                            <Ellipse x:Name="PART_ellipse" Fill="{Binding Path=HighlightBackground, RelativeSource={RelativeSource TemplatedParent}}" 
                                     Width="0" Height="{Binding Path=Width, RelativeSource={RelativeSource Self}}" HorizontalAlignment="Left" VerticalAlignment="Top"/>

                            <ContentPresenter x:Name="PART_contentpresenter" />

                            <Grid.Resources>
                                <Storyboard x:Key="PART_animation" Storyboard.TargetName="PART_ellipse">
                                    <DoubleAnimation Storyboard.TargetProperty="Width" From="0" />
                                    <ThicknessAnimation Storyboard.TargetProperty="Margin" />
                                    <DoubleAnimation BeginTime="0:0:1" Duration="0:0:0.25" Storyboard.TargetProperty="Opacity" From="1" To="0" />
                                    <DoubleAnimation Storyboard.TargetProperty="Width" To="0" BeginTime="0:0:1.25" Duration="0:0:0" />
                                    <DoubleAnimation BeginTime="0:0:1.25" Duration="0:0:0" Storyboard.TargetProperty="Opacity" To="1" />
                                </Storyboard>
                            </Grid.Resources>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

 

소스 코드 추가

	public class RippleEffectDecorator : ContentControl
	{
		static RippleEffectDecorator()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(RippleEffectDecorator), new FrameworkPropertyMetadata(typeof(RippleEffectDecorator)));
		}

		public Brush HighlightBackground
		{
			get { return (Brush)GetValue(HighlightBackgroundProperty); }
			set { SetValue(HighlightBackgroundProperty, value); }
		}

		// Using a DependencyProperty as the backing store for HighlightBackground.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty HighlightBackgroundProperty =
			DependencyProperty.Register("HighlightBackground", typeof(Brush), typeof(RippleEffectDecorator), new PropertyMetadata(Brushes.White));

		Ellipse ellipse;
		Grid grid;
		Storyboard animation;

		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();

			ellipse = GetTemplateChild("PART_ellipse") as Ellipse;
			grid = GetTemplateChild("PART_grid") as Grid;
			animation = grid.FindResource("PART_animation") as Storyboard;

			this.AddHandler(MouseDownEvent, new RoutedEventHandler((sender, e) =>
			{
				var targetWidth = Math.Max(ActualWidth, ActualHeight) * 2;
				var mousePosition = (e as MouseButtonEventArgs).GetPosition(this);
				var startMargin = new Thickness(mousePosition.X, mousePosition.Y, 0, 0);
				//set initial margin to mouse position
				ellipse.Margin = startMargin;
				//set the to value of the animation that animates the width to the target width
				(animation.Children[0] as DoubleAnimation).To = targetWidth;
				//set the to and from values of the animation that animates the distance relative to the container (grid)
				(animation.Children[1] as ThicknessAnimation).From = startMargin;
				(animation.Children[1] as ThicknessAnimation).To = new Thickness(mousePosition.X - targetWidth / 2, mousePosition.Y - targetWidth / 2, 0, 0);
				ellipse.BeginStoryboard(animation);
			}), true);
		}
	}

 

예제 파일

WpfApp3.zip
0.27MB

 

출처 : https://github.com/Domysee/WpfCustomControls

 

GitHub - Domysee/WpfCustomControls

Contribute to Domysee/WpfCustomControls development by creating an account on GitHub.

github.com

 

반응형

'C# > WPF' 카테고리의 다른 글

런타임중에 XAML 로드하기 (Loading XAML at runtime)  (0) 2021.12.15
C# WPF 3D Button 꾸미기  (0) 2021.12.07