Deferred Animation builder to only modify mobjects after the animation is actually played
Passing a flag to .animate was a bit too complicated and would destroy the property aspect of it, now we can also use deferred as a property.
I split the _AnimationBuilder into two subclasses which fulfill their respective roles, whereas _ImmediateAnimationBuilder is the usual builder that we know and love and _DeferredAnimationBuilder is the new builder which actually is delaying the building of the state until the animation is played. I added an example to the documentation, I am not sure if I should add tests for that or what would be a useful test.
But first i would like to discuss the concept, i linked a documentation page for this.
https://manimce--3502.org.readthedocs.build/en/3502/reference/manim.mobject.mobject.Mobject.html?highlight=deferred#deferredexample
class MinimalExample(Scene):
def construct(self):
objects = []
animations = []
animations2 = []
for i in range(10):
m = Square().set_color(BLUE).set_fill(opacity=0.3).scale(0.5)
objects.append(m)
animations.append(ReplacementTransform(m.copy(),m))
if i % 2 == 0:
animations2.append(m.animate.set_color(GREEN))
else:
animations2.append(FadeOut(m))
group = VGroup(*objects).arrange_in_grid()
self.play(*animations, run_time=2)
self.wait()
self.play(*animations2, run_time=2)
self.wait()
vs.
class Expected(Scene):
def construct(self):
objects = []
animations = []
animations2 = []
l1 = []
l2 = []
for i in range(10):
m = Square().set_color(BLUE).set_fill(opacity=0.3).scale(0.5)
objects.append(m)
animations.append(ReplacementTransform(m.copy(),m))
if i % 2 == 0:
l1.append(m)
else:
l2.append(m)
group = VGroup(*objects).arrange_in_grid()
self.play(*animations, run_time=2)
self.wait()
self.play(*[x.animate.set_color(GREEN) for x in l1],*[FadeOut(x) for x in l2], run_time=2)
self.wait()```
Marked as draft, as requested by MrDiver internally.
Are there usecases for both the deferred and the immediate builder? I can see how the deferred one is useful. 🤔
Are there usecases for both the deferred and the immediate builder? I can see how the deferred one is useful. 🤔
It definitely broke a lot of tests when i only used the deferred one, so maybe there are a lot of edge cases where it's useful to have .animate i am not sure how changing the default to deferred would affect everything but i must say i also haven't looked to deep into why the tests are failing and assumed it was my sloppy implementation at that point.
But i guess there are usecases for both, the instant .animate is way more useful if you directly animate the mobject because it causes a lot less overhead and maybe weird behavior because your using the state right now and that also accounts for all the other mobject states with like .become which will instantly generate a state and with the .deferred it will use also the target mobject state that is present at animation .begin time so it really depends on a lot of edge cases what the user wants and i really don't want to assume that they want the deferred behavior 🤷🏼
I think the main benefit might lie in combination with AnimationGroup.
Such that you can build a list of animations with the deferred animation builder and then later on use them in an animation group for complex transitions which depend on the current state of the scene and not when the Mobjects were created.