您可以在 ButtonTemplate 中使用
Canvas
来实现 RippleEffect。
<Canvas x:Name="Canvas"
Width="{Binding ActualWidth, ElementName=OuterCanvas, Mode=OneWay}"
Height="{Binding ActualHeight, ElementName=OuterCanvas, Mode=OneWay}"
Background="Transparent"
MouseLeftButtonDown="Canvas_MouseLeftButtonDown">
与
Ellipse
,也在 ButtonTemplate 中
<Ellipse x:Name="RippleEllipse"
Width="10"
Height="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Gray"
Opacity="1"
Visibility="Hidden"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/>
</Ellipse.RenderTransform>
</Ellipse>
使用
Storyboard
为 Ellipse
制作动画,以获得 Ripple 效果。
<Storyboard x:Key="RippleEffect" Completed="Storyboard_Completed">
<!-- Visibility -->
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.Visibility)" Duration="0:0:0.5">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
<!-- Scale animation -->
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:0.5">
<LinearDoubleKeyFrame KeyTime="100%" Value="10"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(ScaleTransform.ScaleY)" Duration="0:0:0.5">
<LinearDoubleKeyFrame KeyTime="100%" Value="10"/>
</DoubleAnimationUsingKeyFrames>
<!-- Opacity animation -->
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.Opacity)" Duration="0:0:0.5">
<LinearDoubleKeyFrame KeyTime="0:0:0" Value="1"/>
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
现在,需要将
Ellipse
移动到单击所在的位置,然后启动 Storyboard
。
private Storyboard _storyboard;
private Point _mousePosition;
private Ellipse _ellipse;
public RippleButton()
{
InitializeComponent();
// Get storyboard from RippleButton
_storyboard = (Storyboard)this.Resources["RippleEffect"];
}
private async void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Canvas _canvas = (Canvas)sender as Canvas;
if (_canvas != null)
{
_mousePosition = e.GetPosition(_canvas);
// Get the ellipse from the canvas
_ellipse = _canvas.Children[1] as Ellipse;
// Move the ellipse to the point where the mouse was clicked
_ellipse.SetValue(Canvas.LeftProperty, _mousePosition.X - _ellipse.ActualWidth / 2);
_ellipse.SetValue(Canvas.TopProperty, _mousePosition.Y - _ellipse.ActualHeight / 2);
await Task.Delay(100);
// Attach storyboard to the ellipse
Storyboard.SetTarget(_storyboard, _ellipse);
_storyboard.Begin();
}
}
private void Storyboard_Completed(object sender, EventArgs e)
{
_storyboard.Remove();
}
结果
一些注意事项:
Storyboard
动画具有静态值,因此Ripple效果在不同尺寸的Button
上看起来会有所不同。Ellipse
填充也是静态的,可以通过将Dependency Property
添加到Control
来更改。