C# UWP xaml涟漪效果(android效果)动画

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

我尝试在UWP应用程序中编写一个Android效果(ripple)。所以我在网格内创建了一个椭圆几何(在我的用户控件中),但是当椭圆几何的RadiusX和RadiusY播放它们的动画时,我的椭圆几何从网格中生长出来。。。 我试图用一个可见区域来限制路径,并将其剪辑到路径上,但没有成功

这里是我的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.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);
}