More Complex Animations

Animations created with AnAnimLib consist of creating AnObjects that represent graphical objects and using Instructions to modify their attributes. For example, the Move and MoveTo instructions modify the position attribute of the AnObject on which they operate. Complex animations can be created by creating classes that inherit from one of the base AnObject classes, defining custom attributes that control their appearance, and maniuplating those attributes using Instructions.

SetAttribute and SlideAttribute

Many instructions included with AnAnimLib inherit from one of two core instructions; SetAttribute, which sets an attribute to a particular value, and SlideAttribute, which “slides” an attribute through a range of values. The snippets below demonstrate two ways to perform a move; using Move and MoveTo or using SetAttribute and SlideAttribute.

 1import ananimlib as al
 2
 3rect = al.Rectangle([1,1])
 4
 5al.Animate(
 6    al.AddAnObject(rect),
 7    al.MoveTo(rect, [-3,0]),
 8    al.Move(rect, [6,0], duration=1.0),
 9    al.Wait(1.0)
10)
11
12al.play_movie()
 1import ananimlib as al
 2
 3rect = al.Rectangle([1,1])
 4
 5al.Animate(
 6    al.AddAnObject(rect),
 7    al.SetAttribute(rect, "position", [-3,0]),
 8    al.SlideAttribute(rect, "position", [3,0], duration=1.0),
 9    al.Wait(1.0),
10)
11
12m.play_movie()

The output from both snippets is the same:

_images/quickstart_ex2.gif

Both SetAttribute and SlideAttribute take as parameters the AnObject, the name of the attribute to manipulate, a value to assign that attribute, and an optional duration. Here is how the Move instruction is implemented:

 1class Move(al.SlideAttribute):
 2    """Move an AnObject relative its current position
 3
 4    Parameters
 5    ----------
 6    key: string or AnObject
 7        The AnObject to move
 8
 9    displacement: Vector
10        The new coordinates of the mobject in Scene Units
11
12    duration: optional float
13        The amount of time over which to move the mobject.
14        default = 0.0, instantaneous
15
16    transfer_func: optional callable
17        The transfer function maps the ratio of time elapsed over total time to the
18        fraction of the total move distance.
19        ratio = transfer_func(alpha)
20        default = smooth
21    """
22
23    def __init__(self, key, displacement, duration=0.0,
24                 transfer_func=al.smooth):
25        super().__init__(key         = key,
26                        attribute  = 'position',
27                        end_value  = displacement,
28                        duration   = duration,
29                        transfer_func = transfer_func)

Since SetAttribute and SlideAttribute operate on an arbitrary attribute, our custom instruction need only pass the name of that attribute and any other required parameters to the __init__ method of the parent class.

Take as an example a rolling wheel. To simulate the motion, we need to simultaneously update both the object’s position and rotation angle. There is a mathematical relationship between the position and angular position that must be encoded somewhere. That logic can be encoded either in a custom AnObject whose position attribute also correctly updates the wheel’s rotation angle or, it can be encoded in a custom Instruction that simultaneously updates both attributes of the wheel.