1

我正在努力平滑 WPF 动画

其实我的动画代码如下:

private void AnimateX ( FrameworkElement element, double XMoveStart, double XMoveEnd, int secondX)
{

    SineEase eEase = new SineEase();
    eEase.EasingMode = EasingMode.EaseInOut;
    Storyboard sb = new Storyboard();

    DoubleAnimation daX = new DoubleAnimation(XMoveStart, XMoveEnd, new Duration(new TimeSpan(0, 0, 0, secondX, 0)));
    daX.EasingFunction = eEase;
    Storyboard.SetTargetProperty(daX, new PropertyPath("(Canvas.Left)"));

    sb.Children.Add(daX);

    element.BeginStoryboard(sb);
}

上面的代码是一种轻松水平移动对象的方法。当只有一个物体在移动时,就可以了。但是,每当两个或多个对象一起移动时(在前一个动画尚未完成时调用另一个对象的 AnimateX 方法),动画就会开始变得抖动。我所说的抖动是指在动画过程中物体有点晃动。

4

2 回答 2

1

我多次遇到同样的问题。我发现根据您添加到画布的对象,WPF 通常必须在每一帧上重新生成这些对象的表示(我相信这可能是您的情况,具体取决于您正在操作的 UI 元素的类型)。您可以通过告诉 WPF 将画布的表示缓存在位图中来解决抖动问题。在画布的 Xaml 定义中,这非常简单,如下所示:

<Canvas ...Your canvas properties...>
    <Canvas.CacheMode>
        <BitmapCache />
    </Canvas.CacheMode>
    ...Your objects...
</Canvas>`

这减少了 WPF 应用程序的负载,因为它只是将对象的表示形式存储为位图图像,因此您的应用程序不必在每一帧上重新绘制它们。此解决方案仅适用于您的动画在画布外部应用,并且没有持续的本地动画应用于画布中绘制的各个对象的情况。如果您的代码中的其他动画相对于彼此移动两个对象,您将需要创建具有自己缓存的单独画布。

请注意,此策略不会缓解某些 UI 元素。但是,我已经看到这种策略对许多元素都有效,包括TextBox等,以及几何形状。无论如何,它总是值得一试的。

其次,如果缓存本地表示还不够,那么您可能需要查看代码的性能,看看是否有任何进程可能导致暂时阻塞 UI。关于这方面没有统一的解决方案,这取决于还有什么给您的应用程序 UI 带来压力。清理代码并在相关的地方使用异步进程可能会有所帮助。

最后,如果在所有这些检查之后对您的应用程序的总体需求仍然过高,您可以通过降低其一般帧速率(默认为 60)来消除应用程序的一些压力。您可以尝试 30 或 40 看看这是否有所改善通过在初始化中包含以下代码来进行抖动:

Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = 40 });
于 2017-05-22T19:57:11.167 回答
0

只是一个猜测,但是如果您直接为属性设置动画,而不使用 Storyboard,会发生什么?

private void AnimateX(FrameworkElement element, double xMoveStart, double xMoveEnd, double durationSeconds)
{
    DoubleAnimation animation = new DoubleAnimation
    {
        From = xMoveStart,
        To = xMoveEnd,
        Duration = TimeSpan.FromSeconds(durationSeconds),
        EasingFunction = new SineEase { EasingMode = EasingMode.EaseInOut }
    };

    element.BeginAnimation(Canvas.LeftProperty, animation);
}
于 2012-10-01T08:54:44.040 回答