When there are two objects A and B, we will learn about the animation effect that A gradually changes to B.
Class | Parameters | Explanation |
MoveAlongPath | mobject, target_mobject=None |
mobject is converted to the location/form of target_mobject. At this time, the name of the object that has changed and remains is mobject not target_mobject. |
ClockwiseTransform | mobject, target_mobject=None |
mobject is converted to the position/shape of target_mobject. When mobject moves to target_mobject, it is converted while flying clockwise. At this time, the name of the object that has changed and remained is mobject. |
CounterclockwiseTransform | mobject, target_mobject=None |
mobject is converted to the position/shape of target_mobject. When mobject moves to target_mobject, it is converted while flying counterclockwise. At this time, the name of the object that has changed and remains is mobject. |
ReplacementTransform | mobject, target_mobject=None |
mobject is converted to the location/form of target_mobject. At this time, the name of the object that has changed and remains is target_mobject. |
Swap | *mobjects | Two objects swapped each other |
TransformFromCopy | mobject, target_mobject=None |
As mobject moves toward target_mobject, the shape/color changes, but the original mobject remains |
CyclicReplace | *mobjects | Move the given mobjects one by one. The first one changes to the second, the second to the third, the last one to the first, and so on, as if on a circular cycle. |
ScaleInPlace | mobject, scale_factor |
Animation effect that changes mobject to the size of scale_factor |
FadeToColor | mobject, color | Animation effect that turns mobject into the given color |
Restore | mobjects | Animation that returns mobject to the state it was in when mobject.save_state() was called. |
MoveToTarget | mobjects | Animation to move mobject to mboject.target |
Transform class
object > Animation > Transform
manimlib.animation.transform.Transform(self, mobject, target_mobject=None, **kwargs)
A mobject is converted to the location/form of target_mobject.
At this time, the last remaining object name is mobject.
self.play(Transform(square, circle), run_time=3)
CONFIG = {
"path_arc": 0,
"path_arc_axis": OUT,
"path_func": None,
"replace_mobject_with_target_in_scene": False,
}
Parameters: mobject
Object to be animated
Parameters: target_mobject=None
Target object to be converted.
The object moves to the location of target_mobject and changes to the shape of target_mobject.
Parameters: **kwargs
CONFIG values of Transform and Animation
Frequently used variables are,
- run_time=1.0: Animation running time
- rate_func=smooth: Velocity change function when the animation is running
The Transform class shows an animation effect that gradually changes the position/shape of the object targeting mobject.
When the rectangle A is on the left and the circle B is on the right, the effect is that the rectangle gradually turns into a circle as it flies to the circle.
self.play(Transform(square, circle), run_time=3)
You can see the changing process in the snapshot below.
Note that what is the name of the object that turned into a circle left at the end, which is variable A. It is convenient to understand that A has changed to the form of B.
The reason why the remaining variable is important is because, after performing the Transform once, what kind of object variable should be used when re-animating the transformed object?
Since we transformed A into B, A remains, and we can use some animation for this A again.
The sorce code and output video for the above exampel is as follows.
class TransformTest(Scene):
def construct(self):
self.transform_to_target()
# self.cyclic()
def get_text(self, str):
return Text(str, size=0.5, color=YELLOW, stroke_width=0)
def transform_to_target(self):
self.left_name = self.get_text("A").shift(UP * 2 + LEFT * 3)
self.right_name = self.get_text("B").shift(UP * 2 + RIGHT * 3)
self.square = Square().shift(LEFT*3)
self.circle = Circle(fill_opacity=1, color=RED).shift(RIGHT*3)
self.objs = VGroup(self.left_name, self.right_name, self.square, self.circle)
self.objs.save_state()
t_classes = {
"1. Transform": Transform,
"2. ClockwiseTransform": ClockwiseTransform,
"3. CounterclockwiseTransform": CounterclockwiseTransform,
}
for name, cla in t_classes.items():
self.transform(name, cla)
self.replacement_transform("4. ReplacementTransform", ReplacementTransform)
self.transform_from_copy("5. TransformFromCopy", TransformFromCopy)
self.do_swap("6. Swap", Swap)
def transform(self, name, ani_class):
ani_name = self.get_text(name).to_corner(UL)
self.add(ani_name, self.objs)
self.wait()
self.play(
ani_class(self.square, self.circle, run_time=3),
FadeOut(self.right_name),
self.left_name.move_to, self.right_name, run_time=3,
)
self.wait()
self.remove(ani_name, self.objs)
self.objs.restore()
def replacement_transform(self, name, ani_class):
ani_name = self.get_text(name).to_corner(UL)
self.add(ani_name, self.objs)
self.play(
ani_class(self.square, self.circle, run_time=2),
FadeOut(self.left_name),
)
self.wait()
self.remove(ani_name, self.objs)
self.objs.restore()
def transform_from_copy(self, name, ani_class):
ani_name = self.get_text(name).to_corner(UL)
self.add(ani_name, self.objs)
self.play(
ani_class(self.square, self.circle, run_time=2),
)
self.wait()
self.remove(ani_name, self.objs)
self.objs.restore()
def do_swap(self, name, ani_class):
ani_name = self.get_text(name).to_corner(UL)
self.add(ani_name, self.objs)
self.play(
ani_class(self.square, self.circle, run_time=2),
self.left_name.shift, RIGHT*6,
self.right_name.shift, LEFT * 6,
)
self.wait()
self.remove(ani_name, self.objs)
self.objs.restore()
Classification for Transform, ReplaceTransform, TransformFromCopy
Before we dive into other classes related to transforms. let's look at the differences between the Transform, ReplaceTransform, and TransformFromCopy classes.
These three classes are most commonly used transform effects, but their behavior is subtly different, which is a bit confusing. Let's point out what's different.
If you understand the code below, you will definitely see the difference.
We will create an animation in which three objects are arranged side by side, such as a triangle, a square, and a circle, while only the triangle is displayed on the screen, the triangle turns into a rectangle and the rectangle turns into a circle.
If the triangle is called A, the square is B, and the circle is C, using the Transform class,
Transform(A,B)
Transform(A,C)
If we use ReplacementTransform,
ReplacementTransform(A,B)
ReplacementTransform(B,C)
If we use TransformFromCopy,
TransformFromCopy를(A,B)
TransformFromCopy를(B,C)
Let's explain.
In the case of Transform, A is changed to B, and then A is left in place of B.
At this time, the shape of A is changed to B's shape of rectangle.
In that state, the rectangle should be changed to the circle, so you have to do Transform(A,C)
In the case of ReplacementTransform, B is replaced by A after A is changed to B. In other words, after A is changed to B, what remains is an object with the name B.
So, if you want to change the rectangle to circle, do TransformReplacement(B,C), and after doing this, the last thing left is a circle with the name of C.
In the case of TransformFromCopy, you can think that it's similiar to ReplacementTransform except the starting object is remained. That is, when the shape changes from A to B with TransformFromCopy, A remains, and the cloned A object flies to B to become the sahpe of B, and the name becomes B.
Subsequently, B changes to C, B stays, and cloned B flies to C, and turns into C, then becoms the name of C.
The explanation is a bit complicated, but if you look at the picture below you can understand it.
Below is the source code that created as described above.
class DifferenceOfTransform(Scene):
def construct(self):
self.tri = Triangle().to_edge(LEFT, buff=0.5)
self.square = Square()
self.circle = Circle().to_edge(RIGHT, buff=0.5)
self.group = VGroup(self.tri, self.square, self.circle)
self.group.save_state()
self.transform("Transform(A,B)", "Transform(A,C)")
self.replacement_transform("ReplacementTransform(A,B)", "ReplacementTransform(B,C)")
self.transform_from_copy("TransformFromCopy(A,B)", "TransformFromCopy(B,C)")
def transform(self, s1, s2):
text = VGroup(
Text(s1, stroke_width=0, color=YELLOW, size=0.4),
Text(s2, stroke_width=0, color=YELLOW, size=0.4),
).arrange(DOWN, aligned_edge=LEFT)
self.add(text.to_edge(UP, buff=1))
self.group.restore()
self.add(self.tri)
self.play(Transform(self.tri, self.square), run_time=3)
self.play(Transform(self.tri, self.circle), run_time=3)
self.wait()
self.remove(text, self.tri, self.square, self.circle)
def replacement_transform(self, s1, s2):
text = VGroup(
Text(s1, stroke_width=0, color=YELLOW, size=0.4),
Text(s2, stroke_width=0, color=YELLOW, size=0.4),
).arrange(DOWN, aligned_edge=LEFT)
self.add(text.to_edge(UP, buff=1))
self.group.restore()
self.play(ReplacementTransform(self.tri, self.square), run_time=3)
self.play(ReplacementTransform(self.square, self.circle), run_time=3)
self.wait()
self.remove(text, self.tri, self.square, self.circle)
def transform_from_copy(self, s1, s2):
text = VGroup(
Text(s1, stroke_width=0, color=YELLOW, size=0.4),
Text(s2, stroke_width=0, color=YELLOW, size=0.4),
).arrange(DOWN, aligned_edge=LEFT)
self.add(text.to_edge(UP, buff=1))
self.group.restore()
self.add(self.tri)
self.play(TransformFromCopy(self.tri, self.square), run_time=3)
self.play(TransformFromCopy(self.square, self.circle), run_time=3)
self.wait()
Next: [06-1-F] Animation : Transformation series (2/3)
Go To: [99] Table of Contents
'Programming > Manim Lectures' 카테고리의 다른 글
[06-1-G] Animation : Transformation series (3/3) (0) | 2020.06.09 |
---|---|
[06-1-F] Animation : Transformation series (2/3) (0) | 2020.06.09 |
[06-1-D] Animation : Move/Rotating series (0) | 2020.06.09 |
[06-1-C] Animation : Indicating series (0) | 2020.06.09 |
[06-1-B] Animation : Creation series (0) | 2020.06.09 |