Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed animations introducing or removing objects #2396

Merged
merged 11 commits into from
Jan 23, 2022

Conversation

marcin-serwin
Copy link
Collaborator

@marcin-serwin marcin-serwin commented Dec 25, 2021

Overview: What does this pull request change?

  • :class:.ShowPassingFlash now removes objects when the animation is finished
  • Added introducer keyword argument to :class:.Animation analogous to remover
  • Updated :class:.Graph vertex addition handling

Motivation and Explanation: Why and how do your changes improve the library?

Fixes #2349.

Links to added or changed documentation pages

Further Information and Comments

Code:

class IntroducersInSuccession(Scene):
    def construct(self):
        mobjs = [Square() for _ in range(11)]
        VGroup(*mobjs[:6]).arrange().shift(2 * UP)
        VGroup(*mobjs[6:]).arrange().shift(2 * DOWN)
        self.play(
            Succession(
                Circumscribe(mobjs[0]),
                ShowSubmobjectsOneByOne(mobjs[1]),
                Create(mobjs[2]),
                FadeIn(mobjs[3]),
                Write(mobjs[4]),
                Unwrite(mobjs[5]),
                GrowFromCenter(mobjs[6]),
                ShowPassingFlash(mobjs[7]),
                SpinInFromNothing(mobjs[8]),
                FadeOut(mobjs[9]),
                DrawBorderThenFill(mobjs[10]),
            )
        )

Before:

IntroducersInSuccession.mp4

After:

IntroducersInSuccession.mp4

Reviewer Checklist

  • The PR title is descriptive enough for the changelog, and the PR is labeled correctly
  • If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
  • If applicable: newly added functions and classes are tested

@marcin-serwin marcin-serwin marked this pull request as draft December 25, 2021 03:16
@marcin-serwin marcin-serwin marked this pull request as ready for review December 25, 2021 14:07
@behackl
Copy link
Member

behackl commented Dec 31, 2021

I like the semantics of this approach! In particular, the new method for preparing the scene seems useful. I'll have to think a bit more about this and how it interacts with the already present machinery for adding mobjects (the moving_mobjects and the Scene.add_mobjects_from_animations stuff), but in general this looks very clean.

For now, thank you!

@behackl behackl self-requested a review December 31, 2021 01:25
@behackl behackl added the enhancement Additions and improvements in general label Dec 31, 2021
Copy link
Member

@behackl behackl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I like these changes – thanks again for your efforts! There are some things I am somewhat unhappy with (like the fact that this makes it less easy to understand when in an Animation's life cycle mobjects are added to the scene), but I think the fact that this PR makes Animations more symmetric with the introducer keyword arg on the one hand, and the setup_scene method on the other hand, outweighs my concerns.

It would be good to have another dev look over this / approve it before it is merged.

@@ -112,6 +117,7 @@ def interpolate(self, alpha: float) -> None:
class Succession(AnimationGroup):
def __init__(self, *animations: Animation, lag_ratio: float = 1, **kwargs) -> None:
super().__init__(*animations, lag_ratio=lag_ratio, **kwargs)
self.scene = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see why this is necessary, but I don't quite like it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was needed only because some tests didn't call setup_scene before begin. I've updated them and it's no longer necessary.

@@ -497,7 +497,7 @@ def __getitem__(self: "Graph", v: Hashable) -> "Mobject":
def __repr__(self: "Graph") -> str:
return f"Graph on {len(self.vertices)} vertices and {len(self.edges)} edges"

def _add_vertex(
def _create_vertex(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like these changes to Graph vertex creation, regardless of the changed overridden animation. I do have to admit: I don't like the amount of bending of the Animation framework that needs to be done to make custom overrides of vertex creation work. Maybe it is not worth keeping the @override_animate idea around.

Copy link
Member

@Darylgolden Darylgolden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM in general, just some questions and comments.

if self.is_remover():
scene.remove(self.mobject)

def setup_scene(self, scene: "Scene") -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be prefaced with a single underscore to mark it as only for internal use?

@@ -434,6 +456,16 @@ def is_remover(self) -> bool:
"""
return self.remover

def is_introducer(self) -> bool:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this method only returns the value of an attribute, is it really needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's made this way to mirror the is_remover method.

self.suspend_mobject_updating: bool = suspend_mobject_updating
self.lag_ratio: float = lag_ratio
self._on_finish: Callable[["Scene"], None] = _on_finish
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to mark typehints with the actual class rather than a string.

The mobject to be used as the vertex. Overrides all other
vertex customization options.
"""
) -> Tuple[Hashable, np.ndarray, dict, "Mobject"]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typehint, see above

vertex: Hashable,
position: np.ndarray,
vertex_config: dict,
vertex_mobject: "Mobject",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typehints, see above

Copy link
Member

@Darylgolden Darylgolden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@Darylgolden Darylgolden changed the title Fix animations introducing or removing objects Fixed animations introducing or removing objects Jan 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Additions and improvements in general
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Circumscribe combined with lag_ratio causes the box to be drawn after the animation finishes
3 participants