Description
Description of bug / unexpected behavior
As far as I can, there is no way to easily (even sequentially) compose animations into a new animations, at least if the animations work on the same object. Indeed, I can't find any way to produce an animation anim3
that is the sequential composition of anim1
and anim2
, as soon as anim1
and anim2
work an the same object. For instance, if we consider this code (see below for full usable code):
class Intro(Scene):
def construct(self):
libA = Rectangle(color=GREY, stroke_width=0, fill_opacity=1.0,fill_color=GRAY)
libB = Circle(color=RED, stroke_width=0, fill_opacity=1.0,fill_color=RED)
self.play(FadeIn(libA))
# Make libB replace libA while rotating the elements
libB.rotate(-PI/2, axis=(0,1,0))
self.play(Rotate(libA, angle=PI/2, axis=(0,1,0)))
self.play(FadeIn(libB, run_time=1/25),
FadeOut(libA, run_time=1/25)),
self.play(Rotate(libB, angle=PI/2, axis=(0,1,0)))
self.wait()
then the animation plays smoothly :
scriptoutput.mp4
but if I merge them all in a single animation (using AnimationGroup
that seems to be the only method available as far as I see), then this fails:
from manim import *
class Intro(Scene):
def construct(self):
libA = Rectangle(color=GREY, stroke_width=0, fill_opacity=1.0,fill_color=GRAY)
libB = Circle(color=RED, stroke_width=0, fill_opacity=1.0,fill_color=RED)
self.play(FadeIn(libA))
# Make libB replace libA while rotating the elements
libB.rotate(-PI/2, axis=(0,1,0))
### This fails
self.play(AnimationGroup(
Rotate(libA, angle=PI/2, axis=(0,1,0)),
AnimationGroup(
FadeIn(libB, run_time=1/25),
FadeOut(libA, run_time=1/25)),
Rotate(libB, angle=PI/2, axis=(0,1,0)),
lag_ratio=1))
self.wait()
scriptoutput_.mp4
Note that I understand that applying multiple animations on the same object can be challenging if we apply them in parallel… but for sequential composition I don't see any conceptual difficulty.
Expected behavior
I expect animations to be composable trivially. Note that I do not want to use many self.play
for many reasons:
- first, the animation is supposed to be abstracted into a library, and asking the user to manually loop over a list of animations is really dirty, I would prefer the user to write only
self.play(myobject.turn_into(my_otherobject))
. - then, it is harder to control the easing curves of animations played composed with multiple
self.play
as the easing curve would be to be split into multiple pieces - it is even harder to compose this animation with another (independent) animation in parallel, as we would need to cut the parallel animation into multiple sub-animations that last the same time as the sub-animations… ugly.
How to reproduce the issue
Code for reproducing the problem
from manim import *
class Intro(Scene):
def construct(self):
libA = Rectangle(color=GREY, stroke_width=0, fill_opacity=1.0,fill_color=GRAY)
libB = Circle(color=RED, stroke_width=0, fill_opacity=1.0,fill_color=RED)
self.play(FadeIn(libA))
# Make libB replace libA while rotating the elements
libB.rotate(-PI/2, axis=(0,1,0))
### This fails
self.play(AnimationGroup(
Rotate(libA, angle=PI/2, axis=(0,1,0)),
AnimationGroup(
FadeIn(libB, run_time=1/25),
FadeOut(libA, run_time=1/25)),
Rotate(libB, angle=PI/2, axis=(0,1,0)),
lag_ratio=1))
self.wait()
You might also want to see a related discussion on discord https://discord.com/channels/581738731934056449/1142285601232662538
Metadata
Metadata
Assignees
Type
Projects
Status