diff --git a/manim/scene/scene.py b/manim/scene/scene.py index 9ea3e31749..7a2910c856 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -885,6 +885,33 @@ def clear(self) -> Self: self.foreground_mobjects = [] return self + def recursively_unpack_animation_groups( + self, *animations: Animation + ) -> list[Mobject | OpenGLMobject]: + """ + Unpacks animations + Parameters + ---------- + *animations + The animations to unpack + Returns + ------ + list + The list of mobjects in animations + """ + # Imported inside the method to avoid cyclic import + from ..animation.composition import AnimationGroup + + unpacked_mobjects = [] + for anim in animations: + if isinstance(anim, AnimationGroup): + for sub in anim.animations: + unpacked = self.recursively_unpack_animation_groups(sub) + unpacked_mobjects.extend(unpacked) + else: + unpacked_mobjects.append(anim.mobject) + return unpacked_mobjects + def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]: """ Gets all moving mobjects in the passed animation(s). @@ -904,7 +931,7 @@ def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]: # as soon as there's one that needs updating of # some kind per frame, return the list from that # point forward. - animation_mobjects = [anim.mobject for anim in animations] + animation_mobjects = self.recursively_unpack_animation_groups(*animations) mobjects = self.get_mobject_family_members() for i, mob in enumerate(mobjects): update_possibilities = [ diff --git a/tests/test_graphical_units/control_data/geometry/negative_z_index_AnimationGroup.npz b/tests/test_graphical_units/control_data/geometry/negative_z_index_AnimationGroup.npz new file mode 100644 index 0000000000..80ba71a0eb Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/negative_z_index_AnimationGroup.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/negative_z_index_LaggedStart.npz b/tests/test_graphical_units/control_data/geometry/negative_z_index_LaggedStart.npz new file mode 100644 index 0000000000..dd5e8344d9 Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/negative_z_index_LaggedStart.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/nested_animation_groups_with_negative_z_index.npz b/tests/test_graphical_units/control_data/geometry/nested_animation_groups_with_negative_z_index.npz new file mode 100644 index 0000000000..65c25c6995 Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/nested_animation_groups_with_negative_z_index.npz differ diff --git a/tests/test_graphical_units/test_geometry.py b/tests/test_graphical_units/test_geometry.py index fef2ca0951..9f9b6eda59 100644 --- a/tests/test_graphical_units/test_geometry.py +++ b/tests/test_graphical_units/test_geometry.py @@ -174,6 +174,27 @@ def test_ZIndex(scene): scene.play(ApplyMethod(triangle.shift, 2 * UP)) +@frames_comparison(last_frame=False) +def test_negative_z_index_AnimationGroup(scene): + # https://github.com/ManimCommunity/manim/issues/3334 + s = Square().set_z_index(-1) + scene.play(AnimationGroup(GrowFromCenter(s))) + + +@frames_comparison(last_frame=False) +def test_negative_z_index_LaggedStart(scene): + # https://github.com/ManimCommunity/manim/issues/3914 + line_1 = Line(LEFT, RIGHT, color=BLUE) + line_2 = Line(UP + LEFT, UP + RIGHT, color=RED).set_z_index(-1) + scene.play(LaggedStart(FadeIn(line_1), FadeIn(line_2), lag_ratio=0.5)) + + +@frames_comparison(last_frame=False) +def test_nested_animation_groups_with_negative_z_index(scene): + line = Line(LEFT, RIGHT, color=BLUE).set_z_index(-1) + scene.play(AnimationGroup(AnimationGroup(AnimationGroup(FadeIn(line))))) + + @frames_comparison def test_Angle(scene): l1 = Line(ORIGIN, RIGHT)