Animation

Version 4 (coder, 18/01/2016 18:27)

1 1 admin
h1. Animation
2 1 admin
3 1 admin
{{>toc}} 
4 1 admin
5 1 admin
libavg contains a powerful animation framework that allows you to quickly author time and event-based changes in nodes. Animations can change the values of all numeric node attributes. They can be combined to execute in parallel or in series, they can switch states when some external event occurs, and callbacks can be registered that are called when animations start or stop.
6 1 admin
7 1 admin
h1. Linear Animations
8 1 admin
9 1 admin
It is very simple to animate node attributes:
10 1 admin
11 1 admin
_anim1.py_
12 1 admin
13 1 admin
<pre><code class="python">
14 1 admin
#!/usr/bin/env python
15 1 admin
# -*- coding: utf-8 -*-
16 1 admin
17 1 admin
from libavg import *
18 1 admin
19 1 admin
def startAnim():
20 1 admin
    animObj.start()
21 1 admin
22 1 admin
player = avg.Player.get()
23 1 admin
canvas = player.createMainCanvas(size=(640,480))
24 1 admin
rootNode = canvas.getRootNode()
25 1 admin
node = avg.WordsNode(pos=(10,10), font="arial",
26 1 admin
        text="Hello World", parent=rootNode)
27 1 admin
28 1 admin
animObj = LinearAnim(node, "x", 2000, 0, 200)
29 1 admin
player.setTimeout(0, startAnim)
30 1 admin
31 1 admin
player.play()
32 1 admin
</code></pre>
33 1 admin
34 3 coder
This creates an animation that moves the node from @x=0@ to @x=200@ over a course of 2000 milliseconds. The framework takes care of updating the position each frame. Point and color attributes (such as @pos@, @size@ and @fillcolor@) can be animated in the same way. @LinearAnim@ has a few additional optional parameters, which are described in detail in the [[reference]]. Using this class, you are independent of the framerate: if you change the framerate (maybe because you're running the code on a different computer with a different refresh rate), the animation will still take the same amount of time to complete. It'll just display more or less frames. There is another advantage: If something happens while the animation is running (the user presses a cancel button, for instance), you can just call @animObj.abort()@ and it'll stop dead in it's tracks. The animation framework also makes sure that only one animation per attribute is running at one time. If a second one is started, the first one is aborted.
35 1 admin
36 2 coder
There are convenience functions that handle fading the opacity of nodes called @fadeIn()@ and @fadeOut()@.
37 1 admin
38 3 coder
Interpolation of color values is done in the CIE L'ch color space for best results - see https://www.libavg.de/blog/colors/ for an explanation of why this is a good thing.
39 3 coder
40 1 admin
h1. Easein/out
41 1 admin
42 3 coder
@LinearAnim@ moves the attribute at a constant speed with no acceleration or deceleration. The @EaseInOutAnim@ class encapsulates an animation that proceeds in three phases: ease-in, linear and ease-out. Constructor parameters determine the length of each phase. Start and end speed are zero. Ease-in and ease-out phases have the shape of one quadrant of the sine curve. Less mathematically put: The animation will accelerate and decelerate at the beginning and end and look a lot smoother because of this.
43 1 admin
44 1 admin
h1. ParallelAnim
45 1 admin
46 2 coder
In many cases, you will want to start several animations at once. This can be accomplished using the @ParallelAnim@ class:
47 1 admin
48 4 coder
> (!) *Note:* (!) 
49 4 coder
> The example animates a color, which is a post-1.8 feature. You need to use the current git master to run it.
50 4 coder
51 1 admin
_anim2.py_
52 1 admin
53 1 admin
<pre><code class="python">
54 1 admin
#!/usr/bin/env python
55 1 admin
# -*- coding: utf-8 -*-
56 1 admin
57 1 admin
from libavg import *
58 1 admin
59 1 admin
def startAnim():
60 1 admin
    animObj.start()
61 1 admin
62 1 admin
canvas = player.createMainCanvas(size=(640,480))
63 1 admin
rootNode = canvas.getRootNode()
64 3 coder
node = avg.RectNode(pos=(10,10), size=(100,100), fillcolor="FF0000", fillopacity=1.0,
65 3 coder
        parent=rootNode)
66 1 admin
67 1 admin
animObj = ParallelAnim(
68 3 coder
    [LinearAnim(node, "pos", 2000, (0,0), (200,10)),
69 3 coder
     LinearAnim(node, "fillcolor", 2000, "00FFFF", "FF0000")])
70 1 admin
player.setTimeout(0, startAnim)
71 1 admin
72 1 admin
player.play()
73 1 admin
</code></pre>
74 1 admin
75 3 coder
The example code moves the node down and to the right over a course of 2 seconds while changing its color at the same time. Calling @abort()@ on a @ParallelAnim@ will stop all child animations. @ParallelAnim@ is sometimes useful on its own, but it's really powerful in combination with @StateAnim@.
76 1 admin
77 1 admin
h1. StateAnim
78 1 admin
79 1 admin
More complex animations can be scripted using @StateAnim@. Objects of this class contain a number of animations (so-called "states") that can be executed in an arbitrary sequence. At most one of these animations is active at once. The end of one animation can trigger the start of another one, and states can be set from a python script. A simple use for a @StateAnim@ is as a predetermined sequence of animations, but animations that take different routes depending on user input events are also possible. There is support for debugging animation states by calling @StateAnim.setDebug(True)@. This causes all state changes to be dumped to the console.
80 1 admin
81 2 coder
To make sure there are no discontinuities between two states, @Anim.start()@ has an optional parameter @keepAttr@. If this is set to True, the attribute is not changed at the beginning of the animation and the animation runs only for an appropriate part of the time that the duration parameter specifies. So, suppose that in @anim2.py@ above, @start(True)@ is called and @x=50@ before the animation starts. Since this is one-quarter into the range 0-200, the animation will run for 1500 ms (=2000*0.75) and the node will move from 50 to 200 in this time.
82 1 admin
83 1 admin
Note that changing the state of a @StateAnim@ during an animation callback is not supported. An attempt to do so is silently ignored.
84 1 admin
85 1 admin
h1. Other Animations
86 1 admin
87 1 admin
@WaitAnim@ does nothing for a predetermined amount of time. @ContinuonsAnim@ continually changes one attribute and doesn't stop by itself.