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

Code before:
        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)

                self.add(sq)
                self.play(tri.animate.set_fill(opacity=1))
    """

    def normalize(v):
        norm = np.linalg.norm(v)
        if norm == 0:
            return v
        return v / norm

    mobject.add_updater(lambda m, dt: m.shift(dt * rate * normalize(direction)))
    return mobject


def always_rotate(mobject: Mobject, rate: float = 20 * DEGREES, **kwargs) -> Mobject:
    """Rotate the mobject by `rate` every second

    Parameters
    ----------
    mobject
        The mobject to rotate

    Examples
    --------

    .. manim:: SpinningTriangle

        class SpinningTriangle(Scene):
            def construct(self):
                tri = Triangle().set_fill(opacity=1).set_z_index(2)
                sq = Square().to_edge(LEFT)

                # will keep spinning while there is an animation going on
                always_rotate(tri, rate=2*PI, about_point=ORIGIN)

                self.add(tri, sq)
                self.play(sq.animate.to_edge(RIGHT), rate_func=linear, run_time=1)
    """
    mobject.add_updater(lambda m, dt: m.rotate(dt * rate, **kwargs))
    return mobject


Review comment (suggestion):
```suggestion
    """A mobject which is continuously rotated at a certain rate.
```

Code after:
    rate
        Length in Manim units which the mobject travels in one
        second along the specified direction.

    Examples
    --------

    .. manim:: ShiftingSquare

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

                # construct a square which is continuously
                # shifted to the right
                always_shift(sq, RIGHT, rate=5)

                self.add(sq)
                self.play(tri.animate.set_fill(opacity=1))
    """
    mobject.add_updater(lambda m, dt: m.shift(dt * rate * normalize(direction)))
    return mobject


def always_rotate(mobject: Mobject, rate: float = 20 * DEGREES, **kwargs) -> Mobject:
    """A mobject which is continuously rotated at a certain rate.

    Parameters
    ----------
    mobject
        The mobject to be rotated.
    rate
        The angle which the mobject is rotated by
        over one second.
    kwags
        Further arguments to be passed to :meth:`.Mobject.rotate`.

    Examples
    --------

    .. manim:: SpinningTriangle

        class SpinningTriangle(Scene):
            def construct(self):
                tri = Triangle().set_fill(opacity=1).set_z_index(2)
                sq = Square().to_edge(LEFT)

                # will keep spinning while there is an animation going on
                always_rotate(tri, rate=2*PI, about_point=ORIGIN)