Skip to content

Commit 8320cdd

Browse files
JasonGrace2282pre-commit-ci[bot]behackl
authored
Added docs for functions in mobject_update_utils (#3325)
* Added docs for functions in mobject_update_utils * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Updated docstring of always_shift Co-authored-by: Benjamin Hackl <[email protected]> * Added period to sentence. Co-authored-by: Benjamin Hackl <[email protected]> * Updated parameter description in always_redraw Co-authored-by: Benjamin Hackl <[email protected]> * Update always_rotate description Co-authored-by: Benjamin Hackl <[email protected]> * Finished parameters in always_redraw Co-authored-by: Benjamin Hackl <[email protected]> * Changed comment in always_shift Co-authored-by: Benjamin Hackl <[email protected]> * update always_shift description Co-authored-by: Benjamin Hackl <[email protected]> * used normalize from manim.utils.space_ops * fixed indentation in always_redraw * added type-hints * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <[email protected]>
1 parent 7ad7e99 commit 8320cdd

File tree

1 file changed

+98
-18
lines changed

1 file changed

+98
-18
lines changed

manim/animation/updaters/mobject_update_utils.py

Lines changed: 98 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,34 @@
1515

1616

1717
import inspect
18-
from collections.abc import Callable
18+
from typing import TYPE_CHECKING, Callable
1919

2020
import numpy as np
2121

2222
from manim.constants import DEGREES, RIGHT
2323
from manim.mobject.mobject import Mobject
2424
from manim.opengl import OpenGLMobject
25+
from manim.utils.space_ops import normalize
2526

27+
if TYPE_CHECKING:
28+
from manim.animation.animation import Animation
2629

27-
def assert_is_mobject_method(method):
30+
31+
def assert_is_mobject_method(method: Callable) -> None:
2832
assert inspect.ismethod(method)
2933
mobject = method.__self__
3034
assert isinstance(mobject, (Mobject, OpenGLMobject))
3135

3236

33-
def always(method, *args, **kwargs):
37+
def always(method: Callable, *args, **kwargs) -> Mobject:
3438
assert_is_mobject_method(method)
3539
mobject = method.__self__
3640
func = method.__func__
3741
mobject.add_updater(lambda m: func(m, *args, **kwargs))
3842
return mobject
3943

4044

41-
def f_always(method, *arg_generators, **kwargs):
45+
def f_always(method: Callable[[Mobject], None], *arg_generators, **kwargs) -> Mobject:
4246
"""
4347
More functional version of always, where instead
4448
of taking in args, it takes in functions which output
@@ -80,16 +84,18 @@ def construct(self):
8084
sine = ax.plot(np.sin, color=RED)
8185
alpha = ValueTracker(0)
8286
point = always_redraw(
83-
lambda: Dot(
84-
sine.point_from_proportion(alpha.get_value()),
85-
color=BLUE)
87+
lambda: Dot(
88+
sine.point_from_proportion(alpha.get_value()),
89+
color=BLUE
8690
)
91+
)
8792
tangent = always_redraw(
8893
lambda: TangentLine(
8994
sine,
9095
alpha=alpha.get_value(),
9196
color=YELLOW,
92-
length=4)
97+
length=4
98+
)
9399
)
94100
self.add(ax, sine, point, tangent)
95101
self.play(alpha.animate.set_value(1), rate_func=linear, run_time=2)
@@ -99,36 +105,110 @@ def construct(self):
99105
return mob
100106

101107

102-
def always_shift(mobject, direction=RIGHT, rate=0.1):
103-
def normalize(v):
104-
norm = np.linalg.norm(v)
105-
if norm == 0:
106-
return v
107-
return v / norm
108+
def always_shift(
109+
mobject: Mobject, direction: np.ndarray[np.float64] = RIGHT, rate: float = 0.1
110+
) -> Mobject:
111+
"""A mobject which is continuously shifted along some direction
112+
at a certain rate.
113+
114+
Parameters
115+
----------
116+
mobject
117+
The mobject to shift.
118+
direction
119+
The direction to shift. The vector is normalized, the specified magnitude
120+
is not relevant.
121+
rate
122+
Length in Manim units which the mobject travels in one
123+
second along the specified direction.
124+
125+
Examples
126+
--------
127+
128+
.. manim:: ShiftingSquare
129+
130+
class ShiftingSquare(Scene):
131+
def construct(self):
132+
sq = Square().set_fill(opacity=1)
133+
tri = Triangle()
134+
VGroup(sq, tri).arrange(LEFT)
135+
136+
# construct a square which is continuously
137+
# shifted to the right
138+
always_shift(sq, RIGHT, rate=5)
108139
140+
self.add(sq)
141+
self.play(tri.animate.set_fill(opacity=1))
142+
"""
109143
mobject.add_updater(lambda m, dt: m.shift(dt * rate * normalize(direction)))
110144
return mobject
111145

112146

113-
def always_rotate(mobject, rate=20 * DEGREES, **kwargs):
147+
def always_rotate(mobject: Mobject, rate: float = 20 * DEGREES, **kwargs) -> Mobject:
148+
"""A mobject which is continuously rotated at a certain rate.
149+
150+
Parameters
151+
----------
152+
mobject
153+
The mobject to be rotated.
154+
rate
155+
The angle which the mobject is rotated by
156+
over one second.
157+
kwags
158+
Further arguments to be passed to :meth:`.Mobject.rotate`.
159+
160+
Examples
161+
--------
162+
163+
.. manim:: SpinningTriangle
164+
165+
class SpinningTriangle(Scene):
166+
def construct(self):
167+
tri = Triangle().set_fill(opacity=1).set_z_index(2)
168+
sq = Square().to_edge(LEFT)
169+
170+
# will keep spinning while there is an animation going on
171+
always_rotate(tri, rate=2*PI, about_point=ORIGIN)
172+
173+
self.add(tri, sq)
174+
self.play(sq.animate.to_edge(RIGHT), rate_func=linear, run_time=1)
175+
"""
114176
mobject.add_updater(lambda m, dt: m.rotate(dt * rate, **kwargs))
115177
return mobject
116178

117179

118-
def turn_animation_into_updater(animation, cycle=False, **kwargs):
180+
def turn_animation_into_updater(
181+
animation: Animation, cycle: bool = False, **kwargs
182+
) -> Mobject:
119183
"""
120184
Add an updater to the animation's mobject which applies
121185
the interpolation and update functions of the animation
122186
123187
If cycle is True, this repeats over and over. Otherwise,
124188
the updater will be popped upon completion
189+
190+
Examples
191+
--------
192+
193+
.. manim:: WelcomeToManim
194+
195+
class WelcomeToManim(Scene):
196+
def construct(self):
197+
words = Text("Welcome to")
198+
banner = ManimBanner().scale(0.5)
199+
VGroup(words, banner).arrange(DOWN)
200+
201+
turn_animation_into_updater(Write(words, run_time=0.9))
202+
self.add(words)
203+
self.wait(0.5)
204+
self.play(banner.expand(), run_time=0.5)
125205
"""
126206
mobject = animation.mobject
127207
animation.suspend_mobject_updating = False
128208
animation.begin()
129209
animation.total_time = 0
130210

131-
def update(m, dt):
211+
def update(m: Mobject, dt: float):
132212
run_time = animation.get_run_time()
133213
time_ratio = animation.total_time / run_time
134214
if cycle:
@@ -147,5 +227,5 @@ def update(m, dt):
147227
return mobject
148228

149229

150-
def cycle_animation(animation, **kwargs):
230+
def cycle_animation(animation: Animation, **kwargs) -> Mobject:
151231
return turn_animation_into_updater(animation, cycle=True, **kwargs)

0 commit comments

Comments
 (0)