Repository: ManimCommunity/manim
File: manim/animation/creation.py (Python)

Code before:
        shapes: Mobject,
        scale_factor: float = 8,
        fade_in_fraction=0.3,
        **kwargs,
    ) -> None:
        self.shapes = shapes
        self.scale_factor = scale_factor
        self.shape_center = shapes.get_center()
        self.fade_in_fraction = fade_in_fraction
        for shape in shapes:
            shape.final_position = shape.get_center()
            shape.initial_position = (
                shape.final_position
                + (shape.final_position - self.shape_center) * self.scale_factor
            )
            shape.move_to(shape.initial_position)
            shape.save_state()

        super().__init__(shapes, introducer=True, **kwargs)

    def interpolate_mobject(self, alpha: float) -> None:
        alpha = self.rate_func(alpha)
        for shape in self.shapes:
            shape.restore()
            shape.save_state()
            opacity = shape.get_fill_opacity() or 1
            new_opacity = min(opacity, alpha * opacity / self.fade_in_fraction)
            shape.shift((shape.final_position - shape.initial_position) * alpha)
            shape.rotate(TAU * alpha, about_point=self.shape_center)
            shape.rotate(-TAU * alpha, about_point=shape.get_center_of_mass())
            shape.set_opacity(new_opacity)


class ShowIncreasingSubsets(Animation):
    """Show one submobject at a time, leaving all previous ones displayed on screen.

    Examples
    --------

    .. manim:: ShowIncreasingSubsetsScene

        class ShowIncreasingSubsetsScene(Scene):
            def construct(self):
                p = VGroup(Dot(), Square(), Triangle())
                self.add(p)
                self.play(ShowIncreasingSubsets(p))
                self.wait()
    """

    def __init__(
        self,

Review comment (suggestion):
I'm not sure this is the correct solution here as it modifies the fill opacity of a given mobject -- this actually also happens in the test that you added; at the end of `SpiralIn`, the mobjects should be added to the scene with the opacity values they have been initialized with.

My suggestion for a slightly more complicated fix would be to split the current `opacity` into the typical `stroke_opacity` and `fill_opacity`, and then update both of them according to the rule given in `new_opacity`.

That way, no unexpected opacity changes happen.

Code after:
        shapes: Mobject,
        scale_factor: float = 8,
        fade_in_fraction=0.3,
        **kwargs,
    ) -> None:
        self.shapes = shapes.copy()
        self.scale_factor = scale_factor
        self.shape_center = shapes.get_center()
        self.fade_in_fraction = fade_in_fraction
        for shape in shapes:
            shape.final_position = shape.get_center()
            shape.initial_position = (
                shape.final_position
                + (shape.final_position - self.shape_center) * self.scale_factor
            )
            shape.move_to(shape.initial_position)
            shape.save_state()

        super().__init__(shapes, introducer=True, **kwargs)

    def interpolate_mobject(self, alpha: float) -> None:
        alpha = self.rate_func(alpha)
        for original_shape, shape in zip(self.shapes, self.mobject):
            shape.restore()
            fill_opacity = original_shape.get_fill_opacity()
            stroke_opacity = original_shape.get_stroke_opacity()
            new_fill_opacity = min(
                fill_opacity, alpha * fill_opacity / self.fade_in_fraction
            )
            new_stroke_opacity = min(
                stroke_opacity, alpha * stroke_opacity / self.fade_in_fraction
            )
            shape.shift((shape.final_position - shape.initial_position) * alpha)
            shape.rotate(TAU * alpha, about_point=self.shape_center)
            shape.rotate(-TAU * alpha, about_point=shape.get_center_of_mass())
            shape.set_fill(opacity=new_fill_opacity)
            shape.set_stroke(opacity=new_stroke_opacity)


class ShowIncreasingSubsets(Animation):
    """Show one submobject at a time, leaving all previous ones displayed on screen.

    Examples
    --------

    .. manim:: ShowIncreasingSubsetsScene

        class ShowIncreasingSubsetsScene(Scene):
            def construct(self):
                p = VGroup(Dot(), Square(), Triangle())
                self.add(p)