优化渐变框动画

时间:2011-11-01 03:12:52

标签: c# wpf xaml animation

我正在尝试为我的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 :(得分:0)

有几种选择:

一个。不要使用这么多的矩形。我知道这是显而易见的,但严重的是,即使对于高性能的机器,动画的三千个项目也很多。

湾尝试动画不同矩形的不透明度,而不是填充画笔上的颜色。根据我的疯狂猜测(WAG)理论,这可能会产生积极的影响。

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

// 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.
}

当然还有一些支持代码,你必须将它们放在适当的位置,例如将矩形放到主机上等等,但听起来你自己已经有了这么远。

答案 1 :(得分:0)

以下是我要提高绩效的方法:

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

2)将每个Rectangle的Fill属性随机绑定到许多预定义颜色的StaticResource之一(10-20应该可以做到这一点)。

3)创建一个动画故事板,动画那些StaticResources。

你会失去每个矩形的个性,但它应该动画而不会杀死你的应用程序。

编辑 - 代码示例

例如,添加一些资源来设置动画(它们是矩形,因为你无法直接为SolidColorBrush设置动画):

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

您的故事板看起来像:

    <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。

答案 2 :(得分:0)

您是否尝试过分组动画?虽然你可能有1000多个矩形,但你可以将它们分成几组,并且一次只能运行10个左右的动画。如果块正确间隔,它应该仍然具有随机动画矩形的外观。

这可以通过创建块的层来完成,其中每个层都是透明的,只有它的块可见。将图层堆叠在一起,并为每个图层的alpha设置动画。