Switch old syntax for animating methods to .animate syntax

This commit is contained in:
friedkeenan
2021-02-10 09:10:31 -06:00
parent d24ba30fde
commit cfd32c79b1
5 changed files with 135 additions and 114 deletions

View File

@ -12,11 +12,11 @@ class SquareToCircle(Scene):
self.play(ReplacementTransform(square, circle))
self.wait()
# Try typing the following lines
# self.play(circle.stretch, 4, {"dim": 0})
# self.play(circle.animate.stretch(4, dim=0))
# self.play(Rotate(circle, TAU / 4))
# self.play(circle.shift, 2 * RIGHT, circle.scale, 0.25)
# self.play(circle.animate.shift(2 * RIGHT), circle.animate.scale(0.25))
# circle.insert_n_curves(10)
# self.play(circle.apply_complex_function, lambda z: z**2)
# self.play(circle.animate.apply_complex_function(lambda z: z**2))
class SquareToCircleEmbed(Scene):
def construct(self):
@ -26,12 +26,12 @@ class SquareToCircleEmbed(Scene):
self.add(circle)
self.wait()
self.play(circle.stretch, 4, {"dim": 0})
self.play(circle.animate.stretch(4, dim=0))
self.wait(1.5)
self.play(Rotate(circle, TAU / 4))
self.wait(1.5)
self.play(circle.shift, 2 * RIGHT, circle.scale, 0.25)
self.play(circle.animate.shift(2 * RIGHT), circle.animate.scale(0.25))
self.wait(1.5)
circle.insert_n_curves(10)
self.play(circle.apply_complex_function, lambda z: z**2)
self.play(circle.animate.apply_complex_function(lambda z: z**2))
self.wait(2)

View File

