Animation
Animation is the key function of Manim. The fundamental properties of an animation of Manim are characterized by its
run_time,
rate_func,
remover,
lag_ratio, and
suspend_mobject_updating
Animation Properties
The default properties of Manim animation are:
|
mobject |
starting_mobject |
run_time |
rate_func |
name |
remover |
lag_ratio |
suspend_mobject_updating |
Animation |
|
|
1 |
smooth |
None |
False |
0 |
True |
run_time
run_time is the running time for an animation or animation group.
Example
Code
# folder/file: tut/manim_animation_animation_runtime_001a.py
import numpy as np
from manimlib.scene.scene import Scene
from manimlib.mobject.mobject import Group
from manimlib.mobject.numbers import DecimalNumber
from manimlib.mobject.geometry import Dot, Circle, Square, Triangle,RegularPolygon
from manimlib.animation.creation import ShowCreation
from manimlib.animation.transform import Transform, ReplacementTransform, TransformFromCopy, MoveToTarget, ApplyMethod, ApplyFunction
from manimlib.mobject.svg.tex_mobject import TextMobject, TexMobject
from manimlib.animation.composition import AnimationGroup
from manimlib.utils.rate_functions import linear
class manim_animation_animation_runtime_001a(Scene):
def construct(self):
rows,cols=(12,15)
x0=[-5,*[-3+0.6*i for i in range(cols-4)],*[4+i for i in range(3)] ]
y0=[3.5,*[2.5-0.6*i for i in range(rows-1)]]
txtx=["run\_time",*[str(i) for i in range(cols-4)],"","","", ]
for i in range(cols): self.add(TextMobject(txtx[i]).move_to(([x0[i],y0[0],0])))
txty=["", *[2*i/10 for i in range(rows)]]
for i in range(1,rows): self.add(TextMobject(str(txty[i]),"t").move_to(([x0[0],y0[i],0])))
[[self.add(Dot().move_to(([x0[i],y0[j],0]))) for i in range(1,12)] for j in range(1,rows)]
d=Dot().set_width(0.0000001);a1=[d];a2=[d];a3=[d]
self.add(Circle().scale(0.2).move_to([x0[12],y0[0],0]))
self.add(Square().scale(0.2).move_to([x0[13],y0[0],0]))
self.add(RegularPolygon().scale(0.2).move_to([x0[14],y0[0],0]))
self.add(TextMobject("lag\_ratio").move_to([x0[13],y0[1],0]))
self.add(TextMobject(r"$0.5$").move_to([x0[13],y0[2],0]))
self.add(TextMobject("rate\_func").move_to([x0[13],y0[3],0]))
self.add(TextMobject(r"$linear$").stretch_to_fit_width(0.7).move_to([x0[12],y0[4],0]))
self.add(TextMobject(r"$linear$").stretch_to_fit_width(0.7).move_to([x0[13],y0[4],0]))
self.add(TextMobject(r"$linear$").stretch_to_fit_width(0.7).move_to([x0[14],y0[4],0]))
for j in range(1,rows):
a1.append(Circle().scale(0.2).move_to([x0[1],y0[j],0]))
a2.append(Square().scale(0.2).move_to([x0[1],y0[j],0]))
a3.append(RegularPolygon().scale(0.2).move_to([x0[1],y0[j],0]))
self.add(*a1,*a2,*a3,)
for i in range(1,rows):
a1[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a2[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a3[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
t=10
def func():
return \
tuple([AnimationGroup(\
MoveToTarget(a1[i],rate_func=linear,run_time=txty[i]*t),\
MoveToTarget(a2[i],rate_func=linear,run_time=txty[i]*t),\
MoveToTarget(a3[i],rate_func=linear,run_time=txty[i]*t),\
lag_ratio=0.5)\
for i in range(1,rows)])
self.play(AnimationGroup(*func(),lag_ratio=0))
self.wait(10)
Output
rate_func
rate_func is the interpolation motion control of an animation during the
run_time.
Example
Code
# folder/file: tut/manim_animation_animation_ratefunc_001a.py
import numpy as np
from manimlib.imports import *
from manimlib.scene.scene import Scene
from manimlib.mobject.mobject import Group
from manimlib.mobject.numbers import DecimalNumber
from manimlib.mobject.geometry import Dot, Circle, Square, Triangle,RegularPolygon
from manimlib.animation.creation import ShowCreation
from manimlib.animation.transform import Transform, ReplacementTransform, TransformFromCopy, MoveToTarget, ApplyMethod, ApplyFunction
from manimlib.mobject.svg.tex_mobject import TextMobject, TexMobject
from manimlib.animation.composition import AnimationGroup
from manimlib.utils.rate_functions import *
class manim_animation_animation_ratefunc_001a(Scene):
def construct(self):
rows,cols=(15,15)
x0=[-4,*[-0.5+0.5*i for i in range(cols-4)],*[5.2+0.6*i for i in range(3)] ]
y0=[3.5,*[2.5-0.45*i for i in range(rows-1)]]
txtx=["run\_time",*[str(i) for i in range(cols-4)],"","","", ]
for i in range(cols): self.add(TextMobject(txtx[i]).move_to(([x0[i],y0[0],0])))
txty=["","linear","smooth","rush\_into","rush\_from","slow\_into","double\_smooth","there\_and\_back","there\_and\_back\_with\_pause","running\_start","not\_quite\_there","wiggle","squish\_rate\_func","lingering","exponential\_decay"]#
txty1=["",linear,smooth,rush_into,rush_from,slow_into,double_smooth,there_and_back,there_and_back_with_pause,running_start,not_quite_there(smooth),wiggle,squish_rate_func(smooth),lingering,exponential_decay]
for i in range(1,rows): self.add(TextMobject(txty[i]).move_to(([x0[0],y0[i],0])))
[[self.add(Dot().move_to(([x0[i],y0[j],0]))) for i in range(1,12)] for j in range(1,rows)]
d=Dot().set_width(0.0000001);a1=[d];a2=[d];a3=[d]
self.add(Circle().scale(0.2).move_to([x0[12],y0[0],0]))
self.add(Square().scale(0.2).move_to([x0[13],y0[0],0]))
self.add(RegularPolygon().scale(0.2).move_to([x0[14],y0[0],0]))
self.add(TextMobject("lag\_ratio").move_to([x0[13],y0[1],0]))
self.add(TextMobject(r"$1$").move_to([x0[13],y0[2],0]))
self.add(TextMobject("run\_time").move_to([x0[13],y0[3],0]))
self.add(TextMobject(r"$1t$").move_to([x0[13],y0[4],0]))
for i in range(1,2):
for j in range(1,rows):
a1.append(Circle().scale(0.2).move_to([x0[i],y0[j],0]))
a2.append(Square().scale(0.2).move_to([x0[i],y0[j],0]))
a3.append(RegularPolygon().scale(0.2).move_to([x0[i],y0[j],0]))
self.add(*a1,*a2,*a3,)
for i in range(1,rows):
a1[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a2[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a3[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
tme=5
not_quite_there
wiggle
squish_rate_func
lingering
exponential_decay
def funcs():
return \
tuple([AnimationGroup(\
MoveToTarget(a1[i],rate_func=txty1[i],run_time=tme),\
MoveToTarget(a2[i],rate_func=txty1[i],run_time=tme),\
MoveToTarget(a3[i],rate_func=txty1[i],run_time=tme),\
lag_ratio=1)\
for i in range(1,rows)])
self.play(AnimationGroup(*funcs(),lag_ratio=1))
self.wait(10)
Output
remover
remover is the flag used to specify whether the animation object will be removed from the scene.
Example
Code
# folder/file: tut/manim_animation_animation_remover_001a.py
import numpy as np
from manimlib.scene.scene import Scene
from manimlib.mobject.mobject import Group
from manimlib.mobject.numbers import DecimalNumber
from manimlib.mobject.geometry import Dot, Circle, Square, Triangle,RegularPolygon
from manimlib.animation.creation import ShowCreation
from manimlib.animation.transform import Transform, ReplacementTransform, TransformFromCopy, MoveToTarget, ApplyMethod, ApplyFunction
from manimlib.mobject.svg.tex_mobject import TextMobject, TexMobject
from manimlib.animation.composition import AnimationGroup
from manimlib.utils.rate_functions import there_and_back, there_and_back_with_pause, wiggle, smooth, not_quite_there
class manim_animation_animation_remover_001a(Scene):
def construct(self):
rows,cols=(12,15)
x0=[-5,*[-3+0.6*i for i in range(cols-4)],*[4+i for i in range(3)] ]
y0=[3.5,*[2.5-0.6*i for i in range(rows-1)]]
txtx=["run\_time",*[str(i) for i in range(cols-4)],"","","", ]
for i in range(cols): self.add(TextMobject(txtx[i]).move_to(([x0[i],y0[0],0])))
txty=["", *[2*i/10 for i in range(rows)]]
for i in range(1,rows): self.add(TextMobject(str(txty[i]),"t").move_to(([x0[0],y0[i],0])))
[[self.add(Dot().move_to(([x0[i],y0[j],0]))) for i in range(1,12)] for j in range(1,rows)]
d=Dot().set_width(0.0000001);a1=[d];a2=[d];a3=[d]
self.add(TextMobject("remover").move_to([x0[13],y0[0],0]))
self.add(Circle().scale(0.2).move_to([x0[12],y0[0]-0.5,0]))
self.add(Square().scale(0.2).move_to([x0[13],y0[0]-0.5,0]))
self.add(RegularPolygon().scale(0.2).move_to([x0[14],y0[0]-0.5,0]))
remov=[
[True for i in range(rows)],
[False for i in range(rows)],
[True for i in range(rows)]
]
for i in range(1,rows):
self.add(TextMobject(str(remov[0][i])).scale(0.8).move_to([x0[12],y0[i],0]))
self.add(TextMobject(str(remov[1][i])).scale(0.8).move_to([x0[13],y0[i],0]))
self.add(TextMobject(str(remov[2][i])).scale(0.8).move_to([x0[14],y0[i],0]))
for j in range(1,rows):
a1.append(Circle().scale(0.2).move_to([x0[1],y0[j],0]))
a2.append(Square().scale(0.2).move_to([x0[1],y0[j],0]))
a3.append(RegularPolygon().scale(0.2).move_to([x0[1],y0[j],0]))
self.add(*a1,*a2,*a3,)
for i in range(1,rows):
a1[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a2[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a3[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
t=10
def func():
return \
tuple([AnimationGroup(\
MoveToTarget(a1[i],rate_func=smooth,run_time=txty[i]*t,remover=remov[0][1]),\
MoveToTarget(a2[i],rate_func=not_quite_there(proportion=0.8),run_time=txty[i]*t,remover=remov[1][1]),\
MoveToTarget(a3[i],rate_func=not_quite_there(proportion=0.4),run_time=txty[i]*t,remover=remov[2][1]),\
lag_ratio=0.5)\
for i in range(1,rows)])
self.play(AnimationGroup(*func(),lag_ratio=0))
self.wait(10)
Output
lag_ratio
lag_ratio is the lagged ratio between two animations of a animation group.
Example
Code
# folder/file: tut/manim_animation_animation_lagratio_001a.py
import numpy as np
from manimlib.scene.scene import Scene
from manimlib.mobject.mobject import Group
from manimlib.mobject.numbers import DecimalNumber
from manimlib.mobject.geometry import Dot, Circle, Square, Triangle,RegularPolygon
from manimlib.animation.creation import ShowCreation
from manimlib.animation.transform import Transform, ReplacementTransform, TransformFromCopy, MoveToTarget, ApplyMethod, ApplyFunction
from manimlib.mobject.svg.tex_mobject import TextMobject, TexMobject
from manimlib.animation.composition import AnimationGroup
from manimlib.utils.rate_functions import linear
class manim_animation_animation_lagratio_001a(Scene):
def construct(self):
rows,cols=(12,15)
x0=[-5,*[-3+0.6*i for i in range(cols-4)],*[4+i for i in range(3)] ]
y0=[3.5,*[2.5-0.6*i for i in range(rows-1)]]
txtx=["lag\_ratio",*[str(i) for i in range(cols-4)],"","","", ]
for i in range(cols): self.add(TextMobject(txtx[i]).move_to(([x0[i],y0[0],0])))
txty=["", *[2*i/10 for i in range(rows)]]
for i in range(1,rows): self.add(TextMobject(str(txty[i])).move_to(([x0[0],y0[i],0])))
[[self.add(Dot().move_to(([x0[i],y0[j],0]))) for i in range(1,12)] for j in range(1,rows)]
d=Dot().set_width(0.0000001);a1=[d];a2=[d];a3=[d]
self.add(Circle().scale(0.2).move_to([x0[12],y0[0],0]))
self.add(Square().scale(0.2).move_to([x0[13],y0[0],0]))
self.add(RegularPolygon().scale(0.2).move_to([x0[14],y0[0],0]))
self.add(TextMobject("run\_time").move_to([x0[13],y0[1],0]))
self.add(TextMobject(r"$1t$").move_to([x0[12],y0[2],0]))
self.add(TextMobject(r"$1t$").move_to([x0[13],y0[2],0]))
self.add(TextMobject(r"$1t$").move_to([x0[14],y0[2],0]))
self.add(TextMobject("rate\_func").move_to([x0[13],y0[3],0]))
self.add(TextMobject(r"$linear$").stretch_to_fit_width(0.7).move_to([x0[12],y0[4],0]))
self.add(TextMobject(r"$linear$").stretch_to_fit_width(0.7).move_to([x0[13],y0[4],0]))
self.add(TextMobject(r"$linear$").stretch_to_fit_width(0.7).move_to([x0[14],y0[4],0]))
for i in range(1,2):
for j in range(1,rows):
a1.append(Circle().scale(0.2).move_to([x0[i],y0[j],0]))
a2.append(Square().scale(0.2).move_to([x0[i],y0[j],0]))
a3.append(RegularPolygon().scale(0.2).move_to([x0[i],y0[j],0]))
self.add(*a1,*a2,*a3,)
for i in range(1,rows):
a1[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a2[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
a3[i].target=Triangle().scale(0.2).move_to([x0[11],y0[i],0])
t=10
def func():
return \
tuple([AnimationGroup(\
MoveToTarget(a1[i],rate_func=linear,run_time=t),\
MoveToTarget(a2[i],rate_func=linear,run_time=t),\
MoveToTarget(a3[i],rate_func=linear,run_time=t),\
lag_ratio=txty[i])\
for i in range(1,rows)])
self.play(AnimationGroup(*func()))
self.wait(10)
Output
suspend_mobject_updating
suspend_mobject_updating is the flag used to specify whether the
suspend_updating() function of an animation object will be resumed by
resume_updating() after the animation.
Example
Code
# folder/file: tut/manim_animation_animation_updating_001a.py
from manimlib.imports import *
from manimlib.scene.scene import Scene
from manimlib.mobject.mobject import Group
from manimlib.mobject.geometry import Dot, Circle, Square
from manimlib.animation.creation import ShowCreation
from manimlib.animation.transform import Transform, ReplacementTransform, TransformFromCopy, MoveToTarget, ApplyMethod
from manimlib.mobject.svg.tex_mobject import TextMobject, TexMobject
from manimlib.animation.composition import AnimationGroup
class manim_animation_animation_updating_001a(Scene):
def construct(self):
rows,cols=(5,3)
x0=[-5,-2,4,2.9]
y0=[3,*[1.5-1.2*i for i in range(rows)]]
txtx=["suspend\_updating()","","suspend\_mobject\_updating"]
for i in range(cols): self.add(TextMobject(txtx[i]).move_to(([x0[i],y0[0],0])))
txty=[("",""),("1",True),("1",False),("0",True),("0",False)]
objs=[];t=18
for i in range(rows):
objs.append(Square().scale(0.5).move_to([x0[1],y0[i],0]).add_updater(lambda m, dt: m.shift(dt * RIGHT*0.005*t)))
self.add(TextMobject(txty[i][0]).move_to(([x0[0],y0[i],0])))
self.add(TextMobject(str(txty[i][1])).move_to(([x0[2],y0[i],0])))
self.add(*objs)
self.wait()
objs[1].suspend_updating()
objs[2].suspend_updating()
def anims():
return tuple([DrawBorderThenFill(objs[i],suspend_mobject_updating=txty[i][1],run_time=0.6*t) for i in range(1,rows)])
self.play(AnimationGroup(*anims()))
self.wait(t)
for obj in objs: obj.clear_updaters()
self.wait(t)
Output