C# UWP xaml涟漪效果(android效果)动画
我尝试在UWP应用程序中编写一个Android效果(ripple)。所以我在网格内创建了一个椭圆几何(在我的用户控件中),但是当椭圆几何的RadiusX和RadiusY播放它们的动画时,我的椭圆几何从网格中生长出来。。。 我试图用一个可见区域来限制路径,并将其剪辑到路径上,但没有成功 这里是我的XAML代码:C# UWP xaml涟漪效果(android效果)动画,c#,android,xaml,animation,uwp,C#,Android,Xaml,Animation,Uwp,我尝试在UWP应用程序中编写一个Android效果(ripple)。所以我在网格内创建了一个椭圆几何(在我的用户控件中),但是当椭圆几何的RadiusX和RadiusY播放它们的动画时,我的椭圆几何从网格中生长出来。。。 我试图用一个可见区域来限制路径,并将其剪辑到路径上,但没有成功 这里是我的XAML代码: <UserControl x:Class="UIComponents.POIButton" xmlns="http://schemas.microsoft.com/winfx/200
<UserControl
x:Class="UIComponents.POIButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UIComponents"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="100"
d:DesignWidth="650" Background="White">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Gray">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<!--Animation Ellipse-->
<Grid x:Name="ellipseContainer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="0" Grid.ColumnSpan="3">
<Path x:Name="path" Fill="Red" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<Path.Data>
<EllipseGeometry x:Name="circleGeometry" Center="0,0" RadiusX="5" RadiusY="5" />
</Path.Data>
</Path>
</Grid>
<Rectangle x:Name="clickableRect" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" PointerPressed="clickableRect_PointerPressed" Fill="Transparent" Tapped="clickableRect_Tapped"/>
</Grid>
<UserControl.Resources>
<Storyboard x:Name="RipplePath">
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="RadiusX" Storyboard.TargetName="circleGeometry">
<EasingDoubleKeyFrame KeyTime="0" Value="5"/>
<EasingDoubleKeyFrame KeyTime="0:0:10" Value="200"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="RadiusY" Storyboard.TargetName="circleGeometry">
<EasingDoubleKeyFrame KeyTime="0" Value="5"/>
<EasingDoubleKeyFrame KeyTime="0:0:10" Value="200"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
this.InitializeComponent();
var visual = ElementCompositionPreview.GetElementVisual(this);
visual.Clip = visual.Compositor.CreateInsetClip();
结果如下:
非常感谢您的帮助:)
================尝试Justin XL的解决方案:结果:
感谢Justin的帮助,似乎矩形几何体也被动画化了:
但是没有什么是超出网格的
Xaml代码是:
<UserControl
x:Class="UIComponents.POIButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UIComponents"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="100"
d:DesignWidth="650" Background="White">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Gray">
<Grid.Clip>
<RectangleGeometry Rect="0,0,650,100" />
</Grid.Clip> ...
public POIButton()
{
this.InitializeComponent();
var visual = ElementCompositionPreview.GetElementVisual(this);
visual.Clip = visual.Compositor.CreateInsetClip();
}
======================XAML结果:
此XAML代码不能产生正确的效果:
<UserControl
x:Class="UIComponents.POIButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UIComponents"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Height="100"
Width="650" Background="White">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Gray">
<Grid.Clip>
<RectangleGeometry Rect="0,0,650,100" />
</Grid.Clip>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<!--Animation Ellipse-->
<Grid x:Name="ellipseContainer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="0" Grid.ColumnSpan="3">
<Path x:Name="path" Fill="Red" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<Path.Data>
<EllipseGeometry x:Name="circleGeometry" Center="0,0" RadiusX="5" RadiusY="5" />
</Path.Data>
</Path>
</Grid>...
制作:
感谢@Justin XL对它的帮助:)您只需将控件剪裁到其边界之外即可。这可以通过以下两种方式实现:
<Grid x:Name="Root" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Gray">
<Grid.Clip>
<RectangleGeometry Rect="0,0,200,80" />
</Grid.Clip>
在代码隐藏中使用新的合成API。注意:使用XAML方法,如果控件的大小发生更改,则需要通过绑定或代码隐藏手动更新宽度和高度,而使用组合则不需要
另外,我注意到您使用了在UI线程上运行的路径动画(例如,EnableDependentAnimation
)。这可以用带有ScaleTransform
动画的椭圆
来代替,通常推荐使用这种方法,因为它的性能要好得多
具有
XamlLight
由于您是为UWP开发的,因此必须了解该平台可以做什么,以及UWP实现类似效果的方式,同时还要尊重其自己的流畅设计系统
在15063
中引入的新类的帮助下,我创建了如下所示的FluentButton
控件。您会注意到灯光跟随鼠标光标,单击/轻触时会产生涟漪
第二部分由定制的XamlLight
完成,我称之为RippleXamlLight
,这就是它的实现方式-
首先,创建一个继承自XamlLight
的类
public class RippleXamlLight : XamlLight
然后,在其OnConnected
覆盖方法中,创建一个SpotLight
实例和一个Vector3
动画,用于设置灯光的偏移量的动画。它还将负责订阅指针事件,例如PointerPressed
protected override void OnConnected(UIElement newElement)
{
_compositor = Window.Current.Compositor;
var spotLight = CreateSpotLight();
CompositionLight = spotLight;
_lightRippleOffsetAnimation = CreateLightRippleOffsetAnimation();
SubscribeToPointerEvents();
AddTargetElement(GetId(), newElement);
...
}
}
最后,在按下控件时启动动画。偏移
值由指针位置和基于控件大小计算的\u rippleOffsetZ
提供
private void OnPointerPressed(object sender, PointerRoutedEventArgs e) =>
StartLightRippleOffsetAnimation(e.GetCurrentPoint((UIElement)sender).Position.ToVector2());
private void StartLightRippleOffsetAnimation(Vector2 position)
{
var startingPoisition = new Vector3(position, 0.0f);
_lightRippleOffsetAnimation?.InsertKeyFrame(0.0f, startingPoisition);
_lightRippleOffsetAnimation?.InsertKeyFrame(1.0f, new Vector3(position.X, position.Y, _rippleOffsetZ));
CompositionLight?.StartAnimation("Offset", _lightRippleOffsetAnimation);
}
如果我解释得不够清楚,这是给你参考的答案。:) 这不是您问题的确切答案,但您应该在上查看此示例中的Color Bloom动画。它可能有一些用处。@JustinXL还有一个与问题相关的UIBTW,XAML方法也应该有效(我用你的精确代码尝试过,但效果很好),你的代码中一定有其他东西导致了这个问题。谢谢,我在第一部分中用矩形几何体网格上的剪辑尝试了你的解决方案,但是,当动画播放器,它似乎是矩形动画太。。。我发布了结果,您只需要xaml或cs方法,而不是两者都需要。此外,如果使用xaml方法,则需要确保定义了控件的宽度和高度。xaml仅定义了d:DesignHeight
和d:DesignWidth
。它们需要用高度
和宽度
来替换。我按照您在Xaml中的建议做了,但似乎不起作用。但是CS代码工作得很好,非常感谢:)。我将检查在RadiusX和RadiusY上播放动画时,ellipseGeometry动画是否会消耗大量cpu/gpu性能。
protected override void OnConnected(UIElement newElement)
{
_compositor = Window.Current.Compositor;
var spotLight = CreateSpotLight();
CompositionLight = spotLight;
_lightRippleOffsetAnimation = CreateLightRippleOffsetAnimation();
SubscribeToPointerEvents();
AddTargetElement(GetId(), newElement);
...
}
}
private void OnPointerPressed(object sender, PointerRoutedEventArgs e) =>
StartLightRippleOffsetAnimation(e.GetCurrentPoint((UIElement)sender).Position.ToVector2());
private void StartLightRippleOffsetAnimation(Vector2 position)
{
var startingPoisition = new Vector3(position, 0.0f);
_lightRippleOffsetAnimation?.InsertKeyFrame(0.0f, startingPoisition);
_lightRippleOffsetAnimation?.InsertKeyFrame(1.0f, new Vector3(position.X, position.Y, _rippleOffsetZ));
CompositionLight?.StartAnimation("Offset", _lightRippleOffsetAnimation);
}