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. |