【问题标题】:UWP xaml ripple Effect (android effect) animationUWP xaml 波纹效果(android 效果)动画
【发布时间】:2017-09-16 18:51:15
【问题描述】:

我尝试在 UWP 应用中编写 Android 效果(波纹)。所以我在网格内(在我的用户控件中)创建了一个 EllipseGeometry 但是当我的 ellipseGeometry 的 RadiusX 和 RadiusY 播放动画时,我的 EllipseGeometry 增长出我的网格...... 我试图用可见区域限制路径并将其剪辑到路径,但没有成功。

这是我的 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>

这是我的 Cs 代码:

private void clickableRect_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Point touchPosition = e.GetPosition(ellipseContainer);
        //RectangleGeometry visibleArea = new RectangleGeometry();
        //visibleArea.Rect = new Rect(0, 0, 650, 100);
        //path.Clip = visibleArea;
        Storyboard animation = this.FindName("RipplePath") as Storyboard;
        animation.Begin();

    }

这里,结果:

非常感谢您的帮助:)

============== 试试 Justin XL 的解决方案:结果:

感谢贾斯汀的帮助,矩形几何似乎也被动画化了:

但网格上没有任何东西。

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> ...

CS 代码是:

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>...

结果:

但 CS 代码工作正常(在 XAML 代码中注释 RectangleGeometry 行):

this.InitializeComponent();
        var visual = ElementCompositionPreview.GetElementVisual(this);
        visual.Clip = visual.Compositor.CreateInsetClip();

制作这个:

感谢@Justin XL 的帮助 :)

【问题讨论】:

  • 不是您问题的确切答案,但您应该在Github 上查看此示例中的 Color Bloom 动画。可能有点用处。
  • @JustinXL 又一个问题相关的用户界面
  • 顺便说一句,XAML 方法也应该可以工作(我用你的确切代码试过,它工作得很好),你的代码中一定有其他东西导致了这个问题。

标签: c# android xaml animation uwp


【解决方案1】:

您只需要剪辑控件以防止超出其边界。这可以通过使用来实现

<Grid x:Name="Root" HorizontalAlignment="Stretch"
      VerticalAlignment="Stretch"
      Background="Gray">
    <Grid.Clip>
        <RectangleGeometry Rect="0,0,200,80" />
    </Grid.Clip>

在您的 XAML 中(200 是宽度,80 是高度),或者

public POIButton()
{
    InitializeComponent();

    var visual = ElementCompositionPreview.GetElementVisual(this);
    visual.Clip = visual.Compositor.CreateInsetClip();
}

在代码隐藏中使用新的 Composition API。请注意,使用 XAML 方法时,如果控件的大小发生变化,您需要通过绑定或代码隐藏手动更新宽度和高度,而使用 Composition,您不需要。

另外,我注意到您使用了在 UI 线程上运行的路径动画(例如 EnableDependentAnimation)。这可以用带有ScaleTransform 动画的Ellipse 替换,这通常是推荐的方法,因为它的性能要好得多。


XamlLight 的“涟漪”效果

由于您正在为 UWP 进行开发,因此重要的是要了解该平台可以做什么,以及 UWP 实现类似效果的方式,但仍然尊重其自己的Fluent Design System

借助15063 中引入的新XamlLight 类,我创建了以下FluentButton 控件,如下所示。您会注意到灯光跟随您的鼠标光标,并在单击/点击时产生涟漪。

第二部分由自定义的XamlLight 完成,我称之为RippleXamlLight,这就是它的实现方式-

首先,创建一个继承自XamlLight 的类。

public class RippleXamlLight : XamlLight

然后,在其OnConnected 覆盖方法中,创建一个SpotLight 实例和一个Vector3 动画,用于为灯光的Offset 设置动画。它还将负责订阅指针事件,例如PointerPressed

protected override void OnConnected(UIElement newElement)
{
    _compositor = Window.Current.Compositor;

    var spotLight = CreateSpotLight();
    CompositionLight = spotLight;

    _lightRippleOffsetAnimation = CreateLightRippleOffsetAnimation();

    SubscribeToPointerEvents();

    AddTargetElement(GetId(), newElement);

    ...
    }
}

最后,每当按下控件时启动动画。 Offset 值由指针位置和根据控件大小计算得出的_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);
}

如果我解释得不够清楚,这里是full source 供您参考。 :)

【讨论】:

  • 谢谢,我已经在第一部分尝试了你的解决方案,在网格上使用矩形几何形状进行剪辑,但是当动画播放器看起来矩形也是动画时......我发布了结果
  • 您只需要 xaml 或 cs 方法,而不是两者都需要。此外,如果您使用 xaml 方法,则需要确保定义控件的宽度和高度。您的 xaml 仅定义了 d:DesignHeightd:DesignWidth。它们需要替换为HeightWidth
  • 我按照您在 Xaml 中的建议做了,但它似乎不起作用。但是 CS 代码工作正常,非常感谢 :) 。在 RadiusX 和 RadiusY 上播放动画时,我将检查 ellipseGeometry 动画是否会消耗大量 cpu/gpu 性能。
猜你喜欢
  • 1970-01-01
  • 2017-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 2015-01-12
  • 2020-08-11
相关资源
最近更新 更多