2011-11-01 119 views
3

我正在尝试为我的WPF应用程序构建交互式背景。从下面的截图中可以看出,它由分散在整个背景中的单个矩形组成,我希望它们逐渐淡入和淡出。优化淡入淡出框动画

我正在计算基于用户机器的虚拟屏幕大小(例如,我的是3200x1200)所需的矩形数量。这种方式最大化和最小化窗口将揭示更多的背景。如上所述,对于我的决议,我将需要3220个矩形。

现在我已经实现了这种方式,所有矩形都被添加到随机生成的alpha值的画布上。然后我延迟 - 开始一个自动循环动画(见下文)。 Unfrtunatly这导致我的应用程序非常缓慢(正确如此)。无论如何,我可以实现这种类型的效果,并有更好的表现?

<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

回答

0

这里就是我会做,以提高性能:

1)创建仅是在后台可见的矩形。

2)将每个Rectangle的Fill属性随机绑定到预定义颜色的一个StaticResources(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 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。

+0

我想你仍然可以使用'ObjectAnimationUsingKeyFrames'为'Brushes'制作动画? –

0

有几个选项:

一个。不要使用这么多的矩形。我知道这是显而易见的,但严重的是,有三千件动画是A LOT,即使是高性能的机器。

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

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

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

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