Transformations
The transformations are classified into two:
Transform
ReplacementTransform
All other animations in this style are derived from these two.
Transform
To understand the transformations, we must first understand that each instance of a Mobject has a special identifier that differentiates it from the others, thus, two instances of the same Mobject will have different identifiers.
def construct(self):
d1 = Dot()
d2 = Dot()
d3 = d1
d4 = d2.copy()
print(f"id(d1) = f{id(d1)}")
print(f"id(d2) = f{id(d2)}")
print(f"id(d3) = f{id(d3)}")
print(f"id(d4) = f{id(d4)}")
Results (The values change on every computer or session):
id(d1) = f5547969504
id(d2) = f5548828560
id(d3) = f5547969504
id(d4) = f5534488176
You can see that even though d1
and d2
are instances of the same Mobject
(Dot
) but they have different id. But, d1
and d3
have the same id, that means, that both values point to the same place in memory, so it is the same to modify d1
or d3
, since it is exactly the same object, only with a different name. d4
is an object created from d2
, but they are not the same object.
This is not something special from Manim, all objects are like that.
Something similar happens in transformations.
Transform needs two and only two Mobjects
, the object to transform and the target.
Transform copies the properties of the target and passes them to the object to be transformed, but does not modify the target, it only modifies the object to transform.
def construct(self):
obj = Text("X")
t_a = Text("A")
t_b = Text("B")
t_c = Text("C")
t_d = Text("D")
self.add(obj)
self.play(Transform(obj,t_a))
self.play(Transform(obj,t_b))
self.play(Transform(obj,t_c))
self.play(Transform(obj,t_d))
self.wait()
t_grp = VGroup(t_a,t_b,t_c,t_d)\
.arrange(DOWN)\
.shift(RIGHT)
self.play(Write(t_grp))
self.wait()
It is easy to notice here that neither t_a
, t_b
, t_c
nor t_d
changed their value, the only Mobject that changed was obj
.
ReplacementTransform
It is equivalent to Transform, with the detail that ReplacementTransform does change the content of the target.
def construct(self):
obj = Text("X")
t_a = Text("A")
t_b = Text("B")
t_c = Text("C")
t_d = Text("D")
self.add(obj)
self.play(ReplacementTransform(obj,t_a))
# self.play(ReplacementTransform(obj,t_b)) # <- This not works
self.play(ReplacementTransform(t_a,t_b))
self.play(ReplacementTransform(t_b,t_c))
self.play(ReplacementTransform(t_c,t_d))
self.wait()
t_grp = VGroup(obj,t_a,t_b,t_c)\
.arrange(DOWN)\
.shift(RIGHT)
self.play(Write(t_grp))
self.wait()
You can notice that, while in Transform
we always use the same object in the first argument, ReplacementTransform
does change its first argument.
Transform vs ReplacementTransform
FadeTransform
It is equivalent to Transform, only that instead of interpolating bézier curves, it uses a FadeIn
and FadeOut
to the Mobjects to transform:
def construct(self):
r = Rectangle()
c = Circle()
VGroup(r,c).arrange(RIGHT)
self.add(r,c)
self.play(
FadeTransform(r,c)
)
self.wait()