@ -1,8 +1,8 @@
Example Scenes
==============
After understanding the previous knowledge, we can understand more scenes.
Many example scenes are given in ``example_scenes.py``, let's start with
After understanding the previous knowledge, we can understand more scenes.
Many example scenes are given in ``example_scenes.py``, let's start with
the simplest and one by one.
SquareToCircle
@ -19,7 +19,7 @@ SquareToCircle
circle.set_fill(BLUE, opacity=0.5)
circle.set_stroke(BLUE_E, width=4)
square = Square()
self.play(ShowCreation(square))
self.wait()
self.play(ReplacementTransform(square, circle))
@ -39,40 +39,52 @@ AnimatingMethods
grid = Tex(r"\pi").get_grid(10, 10, height=4)
self.add(grid)
# If you pass in a mobject method to the scene's "play" function,
# it will apply an animation interpolating between the mobject's
# initial state and whatever happens when you apply that method.
# For example, calling grid.shift(2 * LEFT) would shift it two units
# to the left, but the following line animates that motion.
self.play(grid.shift, 2 * LEFT)
# You can animate the application of mobject methods with the
# ".animate" syntax:
self.play(grid.animate.shift(LEFT))
# Alternatively, you can use the older syntax by passing the
# method and then the arguments to the scene's "play" function:
self.play(grid.shift, LEFT)
# Both of those will interpolate between the mobject's initial
# state and whatever happens when you apply that method.
# For this example, calling grid.shift(LEFT) would shift the
# grid one unit to the left, but both of the previous calls to
# "self.play" animate that motion.
# The same applies for any method, including those setting colors.
self.play(grid.set_submobject_colors_by_gradient, BLUE, GREEN)
self.play(grid.set_height, TAU - MED_SMALL_BUFF)
self.play(grid.animate.set_color(YELLOW))
self.wait()
self.play(grid.animate.set_submobject_colors_by_gradient(BLUE, GREEN))
self.wait()
self.play(grid.animate.set_height(TAU - MED_SMALL_BUFF))
self.wait()
# The method Mobject.apply_complex_function lets you apply arbitrary
# complex functions, treating the points defining the mobject as
# complex numbers.
self.play(grid.apply_complex_function, np.exp, run_time=5)
self.play(grid.animate.apply_complex_function(np.exp), run_time=5)
self.wait()
# Even more generally, you could apply Mobject.apply_function,
# which takes in functions form R^3 to R^3
self.play(
grid.apply_function,
lambda p: [
p[0] + 0.5 * math.sin(p[1]),
p[1] + 0.5 * math.sin(p[0]),
p[2]
],
grid.animate.apply_function(
lambda p: [
p[0] + 0.5 * math.sin(p[1]),
p[1] + 0.5 * math.sin(p[0]),
p[2]
]
),
run_time=5,
)
self.wait()
The new usage in this scene is ``.get_grid()`` and ``self.play(mob.method, args)``.
The new usage in this scene is ``.get_grid()`` and ``self.play(mob.animate.method(args))``.
- ``.get_grid()`` method will return a new mobject containing multiple copies of this one arranged in a grid.
- ``self.play(mob.method, args)`` animate the method, and the details are in the comments above.
- ``self.play(mob.animate.method(args))`` animates the method, and the details are in the comments above.
TextExample
-----------
@ -291,18 +303,18 @@ UpdatersExample
# Notice that the brace and label track with the square
self.play(
square.scale, 2,
square.animate.scale(2),
rate_func=there_and_back,
run_time=2,
)
self.wait()
self.play(
square.set_width, 5, {"stretch": True},
square.set_width(5, stretch=True),
run_time=3,
)
self.wait()
self.play(
square.set_width, 2,
square.animate.set_width(2),
run_time=3
)
self.wait()
@ -318,7 +330,7 @@ UpdatersExample
)
self.wait(4 * PI)
The new classes and usage in this scene are ``always_redraw()``, ``DecimalNumber``, ``.to_edge()``,
The new classes and usage in this scene are ``always_redraw()``, ``DecimalNumber``, ``.to_edge()``,
``.center()``, ``always()``, ``f_always()``, ``.set_y()`` and ``.add_updater()``.
- ``always_redraw()`` function create a new mobject every frame.
@ -400,8 +412,8 @@ SurfaceExample
self.play(
Transform(surface, surfaces[2]),
# Move camera frame during the transition
frame.increment_phi, -10 * DEGREES,
frame.increment_theta, -20 * DEGREES,
frame.animate.increment_phi(-10 * DEGREES),
frame.animate.increment_theta(-20 * DEGREES),
run_time=3
)
# Add ambient rotation
@ -416,8 +428,8 @@ SurfaceExample
light = self.camera.light_source
self.add(light)
light.save_state()
self.play(light.move_to, 3 * IN, run_time=5)
self.play(light.shift, 10 * OUT, run_time=5)
self.play(light.animate.move_to(3 * IN), run_time=5)
self.play(light.animate.shift(10 * OUT), run_time=5)
drag_text = Text("Try moving the mouse while pressing d or s")
drag_text.move_to(light_text)
@ -426,7 +438,7 @@ SurfaceExample
self.play(FadeTransform(light_text, drag_text))
self.wait()
This scene shows an example of using a three-dimensional surface, and
This scene shows an example of using a three-dimensional surface, and
the related usage has been briefly described in the notes.
- ``.fix_in_frame()`` makes the object not change with the view angle of the screen, and is always displayed at a fixed position on the screen.
@ -467,7 +479,7 @@ OpeningManimExample
FadeTransform(intro_words, linear_transform_words)
)
self.wait()
self.play(grid.apply_matrix, matrix, run_time=3)
self.play(grid.animate.apply_matrix(matrix), run_time=3)
self.wait()
# Complex map
@ -491,12 +503,12 @@ OpeningManimExample
)
self.wait()
self.play(
moving_c_grid.apply_complex_function, lambda z: z**2,
moving_c_grid.animate.apply_complex_function(lambda z: z**2),
run_time=6,
)
self.wait(2)
This scene is a comprehensive application of a two-dimensional scene.
After seeing these scenes, you have already understood part of the
After seeing these scenes, you have already understood part of the
usage of manim. For more examples, see `the video code of 3b1b <https://github.com/3b1b/videos>`_.

View File

