Wpf Animation Best Practices [closed]

2020-05-17 04:55发布

问题:

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 7 years ago.

I am looking for any best practices or guidelines regarding animation in WPF. Especially information regarding performance considerations.

回答1:

After I have gained a bit more experience in this field since I have asked the question, I will answer this myself. My experience comes from working on the WPF mind mapping application NovaMind - We have done lots of animations lately for our Presenter feature in NovaMind Platinum :-)

The MSDN section on Optimizing WPF Application Performance has some useful information about general considerations when writing WPF apps:

http://msdn.microsoft.com/en-us/library/aa970683.aspx

Here are some bits which I have found especially useful and are related to animation:

  • The CompositionTarget.Rendering event causes WPF to continuously animate. If you use this event, detach it at every opportunity.

  • When you use a Brush to set the Fill or Stroke of an element, it is better to set the Brush.Opacity value rather than the setting the element's Opacity property. Modifying an element's Opacity property can cause WPF to create a temporary surface.

  • You may be able to update a Transform rather than replacing it as the value of a RenderTransform property. This is particularly true in scenarios that involve animation. By updating an existing Transform, you avoid initiating an unnecessary layout calculation.

Here is what I have learned through trial and error:

  1. Say, you have a couple of elements with a Effect such as the BlurEffect applied. It is way faster to apply the effect to the container of these elements rather than the elements themselves. Even though the effect is hardware accelerated, WPF doesn't seem to be good at handling a number of small items with effects. - If you don't want the same blur radius and cannot group them in a container with the effect applied, it is actually faster to render the element to a bitmap (in software) and then animate the bitmap around (if that is possible). Having effects (or opacity for that matter) on objects quickly kills performance when animating.
  2. Setting the opacity on the brush rather than the element (as mentioned further above) makes a huge performance difference when animating objects.
  3. Keep the number of visuals down. Animating a large number of particles is difficult, even with the above tips. In this case you may need to revert to WriteableBitmap instead.

I have also heard that it is faster to render many little objects by overriding OnRender in the container and then rendering them using the drawingContext rather than adding them to the visual tree directly. In practice this didn't make any difference in my scenario (when rendering around 300 ellipse geometries) but it might be helpful in some scenarios. The theory sounds solid.

Finally, I have found the animation classes built into WPF way too cumbersome and had much more fun and success using the underdog of animation libraries: Artefact Animator. Seriously, give it a try. (it is also available for Silverlight) It is what animating (in code) should have been like.

All is not rainbows and unicorns though. I still find it impossible to create truly fluid animations when running full screen in higher resolutions. More on that in my question How to know why an animation stutters? - I would appreciate any input on that.

cheers, good luck and if you have something cool to show, let me know :)