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