我正在尝试为我的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>
答案 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设置动画。