Suppose I have a storyboard, created at runtime by some process, containing keyframe animations. Is it possible to "scale" the animation speed so that the animation plays faster (or slower) after it has been constructed?
I am currently trying to make the decision wether to use the built-in animation stuff or to use something like DispatcherTimer or CompositionTarget.Rendering and do the moving of objects manually. Speed control is one of the requirements I have..
Yes it is possible. The property on the Storyboard is called "SpeedRatio"
http://msdn.microsoft.com/en-us/library/system.windows.media.animation.timeline.speedratio(v=VS.95).aspx
Related
Is this possible in expression blend?
What i am looking for is to start a storyboard, then at second 2 i would like to start another storyboard.
Why am I looking for this? So I can re-use storyboards and 'pieces' of larger storyboards. Seems like it would be the most OO I can get from storyboards.
Thanks!
Storyboards are not supposed to be OO, they are animation and timeline tools. If you want to create custom and controlled animations, I would advice that you research about the CompositeTarget.Rendering event and read about animations and easing. You can use IEasingFunction to select the easing your custom animations would use.
A different option would be to use the Storyboard.Completed event to find out when a storyboard is finished so that you can start another one, but if you decide to go this way you have to be very careful about memory leaks related with event hooks.
There is a lot of talk about the simplicity of Visual States and the transitions between them in WPF/Silverlight.
I have the need to generate animations dynamically at runtime, to animate the rotation of a 3D model (depending on the users mouse interaction, I want to rotate the 3D model around its axis).
I have been generating an Animation at runtime and animating the model, just fine, but it feels wrong to me... I was wondering if anyone out there thinks that creating visual states at runtime would be a better alternative?
Cheers,
Mark
I don't think this is a suitable use for Visual States. My understanding is that they are the distinct states that an object can have - a button is "normal", "focused", "pressed", "hovered over" etc. and the Visual State Manager (VSM) controls the transitions between these states.
In your case you are animating something that can have an infinite number of states - one view for every conceivable viewpoint on your model. I don't think the VSM will be particularly efficient in this case.
I'm working on a game-like app which has up to a thousand shapes (ellipses and lines) that constantly change at 60fps. Having read an excellent article on rendering many moving shapes, I implemented this using a custom Canvas descendant that overrides OnRender to do the drawing via a DrawingContext. The performance is quite reasonable, although the CPU usage stays high.
However, the article suggests that the most efficient approach for constantly moving shapes is to use lots of DrawingVisual instances instead of OnRender. Unfortunately though it doesn't explain why that should be faster for this scenario.
Changing the implementation in this way is not a small effort, so I'd like to understand the reasons and whether they are applicable to me before deciding to make the switch. Why could the DrawingVisual approach result in lower CPU usage than the OnRender approach in this scenario?
From Pro WPF in C# 2008:
The problem posed by these
applications isn't the complexity of
the art, but the sheer number of
individual graphic elements. Even if
you replace your Path elements with
lighter weight Geometry objects, the
overhead will still hamper the
application's performance. The WPF
solution for this sort of situation is
to use the lower-level visual layer
model. The basic idea is that you
define each graphical element as a
Visual object, which is an extremely
lightweight ingredient that has less
overhead than a Geometry object or a
Path object.
What it boils down to is that every single one of those ellipses and lines you're creating is a separate FrameworkElement; that means it supports not only hit testing, but also layout, input, focus, events, styles, data-binding, resources, and animation. That's a pretty heavy-weight object for what you're trying to do! The Visual object skips all of that and inherits directly from DependencyObject. It still provides support for hit-testing, coordinate transformation, and bounding-box calculations, but none of the other stuff that the shapes support. It's far more lightweight and would probably improve your performance immensely.
EDIT:
Ok, I misread your question the first time around.
In the case that you are using OnRender, it really depends how you are creating the visuals and displaying them. If you are using a DrawingContext and adding all of the visuals to a single element, this is no different than using the DrawingVisual approach. If you were creating a separate element for each Visual created, then this would be a problem. It seems to me that you are doing things the right way.
Everyone in the answers got it wrong. The question is whether rendering shapes directly in the drawing context is faster than creating DrawingVisual. The answer is obviously 'yes'. Functions such as DrawLine, DrawEllipse, DrawRectangle etc. do not create any UI Element. DrawingVisual is much slower because it does create a UI Element, although a lightweight one. The confusion in the answers is because people simply copy/paste the DrawingVisual performs better than distinct UIElement shapes statement from MSDN.
I thought Petzold explains in this paragraph;
The ScatterPlotVisual class works by
creating a DrawingVisual object for
each DataPoint. When the properties of
a DataPoint object change, the class
only needs to alter the DrawingVisual
associated with that DataPoint.
Which builds on an earlier explanation;
Whenever the ItemsSource property
changes, or the collection changes, or
a property of the DataPoint objects in
the collection changes,
ScatterPlotRender calls
InvalidateVisual. This generates a
call to OnRender, which draws the
entire scatter plot.
Is this what your asking about?
By the way, this is a fairly recent high-performance WPF tutorial, many tens of thousands of points in that plot, it is 3D rendered and animated also (even uses mouse input to drive some of the transforms).
In my tests however (panning animations), I notice no difference in speed. I would say that using a host element for many drawing visuals is a bit faster. This approach where you build your visual tree with many visuals gives you more control. Moreover, when you want to do a complex hit testing, the filtering process is faster because you can skip entire "branches" of visuals
I have a a bunch of WPF UserControls that internally trigger some animations upon user interactions. All animations have repeatbehavior = "true" and all animations have the same duration. Now I would like synchronize all those animations on one timeline so they are fading in and out in sync. No matter when the user triggerd the animations. For example if the animations all last 3 secs and the user triggers the 2nd animation 1.5 secs after the first, I still want the animations reach their maximum at the same time.
Maybe I can define a global time line in a global resource dictionary that all animations that are defined somewhere in the UserControls can use? Preferably XAML only.
Simply add all of your animations to a single TimelineCollection. Then add that TimelineCollection to your Storyboard.Children. Then they will all fire simultaneously.
XAML: impossible (as far as I know)
code: CompositionTarget.Rendering
Maybe my post can help you http://translate.google.it/translate?js=n&prev=_t&hl=it&ie=UTF-8&layout=2&eotf=1&sl=it&tl=en&u=http%3A%2F%2Fblogs.ugidotnet.org%2Fleonardo%2Farchive%2F2011%2F01%2F08%2Fsincronizziamo-le-animazioni-con-wpf.aspx&act=url (is in Italian and link is of Google Translate)
I'm trying to learn WPF animations and am currently confused by quite a few things:
I used tools like processing, where you have a simple method which is called n times per minute, where n is the frame rate.
The way to do animations in WPF is to modify a property. If i use for example DoubleAnimation then a double is increased as the animation proceeds. But this is not exactly what I want. I want that in every cycle some properties are increased, some are modified by random and some are modified by user interaction. How can I do this in WPF?
What is also confusing me is the fact that WPF supports multiple animations at the same time. How does this work? Is there a thread for every animation or just one for all animations.
I used gdi with c# some time ago. I even could use multiple threads for drawing; As far as I remember I just had to insert all the drawing commands in some queue and then windows took care of them.. I have no idea how this is handled with WPF.
On a basic level, WPF animations are just the same as any other kind of animation: internally a timer ticks and some properties are modified which lead to a different picture when drawn to the screen.
WPF does all the leg work for you to be able to specify animations relative to wall-clock time, like "move that box at 3mm per second to the left". For more complex scenarios you might want to code up your own Animation, see the Custom Animation Overview article on the MSDN.
Regarding threading, WPF works the same as GDI: There is one Thread that handles all the interaction with the WPF model and you can only talk to WPF Controls if you're running on this thread. You can use the Dispatcher to "send" code to this thread if you are free threading. Actual drawing to DirectX is done in a separate thread, but that is of no concern to casual users of the API.
You can run several animations at the same time by putting them into a StoryBoard.
You can use the animation's BeginTime to get one animation to start after another.
You can use the key frames version (DoubleAnimationUsingKeyFrames) or the path version (DoubleAnimationUsingPath) to create complex non-linear animations.