优化淡入淡出框动画

发布于 2024-12-13 12:29:45 字数 722 浏览 0 评论 0原文

我正在尝试为我的 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>

褪色框

I am trying to build an interactive background for my WPF application. As you can tell from the screenshot below, it consists of individual rectangles scattered throughout the background and I want them to individually fade in and out.

I am calculating the amount of rectangles required based on the Virtual Screen Size of the users machine (mine is 3200x1200 for example). That way maximizing and minimizing the window will reveal more of the background. As stated, for my resolution I am going to need 3220 rectangles.

The way I have this implemented now is all rectangles are added to a canvas with randomly generated alpha values. I then delay-begin an auto-looping animation (see below). Unofrtunatly this is causing my application to be extremely sluggish (rightfully so). Is there anyway I can implement this type of effect and have much better performance?

<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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

信仰 2024-12-20 12:29:45

以下是我将采取的措施来提高性能:

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。

Here's what I would do to improve performance:

1) Create only the Rectangles that are visible in the background.

2) Randomly bind the Fill property of each Rectangle to one of a number of StaticResources of predefined colors (10-20 should probably do the trick).

3) Create a storyboard that animates those StaticResources.

You would lose the individualality each Rectangle, but it should animate without killing your application.

EDIT - Code examples

For example, add some resources to animate (they're rectangles since you can't directly animate a SolidColorBrush):

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

Your Storyboard would look something like:

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

In your code-behind where you generate all the rectangles, you'll need to bind to the resources. So somewhere in the loop, you'll need to add:

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

Finally, all you'll have to do is start the BackgroundAnimation.

夕嗳→ 2024-12-20 12:29:45

有几个选项

:不要使用那么多矩形。我知道这是显而易见的,但说真的,即使对于高性能机器来说,要制作三千个动画项目也很多。

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

当然,您还需要添加一些支持代码,例如将矩形连接到其主机等,但听起来您已经自己做到了这一点。

There are a couple of options:

a. Don't use so many rectangles. I know this is obvious, but seriously, three thousand items to animate is A LOT even for a performant machine.

b. Try animating the opacity of the different rectangles instead of the color on the fill brush. According to my wild ass guess (WAG) theory, this may have a positive effect.

c. Try animating the opacities / colors of each of the rectangles manually instead of using storyboards to tweak the color. For example:

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

You will notice a special class that has a bit of extra information for your needs.

class MyRect
{
  public Shape Rectangle;
  public bool FadingIn;

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

  //... etc.
}

Of course there is still some more support code that you will have to put in place, like getting your rectangles to their host, etc. but it sounds like you have already gotten that far on your own.

路弥 2024-12-20 12:29:45

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

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

Have you tried animating them in groups? While you may have 1000+ rectangles perhaps you could break them up in to groups and only have 10 or so animations running at once. If the blocks are spaced correctly it should still have the appearance of randomly animated rectangles.

This could be done by creating layers of blocks, where each layer is transparent with just it's blocks visible on it. Stack the layers on top of each other and animate the alpha of each layer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文