【问题标题】:uwp rotation animation in a loop with RotationAnimation class freezing UserInterface循环中的 uwp 旋转动画,RotationAnimation 类冻结 UserInterface
【发布时间】:2018-02-14 14:04:13
【问题描述】:

我正在尝试使用 UWP 社区工具包 中的动画在我的 uwp 应用程序中的 UI 元素上获得晃动(或抖动效果)。如果我在上面放一个旋转动画,它会像预期的那样完美。但我实际上是在尝试将它们链接起来,然后将它们放在一个事件中的循环中,这样 ui 元素就会像在摇晃一样循环。

为此,我正在尝试以下代码。

var parent = panel?.Parent as UIElement;
if (parent != null)
{
    while (true)
    {
        var animation = new RotationAnimation() { To = 0.3, Duration = TimeSpan.FromMilliseconds(100) };
        animation.StartAnimation(panel);

        var animation2 = new RotationAnimation() { From = 0.3, To = 0, Duration = TimeSpan.FromMilliseconds(100) };
        animation2.StartAnimation(parent);

        var animation3 = new RotationAnimation() { To = -0.3, Duration = TimeSpan.FromMilliseconds(100) };
        animation3.StartAnimation(panel);

        var animation4 = new RotationAnimation() { From = -0.3, To = 0, Duration = TimeSpan.FromMilliseconds(100) };
        animation4.StartAnimation(parent);
    }
}

如您所见,我正在从一些逻辑中获取我的 UI 元素,然后我尝试将 4 个旋转动画 1 个一个接一个地链接。

  1. 顺时针旋转一点
  2. 恢复正常状态。
  3. 逆时针旋转一点
  4. 恢复正常状态。

这应该会产生我想要的 抖动效果,但我的 应用实际上挂起(而且我没有得到任何 异常),即使我尝试在没有 while loop 的情况下做到这一点。我试图首先创建它,然后我的目标是在一个函数中使其 asyncronous ,以便我可以在一个元素上调用它,然后从另一个事件或方法停止动画。

我感觉这可能不是从 UWP 社区工具包链接这些动画的正确方法,这就是 UI 冻结的原因,还有更好的方法吗?

我也知道类似 panel.Rotate() 的扩展方法,它也由社区工具包提供,但我不想使用它们,因为我必须提供 面板的centerXcenterY,我在其他场景中已经在相同的对象上使用了缩放动画,所以我不确定如何提供UI的centerX和centerY元素。

我也在那个特定的 ui 元素上使用 extensions:VisualEx.NormalizedCenterPoint="0.5,0.5,0" ,这就是为什么我对提供中心点有点困惑,因此想要使用这个 RotationAnimation 类,它不采用任何中心点并自动检测中心点作为元素的中心,这可能是因为我设置了那个 xaml 属性。

【问题讨论】:

    标签: xaml animation uwp uwp-xaml windows-community-toolkit


    【解决方案1】:

    这里的问题是StartAnimation 不等待动画完成。当您运行代码时,它实际上会尝试同时运行所有动画。当你在 while (true) 块中执行此操作时,情况会变得更糟,因为这将无限重复该过程,因此它可能会尝试同时启动数百个动画。

    作为一种快速修复,您可以在各个阶段之间添加await Task.Delay( 100 ) 调用,以确保 UI 等待动画完成。但是这个解决方案不是很好,它依赖于Task.Delay,并且动画在恰好 100 毫秒后不会 100% 可靠地运行。

    在上一个的Completed事件中运行下一个动画的更好解决方案:

    animation.Completed += YourHandler;
    

    但是,我们为什么要重新发明轮子?我们可以使用工具包本身提供的AnimationSet

    AnimationSet

    AnimationSet 类允许您创建复杂的动画并将它们一一链接。为此,您可以使用 Then 方法,该方法将等待上一个动画完成,然后再开始下一个动画。请参阅source code

    var animationSet = panel.Rotate( 0.3 )
             .Then()
             .Rotate( -0.3 )
             .Then()
             .Rotate( 0.3 )
             .Then()
             .Rotate( -0.3 );
    

    【讨论】:

    • AnimationSet 不包含旋转的定义,并且最好的重载需要 Ui 元素,得到这个编译错误
    • using Microsoft.Toolkit.Uwp.UI.Animations; 语句添加到您的文件中
    • 单次旋转不会出现此错误,只有链接会导致此错误。
    • 它应该可以作为扩展方法使用——见github.com/Microsoft/UWPCommunityToolkit/blob/master/…
    • 如果你手动写AnimationExtensions.Rotate 是否有AnimationSet 过载?
    猜你喜欢
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    相关资源
    最近更新 更多