如何平滑WPF动画?

时间:2012-10-01 08:21:21

标签: wpf animation storyboard

我正在努力平滑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方法),动画就会开始变得紧张。我的意思是,在动画过程中,物体会发抖。

2 个答案:

答案 0 :(得分:1)

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

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

这减少了WPF应用程序的负载,因为它只是将对象的表示形式存储为位图图像,因此您的应用程序不必在每个帧上重绘它们。此解决方案仅在您的动画外部应用于画布时才有效,并且没有正在进行的局部动画应用于画布中绘制的各个对象。如果代码中的其他动画将两个对象相互移动,您将希望创建具有自己的缓存的分隔画布。

请注意,此策略不会放宽某些UI元素。但是,我已经看到这种策略可以有效地用于许多元素,包括 TextBoxes 等等,以及几何形状。无论如何,总是值得一试。

其次,如果缓存本地表示不够,那么您可能希望查看代码的性能,并查看是否有任何进程可能会暂时阻止UI。关于这方面没有统一的解决方案,这取决于还有什么对您的应用程序UI造成压力。清理代码并使用相关的异步流程可以提供帮助。

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

Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = 40 });

答案 1 :(得分:0)

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

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);
}