@ -1,10 +1,10 @@
Quick Start
===========
After installing the manim environment according to the instructions on the
After installing the manim environment according to the instructions on the
:doc:`installation` page, you can try to make a scene yourself from scratch.
First, create a new ``.py`` file (such as ``start.py``) according to the following
First, create a new ``.py`` file (such as ``start.py``) according to the following
directory structure:
.. code-block:: text
@ -45,7 +45,7 @@ A window will pop up on the screen. And then you can :
- scroll the middle mouse button to move the screen up and down
- hold down the :kbd:`z` on the keyboard while scrolling the middle mouse button to zoom the screen
- hold down the :kbd:`s` key on the keyboard and move the mouse to pan the screen
- hold down the :kbd:`d` key on the keyboard and move the mouse to change the three-dimensional perspective.
- hold down the :kbd:`d` key on the keyboard and move the mouse to change the three-dimensional perspective.
Finally, you can close the window and exit the program by pressing :kbd:`q`.
@ -55,8 +55,8 @@ Run this command again:
python manim.py start.py SquareToCircle -os
At this time, no window will pop up. When the program is finished, this rendered
image will be automatically opened (saved in the subdirectory ``images/`` of the same
At this time, no window will pop up. When the program is finished, this rendered
image will be automatically opened (saved in the subdirectory ``images/`` of the same
level directory of ``start.py`` by default):
.. image:: ../_static/quickstart/SquareToCircle.png
@ -67,36 +67,36 @@ Make an image
Next, let's take a detailed look at what each row does.
**Line 1**:
**Line 1**:
.. code-block:: python
from manimlib.imports import *
This will import all the classes that may be used when using manim.
**Line 3**:
.. code-block:: python
class SquareToCircle(Scene):
Create a :class:`Scene` subclass ``SquareToCircle``, which will be
Create a :class:`Scene` subclass ``SquareToCircle``, which will be
the scene you write and render.
**Line 4**:
.. code-block:: python
def construct(self):
Write the ``construct()`` method, the content of which will determine
Write the ``construct()`` method, the content of which will determine
how to create the mobjects in the screen and what operations need to be performed.
**Line 5**:
.. code-block:: python
circle = Circle()
Create a circle (an instance of the :class:`Circle` class), called ``circle``
@ -104,7 +104,7 @@ Create a circle (an instance of the :class:`Circle` class), called ``circle``
**Line 6~7**:
.. code-block:: python
circle.set_fill(BLUE, opacity=0.5)
circle.set_stroke(BLUE_E, width=4)
@ -116,7 +116,7 @@ Set the circle style by calling the circle's method.
**Line 9**:
.. code-block:: python
self.add(circle)
Add this circle to the screen through the ``.add()`` method of :class:`Scene`.
@ -137,7 +137,7 @@ Let's change some codes and add some animations to make videos instead of just p
circle.set_fill(BLUE, opacity=0.5)
circle.set_stroke(BLUE_E, width=4)
square = Square()
self.play(ShowCreation(square))
self.wait()
self.play(ReplacementTransform(square, circle))
@ -149,51 +149,51 @@ Run this command this time:
python manim.py start.py SquareToCircle
The pop-up window will play animations of drawing a square and transforming
The pop-up window will play animations of drawing a square and transforming
it into a circle. If you want to save this video, run:
.. code-block:: sh
python manim.py start.py SquareToCircle -ow
This time there will be no pop-up window, but the video file (saved in the subdirectory
``videos/`` of the same level directory of ``start.py`` by default) will be automatically
This time there will be no pop-up window, but the video file (saved in the subdirectory
``videos/`` of the same level directory of ``start.py`` by default) will be automatically
opened after the operation is over:
.. raw:: html
<video class="manim-video" controls loop autoplay src="../_static/quickstart/SquareToCircle.mp4"></video>
Let's take a look at the code this time. The first 7 lines are the same as the previous
ones, and the 8th line is similar to the 5th line, which creates an instance of the
Let's take a look at the code this time. The first 7 lines are the same as the previous
ones, and the 8th line is similar to the 5th line, which creates an instance of the
:class:`Square` class and named it ``square``.
**Line 10**:
.. code-block:: python
self.play(ShowCreation(square))
An animation is played through :class:`Scene`'s ``.play()`` method. :class:`ShowCreation`
is an animation that shows the process of creating a given mobject.
is an animation that shows the process of creating a given mobject.
``self.play(ShowCreation(square))`` is to play the animation of creating ``square``.
**Line 11**:
.. code-block:: python
self.wait()
Use :class:`Scene`'s ``.wait()`` method to pause (default 1s), you can pass in
Use :class:`Scene`'s ``.wait()`` method to pause (default 1s), you can pass in
parameters to indicate the pause time (for example, ``self.wait(3)`` means pause for 3s).
**Line 12**:
.. code-block:: python
self.play(ReplacementTransform(square, circle))
Play the animation that transforms ``square`` into ``circle``.
Play the animation that transforms ``square`` into ``circle``.
``ReplacementTransform(A, B)`` means to transform A into B's pattern and replace A with B.
**Line 13**: Same as line 11, pause for 1s.
@ -202,34 +202,34 @@ Play the animation that transforms ``square`` into ``circle``.
Enable interaction
------------------
Interaction is a new feature of the new version. You can add the following line
Interaction is a new feature of the new version. You can add the following line
at the end of the code to enable interaction:
.. code-block:: python
self.embed()
Then run ``python manim.py start.py SquareToCircle``.
Then run ``python manim.py start.py SquareToCircle``.
After the previous animation is executed, the ipython terminal will be opened on
the command line. After that, you can continue to write code in it, and the statement
you entered will be executed immediately after pressing :kbd:`Enter`.
After the previous animation is executed, the ipython terminal will be opened on
the command line. After that, you can continue to write code in it, and the statement
you entered will be executed immediately after pressing :kbd:`Enter`.
For example: input the following lines (without comment lines) into it respectively
For example: input the following lines (without comment lines) into it respectively
(``self.play`` can be abbreviated as ``play`` in this mode):
.. code-block:: python
# Stretched 4 times in the vertical direction
play(circle.stretch, 4, {"dim": 0})
play(circle.animate.stretch(4, dim=0}))
# Rotate the ellipse 90°
play(Rotate(circle, TAU / 4))
# Move 2 units to the right and shrink to 1/4 of the original
play(circle.shift, 2 * RIGHT, circle.scale, 0.25)
play(circle.animate.shift(2 * RIGHT), circle.animate.scale(0.25))
# Insert 10 curves into circle for non-linear transformation (no animation will play)
circle.insert_n_curves(10)
# Apply a complex transformation of f(z)=z^2 to all points on the circle
play(circle.apply_complex_function, lambda z: z**2)
play(circle.animate.apply_complex_function(lambda z: z**2))
# Close the window and exit the program
exit()
@ -239,8 +239,8 @@ You will get an animation similar to the following:
<video class="manim-video" controls loop autoplay src="../_static/quickstart/SquareToCircleEmbed.mp4"></video>
If you want to enter the interactive mode directly, you don't have to write an
empty scene containing only ``self.embed()``, you can directly run the following command
If you want to enter the interactive mode directly, you don't have to write an
empty scene containing only ``self.embed()``, you can directly run the following command
(this will enter the ipython terminal while the window pops up):
.. code-block:: sh
@ -250,7 +250,7 @@ empty scene containing only ``self.embed()``, you can directly run the following
You succeeded!
--------------
After reading the above content, you already know how to use manim.
Below you can see some examples, in the :doc:`example_scenes` page.
After reading the above content, you already know how to use manim.
Below you can see some examples, in the :doc:`example_scenes` page.
But before that, you'd better have a look at the :doc:`configuration` of manim.

