« Previous - Version 3/4 (diff) - Next » - Current version
coder, 17/06/2015 23:33


Animation

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.

Linear Animations

It is very simple to animate node attributes:

anim1.py

 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3
 4from libavg import *
 5
 6def startAnim():
 7    animObj.start()
 8
 9player = avg.Player.get()
10canvas = player.createMainCanvas(size=(640,480))
11rootNode = canvas.getRootNode()
12node = avg.WordsNode(pos=(10,10), font="arial",
13        text="Hello World", parent=rootNode)
14
15animObj = LinearAnim(node, "x", 2000, 0, 200)
16player.setTimeout(0, startAnim)
17
18player.play()

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.

There are convenience functions that handle fading the opacity of nodes called fadeIn() and fadeOut().

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.

Easein/out

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.

ParallelAnim

In many cases, you will want to start several animations at once. This can be accomplished using the ParallelAnim class:

anim2.py

 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3
 4from libavg import *
 5
 6def startAnim():
 7    animObj.start()
 8
 9canvas = player.createMainCanvas(size=(640,480))
10rootNode = canvas.getRootNode()
11node = avg.RectNode(pos=(10,10), size=(100,100), fillcolor="FF0000", fillopacity=1.0,
12        parent=rootNode)
13
14animObj = ParallelAnim(
15    [LinearAnim(node, "pos", 2000, (0,0), (200,10)),
16     LinearAnim(node, "fillcolor", 2000, "00FFFF", "FF0000")])
17player.setTimeout(0, startAnim)
18
19player.play()

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.

StateAnim

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.

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.

Note that changing the state of a StateAnim during an animation callback is not supported. An attempt to do so is silently ignored.

Other Animations

WaitAnim does nothing for a predetermined amount of time. ContinuonsAnim continually changes one attribute and doesn't stop by itself.