Search code examples
pythonmanim

Manim, ReplacementTransform without Transform


I'm new to manim.

as with following example,

class scene_example(Scene):
    def construct(self):
        txt1 = Text("Text1")
        txt2 = Text("Change to this text without animation")

        self.play(FadeIn(txt1))
        self.play(ReplacementTransform(txt1, txt2))

Is there any convenient function for "Replace" the txt1 to txt2? (i.e., without the "transforming" animation?)

class scene_example(Scene):
    def construct(self):
        txt1 = Text("Text1")
        txt2 = Text("Change to this text without animation")
        
        self.play(FadeIn(txt1))
        self.play(FadeOut(txt1), FadeIn(txt2) )

This code will do what I want, but I feel that there might function like ReplacemnetTransform to fulfill the simple "Replacement" animation. I tried to make a function for FadeIn and then FadeOut but, that doesn't work.

class q(Scene):
    def construct(self):
        def Replace(self, mObj1, mObj2):
            self.play(FadeIn(mObj1),FadeOut(mObj2))

        txt1 = "HI"
        txt2 = "HI2"

        self.play(FadeIn(txt1))
        Replace(txt1, txt2)

Solution

  • In the code that you tried to write:

    class q(Scene):
        def construct(self):
            def Replace(self, mObj1, mObj2):
                self.play(FadeIn(mObj1),FadeOut(mObj2))
    
            txt1 = Text("HI")
            txt2 = Text("HI2")
    
            self.play(FadeIn(txt1))
            Replace(txt1, txt2)
    

    the parameter self doesn't get passed to the Replace function automatically. One solution is to replace Replace(txt1, txt2) with Replace(self, txt1, txt2).

    Another option is to not make Replace take the self parameter at all. The code

    class q(Scene):
        def construct(self):
            def Replace(mObj1, mObj2):
                self.play(FadeIn(mObj1),FadeOut(mObj2))
    
            txt1 = Text("HI")
            txt2 = Text("HI2")
    
            self.play(FadeIn(txt1))
            Replace(txt1, txt2)
    

    should also work. In this case because of how scoping works in python, the self inside Replace refers to the self parameter passed to the construct method. In the previous example where Replace had its own self parameter, the self parameter masks the one passed to construct, and the self within Replace refers to Replace's self. (Which by default doesn't have any value unless one is given when calling Replace. In fact, when you tried to run your code, you probably got an error along the lines of TypeError: Replace() missing 1 required positional argument: 'mObj2')

    Yet another possibility is to define Replace inside the q class, but outside the construct method:

    class q(Scene):
        def Replace(self, mObj1, mObj2):
            self.play(FadeIn(mObj1),FadeOut(mObj2))
    
        def construct(self):
            txt1 = Text("HI")
            txt2 = Text("HI2")
    
            self.play(FadeIn(txt1))
            self.Replace(txt1, txt2)
    

    Additionally, if you just want to replace the initial text with some new text with no animations at all (not even the fading in and out), then you can use

    self.remove(txt1)
    self.add(txt2)
    

    A much more complicated option is to create a custom Animation class that is instantiated with two MObjects, and fades the first one out while fading the second one in.

    class FadingReplace(Animation):
      def __init__(self, obj1, obj2, ...):
        pass
    #implementation left as an exercise for the reader
    

    Then you could use

    self.play(FadingReplace(txt1, txt2))