优化淡出框动画

3
我正在尝试为我的WPF应用程序构建一个交互式背景。如下面的截图所示,它由分散在背景中的独立矩形组成,我希望它们能够单独地淡入淡出。
我根据用户机器的虚拟屏幕大小(例如我的是3200x1200)计算所需的矩形数量。这样,最大化和最小化窗口将显示更多的背景。如上所述,对于我的分辨率,我将需要3220个矩形。
我现在的实现方式是将所有矩形添加到带有随机生成的alpha值的画布上。然后我延迟开始一个自动循环动画(见下文)。不幸的是,这导致我的应用程序非常缓慢(理所当然)。有没有办法实现这种类型的效果并获得更好的性能?
<Storyboard x:Key="uiStoryboardTile" AutoReverse="True" RepeatBehavior="Forever">
    <ColorAnimationUsingKeyFrames
        Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
        <EasingColorKeyFrame KeyTime="0:0:2" Value="Transparent"/>
    </ColorAnimationUsingKeyFrames>
</Storyboard>

Fading Boxes

3个回答

0

有几个选项:

a. 不要使用太多矩形。我知道这很明显,但是即使对于性能良好的机器来说,要动画化三千个项目也是非常多的。

b. 尝试动画化不同矩形的不透明度而不是填充刷子的颜色。根据我的猜测理论,这可能会产生积极的影响。

c. 尝试手动动画化每个矩形的不透明度/颜色,而不是使用故事板来调整颜色。例如:

// Disclaimer: This code was written in the SO text editor.  Might not be correct.
foreach (MyRect rect in MyRectangles)
{
  if (rect.FadingIn)
  {
    rect.Opacity += 0.1;
    if (rect.Opacity >= 1) { rect.FadingIn = false; }
  }
  else
  {
    rect.Opacity -= 0.1;
    if (rect.Opacity <= 0 ) { rect.FadingIn = true; }
  }
}

你会注意到一个特殊的类,它包含了一些额外的信息以满足你的需求。

class MyRect
{
  public Shape Rectangle;
  public bool FadingIn;

  public double Opacity
  {
    get { return Rectangle.Opacity; }
    set { Rectangle.Opacity = value }
  }

  //... etc.
}

当然,你还需要放置一些支持代码,比如将矩形放到宿主机上等等,但是听起来你已经自己完成了这些步骤。

0

以下是我为提高性能所做的事情:

1)仅创建在背景中可见的矩形。

2)将每个矩形的填充属性随机绑定到预定义颜色的静态资源之一(10-20个应该足够了)。

3)创建一个动画故事板来动画这些静态资源。

虽然您会失去每个矩形的个性,但它应该可以动画而不会使您的应用程序崩溃。

编辑 - 代码示例

例如,添加一些要动画的资源(它们是矩形,因为您无法直接动画 SolidColorBrush):

<Window.Resources>
        <Rectangle x:Key="Color0" Fill="#FFFFCFFF" />
        <Rectangle x:Key="Color1" Fill="#FFFFC2C2" />
        <Rectangle x:Key="Color2" Fill="#FFFFEFD2" />
        ...
</Window.Resources>

你的Storyboard会长成这个样子:

    <Storyboard x:Key="BackgroundAnimation" AutoReverse="True" RepeatBehavior="Forever">
        <ColorAnimationUsingKeyFrames Storyboard.Target="{StaticResource Color0}"
                                      Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                                      BeginTime="0:0:0:0"
                                      AutoReverse="True"
                                      Duration="00:00:03.00">
            <ColorKeyFrameCollection>
                <EasingColorKeyFrame Value="Transparent" />
            </ColorKeyFrameCollection>
        </ColorAnimationUsingKeyFrames>

     <!-- Add keyframes for each color, varying start and duration -->
      ...
</Storyboard>

在您的代码后台中生成所有矩形的位置,您需要绑定资源。因此,在循环的某个地方,您需要添加以下内容:
 // I'll leave the implementation of GetRandomColorId to you
 resourceId = GetRandomColorId(MAX_COLORS);

 Shape source = (Shape)this.FindResource("Color" + resourceId);
                    Binding binding = new Binding
                                          {
                                              Path = new PropertyPath("Fill"),
                                              Source = source
                                          };

                    rect.SetBinding(Shape.FillProperty, binding);

最后,您所需要做的就是启动BackgroundAnimation。

我认为您仍然可以使用ObjectAnimationUsingKeyFrames来对Brushes进行动画处理? - Justin XL

0

您尝试过以组的形式进行动画处理吗?即使您有1000多个矩形,也可以将它们分成组,只同时运行10个左右的动画。如果块的间距正确,它仍应具有随机动画矩形的外观。

这可以通过创建块的图层来完成,每个图层都是透明的,只有其块可见。将这些图层堆叠在一起,并为每个图层动画透明度即可实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接