There are different levels of animation. I have a feeling that you mostly exhausted the possibilities of "default" animation features embedded in WPF and available via XAML, that's why you face the problem of expressive power of the method. Maybe your animation need more flexibility; it is more complex then the set of combined features of animation with the storyboard, etc.
If so, you need to step one level lower and design lower-level animation which would allow for nearly any motion. First, create a mathematical model of animation, express it in the form of data model. It could be a model of "physics" of the scene or something else — you named it.
On a next step, develop a rendering of your scene as a
static picture on your canvas using your elements placed on the canvas. In other words, make the positions of all the objects and the transformations depending on your data model.
Next step: make a "rendering procedure". When the data model is updated, all your objects should relocate/transform according to the new data. This is the key: relationships between all the elements can be as complex as you need. Make it a single parameterless method, let's call it "
Step
".
Next step: add time to this picture. You can use a timer or a separate thread. I would advice to use a thread which is easier to implement and which is more reliable. First, you need to modify your data model depending on time. Here is a very important thing: with thread, you will need to use
System.Threading.Thread.Sleep(frameDuration)
.
Do not calculate time based on frameDuration
! The actual thread timer would be somewhat random. Instead, you need to use "real" time. Take if from
System.DateTime.Now
or better use more accurate
System.Diagnostics.Stopwatch
,
http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx[
^]. I did not try to compare performance yet, but as you need to make this time method as fast as possible, I suspect
Stopwatch
will also perform faster. Please do some experiments/testing by yourself and pick the best method of timing.
From the above step, you will get some thread which "animates" the data model depending on real time, but the points of real may be not precisely equidistant, which will work quite fine, you will see it. What's more important, you need to have proper average frames per second (experiment with it by yourself) and model depending not on the number of frame, but on the "real" time; see the above paragraph.
If leaves for the last step: how to make the scene update. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method
Invoke
or
BeginInvoke
of
System.Windows.Threading.Dispatcher
. In this case, you need to invoke your method
Step
I described above.
You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[
^],
Problem with Treeview Scanner And MD5[
^].
See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[
^],
Control events not firing after enable disable + multithreading[
^].
—SA