使用RotationAnimation类冻结UserInterface的循环中的uwp旋转动画

时间:2018-02-14 14:04:14

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

我正在尝试使用 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个rotationAnimations 链接到另一个。

  1. 顺时针旋转一点
  2. 恢复正常状态。
  3. 逆时针旋转一点
  4. 恢复正常状态。
  5. 这应该会创建我想要的微动效果,但我的应用实际挂起(而且我没有得到任何例外)即使我在没有while 循环的情况下尝试这样做。我首先尝试创建它,然后我的目标是在函数中使它成为 asyncronous ,这样我就可以在一个元素上调用它,然后从另一个事件或方法中停止动画。

      

    我感觉可能这不是从 UWP社区工具包链接这些动画的正确方法,这就是为什么UI处于冻结状态并且有更好的方法来执行此操作?

         

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

         

    此外,我在特定的ui元素上使用扩展名:VisualEx.NormalizedCenterPoint =&#34; 0.5,0.5,0&#34; ,这就是为什么我有点困惑提供中心点,因此想要使用这个 RotationAnimation 类,它不会占用任何中心点并自动检测中心点作为元素的中心,可能是因为设置了xaml属性。

1 个答案:

答案 0 :(得分:0)

这里的问题是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 );