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

Code before:
                sine = ax.plot(np.sin, color=RED)
                alpha = ValueTracker(0)
                point = always_redraw(
                        lambda: Dot(
                            sine.point_from_proportion(alpha.get_value()),
                            color=BLUE)
                    )
                tangent = always_redraw(
                    lambda: TangentLine(
                        sine,
                        alpha=alpha.get_value(),
                        color=YELLOW,
                        length=4)
                )
                self.add(ax, sine, point, tangent)
                self.play(alpha.animate.set_value(1), rate_func=linear, run_time=2)
    """
    mob = func()
    mob.add_updater(lambda _: mob.become(func()))
    return mob


def always_shift(
    mobject: Mobject, direction: np.ndarray[np.float64] = RIGHT, rate: float = 0.1
) -> Mobject:
    """Shift the mobject by `rate*direction` every second

    Parameters
    ----------
    mobject
        The mobject to shift
    direction
        The direction to shift
    rate
        Amount of direction to be covered in one second

    Examples
    --------

    .. manim:: ShiftingSquare

        class ShiftingSquare(Scene):
            def construct(self):
                sq = Square().set_fill(opacity=1)
                tri = Triangle()
                VGroup(sq, tri).arrange(LEFT)

                # always shift square one unit to the right
                # even if there is an animation going on
                always_shift(sq, RIGHT, rate=5)


Review comment (suggestion):
```suggestion
    """A mobject which is continuously shifted along some direction
    at a certain rate.
```

Code after:

        class TangentAnimation(Scene):
            def construct(self):
                ax = Axes()
                sine = ax.plot(np.sin, color=RED)
                alpha = ValueTracker(0)
                point = always_redraw(
                    lambda: Dot(
                        sine.point_from_proportion(alpha.get_value()),
                        color=BLUE
                    )
                )
                tangent = always_redraw(
                    lambda: TangentLine(
                        sine,
                        alpha=alpha.get_value(),
                        color=YELLOW,
                        length=4
                    )
                )
                self.add(ax, sine, point, tangent)
                self.play(alpha.animate.set_value(1), rate_func=linear, run_time=2)
    """
    mob = func()
    mob.add_updater(lambda _: mob.become(func()))
    return mob


def always_shift(
    mobject: Mobject, direction: np.ndarray[np.float64] = RIGHT, rate: float = 0.1
) -> Mobject:
    """A mobject which is continuously shifted along some direction
    at a certain rate.

    Parameters
    ----------
    mobject
        The mobject to shift.
    direction
        The direction to shift. The vector is normalized, the specified magnitude
        is not relevant.
    rate
        Length in Manim units which the mobject travels in one
        second along the specified direction.

    Examples
    --------

    .. manim:: ShiftingSquare

        class ShiftingSquare(Scene):