Hello, λanim!
In this tutorial, we’re going to recreate the lanim.examples.hello
animation.
1. Create a stub
Create a file called tutorial_hello.py
with this content:
from lanim.examples.hello import export
Then run python -m lanim -o hello.mp4 tutorial_hello
in the same directory.
This explains how to make lanim
animate your module: it needs to export the
animation under the export
name.
2. Create the greeting
from lanim.pil import Latex
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
3. Make a static animation of the greeting
from lanim.core import const_a
from lanim.pil import Latex
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
export = const_a(sign)
python -m lanim -o hello.mp4 tutorial_hello
and see what happens.
This animation is only 1 second long, how do we make it longer?
3. Stretch the animation
from lanim.core import const_a
from lanim.pil import Latex
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
export = const_a(sign) * 5
Render the video again. It should be five seconds long.
4. Make the sign scale out instead of just sitting there
from lanim.pil import Latex, appear
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
export = appear(sign) * 2
5. Create a border around the greeting
from lanim.pil import Latex, Rect
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
How do we animate both of them?
6. Animate a pair of the greeting and the border
from lanim.pil import appear, Latex, Rect, Pair
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = appear(pair)
Pair
is also an ordinary immutable value, like Latex
and Rect
.
7. Make the last frame persist for a while
You can put one animation after another by adding them:
from lanim.core import const_a
from lanim.pil import appear, Latex, Rect, Pair
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = appear(pair) + const_a(pair)
8. Make the border appear before the sign
8.1. Make the sign appear inside the border
from lanim.core import const_a
from lanim.pil import appear, gbackground, Latex, Rect, Pair
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = gbackground(appear(sign), [border]) + const_a(pair)
gbackground
accepts an animation and a list of graphics to put in the background.
8.2. Stretch out the border before the greeting animation
from lanim.core import const_a
from lanim.pil import appear, gbackground, Latex, Rect, Pair
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = appear(border) + gbackground(appear(sign), [border]) + const_a(pair)
8.3. Formatting tweak
from lanim.core import const_a
from lanim.pil import appear, gbackground, Latex, Rect, Pair
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = (
appear(border)
+ gbackground(appear(sign), [border])
+ const_a(pair)
)
9. Move the assembly down
from lanim.core import const_a
from lanim.pil import appear, gbackground, move_by, Latex, Rect, Pair
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = (
appear(border)
+ gbackground(appear(sign), [border])
+ const_a(pair)
+ move_by(pair, dx=0, dy=10)
)
The animation is doing the action we wanted it to do, but it’s not pretty. Let’s fix that.
10. Add easings
An easing function allows you to change the “shape” or “texture” of the change.
To illustrate, look at these easings:
- The linear easing moves at a steady pace. It doesn’t change an animation.
- The in-out easing has a gentle start and end
- The sled easing starts out slow and then accelerates
An easing is a function from [0; 1]
to [0; 1]
.
You can see their graphs in on Desmos
from lanim.core import const_a
from lanim.pil import appear, gbackground, move_by, Latex, Rect, Pair
from lanim.easings import in_out, sled
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = (
appear(border)
+ gbackground(appear(sign), [border]).ease(in_out)
+ const_a(pair)
+ move_by(pair, dx=0, dy=10).ease(sled)
)
11. Adjust durations
Timing is to animation what intonation is to speech.
Let’s spice our animation up by tweaking some of the durations.
from lanim.core import const_a
from lanim.pil import appear, gbackground, move_by, Latex, Rect, Pair
from lanim.easings import in_out, sled
sign = Latex(x=0, y=0, source=r"Hello, $\lambda$anim!")
border = Rect(
x=0,
y=0,
width=sign.width() + 1,
height=sign.height() + 1
)
pair = Pair(sign, border)
export = (
appear(border) * 0.5
+ gbackground(appear(sign), [border]).ease(in_out)
+ const_a(pair) * 0.25
+ move_by(pair, dx=0, dy=10).ease(sled)
)
Recap
In this tutorial, you’ve learned how to:
- Export a simple animation from a Python module
- Create graphical objects, namely
Latex
,Rect
andPair
- Animate still frames, as well as scale out and move objects
- Change the duration of animations
- Put animations in sequence
- Use easings to make transitions more interesting