View File

@ -37,7 +37,7 @@ class OpeningManimExample(Scene):
FadeTransform(intro_words, linear_transform_words)
)
self.wait()
self.play(grid.apply_matrix, matrix, run_time=3)
self.play(grid.animate.apply_matrix(matrix), run_time=3)
self.wait()
# Complex map
@ -61,7 +61,7 @@ class OpeningManimExample(Scene):
)
self.wait()
self.play(
moving_c_grid.apply_complex_function, lambda z: z**2,
moving_c_grid.animate.apply_complex_function(lambda z: z**2),
run_time=6,
)
self.wait(2)
@ -72,35 +72,44 @@ class AnimatingMethods(Scene):
grid = Tex(r"\pi").get_grid(10, 10, height=4)
self.add(grid)
# If you pass in a mobject method to the scene's "play" function,
# it will apply an animation interpolating between the mobject's
# initial state and whatever happens when you apply that method.
# For example, calling grid.shift(2 * LEFT) would shift it two units
# to the left, but the following line animates that motion.
self.play(grid.shift, 2 * LEFT)
# You can animate the application of mobject methods with the
# ".animate" syntax:
self.play(grid.animate.shift(LEFT))
# Alternatively, you can use the older syntax by passing the
# method and then the arguments to the scene's "play" function:
self.play(grid.shift, LEFT)
# Both of those will interpolate between the mobject's initial
# state and whatever happens when you apply that method.
# For this example, calling grid.shift(LEFT) would shift the
# grid one unit to the left, but both of the previous calls to
# "self.play" animate that motion.
# The same applies for any method, including those setting colors.
self.play(grid.set_color, YELLOW)
self.play(grid.animate.set_color(YELLOW))
self.wait()
self.play(grid.set_submobject_colors_by_gradient, BLUE, GREEN)
self.play(grid.animate.set_submobject_colors_by_gradient(BLUE, GREEN))
self.wait()
self.play(grid.set_height, TAU - MED_SMALL_BUFF)
self.play(grid.animate.set_height(TAU - MED_SMALL_BUFF))
self.wait()
# The method Mobject.apply_complex_function lets you apply arbitrary
# complex functions, treating the points defining the mobject as
# complex numbers.
self.play(grid.apply_complex_function, np.exp, run_time=5)
self.play(grid.animate.apply_complex_function(np.exp), run_time=5)
self.wait()
# Even more generally, you could apply Mobject.apply_function,
# which takes in functions form R^3 to R^3
self.play(
grid.apply_function,
lambda p: [
p[0] + 0.5 * math.sin(p[1]),
p[1] + 0.5 * math.sin(p[0]),
p[2]
],
grid.animate.apply_function(
lambda p: [
p[0] + 0.5 * math.sin(p[1]),
p[1] + 0.5 * math.sin(p[0]),
p[2]
]
),
run_time=5,
)
self.wait()
@ -294,18 +303,18 @@ class UpdatersExample(Scene):
# Notice that the brace and label track with the square
self.play(
square.scale, 2,
square.animate.scale(2),
rate_func=there_and_back,
run_time=2,
)
self.wait()
self.play(
square.set_width, 5, {"stretch": True},
square.set_width(5, stretch=True),
run_time=3,
)
self.wait()
self.play(
square.set_width, 2,
square.animate.set_width(2),
run_time=3
)
self.wait()
@ -398,8 +407,8 @@ class GraphExample(Scene):
lambda: axes.i2gp(x_tracker.get_value(), parabola)
)
self.play(x_tracker.set_value, 4, run_time=3)
self.play(x_tracker.set_value, -2, run_time=3)
self.play(x_tracker.animate.set_value(4), run_time=3)
self.play(x_tracker.animate.set_value(-2), run_time=3)
self.wait()
@ -442,9 +451,9 @@ class CoordinateSystemExample(Scene):
dot = Dot(color=RED)
dot.move_to(axes.c2p(0, 0))
self.play(FadeIn(dot, scale=0.5))
self.play(dot.move_to, axes.c2p(3, 2))
self.play(dot.animate.move_to(axes.c2p(3, 2)))
self.wait()
self.play(dot.move_to, axes.c2p(5, 0.5))
self.play(dot.animate.move_to(axes.c2p(5, 0.5)))
self.wait()
# Similarly, you can call axes.point_to_coords, or axes.p2c
@ -461,9 +470,9 @@ class CoordinateSystemExample(Scene):
ShowCreation(h_line),
ShowCreation(v_line),
)
self.play(dot.move_to, axes.c2p(3, -2))
self.play(dot.animate.move_to(axes.c2p(3, -2)))
self.wait()
self.play(dot.move_to, axes.c2p(1, 1))
self.play(dot.animate.move_to(axes.c2p(1, 1)))
self.wait()
# If we tie the dot to a particular set of coordinates, notice
@ -471,8 +480,8 @@ class CoordinateSystemExample(Scene):
# system defined by them.
f_always(dot.move_to, lambda: axes.c2p(1, 1))
self.play(
axes.scale, 0.75,
axes.to_corner, UL,
axes.animate.scale(0.75),
axes.animate.to_corner(UL),
run_time=2,
)
self.wait()
@ -546,8 +555,8 @@ class SurfaceExample(Scene):
self.play(
Transform(surface, surfaces[2]),
# Move camera frame during the transition
frame.increment_phi, -10 * DEGREES,
frame.increment_theta, -20 * DEGREES,
frame.animate.increment_phi(-10 * DEGREES),
frame.animate.increment_theta(-20 * DEGREES),
run_time=3
)
# Add ambient rotation
@ -562,8 +571,8 @@ class SurfaceExample(Scene):
light = self.camera.light_source
self.add(light)
light.save_state()
self.play(light.move_to, 3 * IN, run_time=5)
self.play(light.shift, 10 * OUT, run_time=5)
self.play(light.animate.move_to(3 * IN), run_time=5)
self.play(light.animate.shift(10 * OUT), run_time=5)
drag_text = Text("Try moving the mouse while pressing d or s")
drag_text.move_to(light_text)
@ -593,9 +602,9 @@ class InteractiveDevlopment(Scene):
# the interactive shell
self.play(ReplacementTransform(square, circle))
self.wait()
self.play(circle.stretch, 4, 0)
self.play(circle.animate.stretch(4, 0))
self.play(Rotate(circle, 90 * DEGREES))
self.play(circle.shift, 2 * RIGHT, circle.scale, 0.25)
self.play(circle.animate.shift(2 * RIGHT, circle.scale, 0.25))
text = Text("""
In general, using the interactive shell